contrib/mul/pdf1d/pdf1d_flat_builder.cxx
Go to the documentation of this file.
00001 // This is mul/pdf1d/pdf1d_flat_builder.cxx
00002 
00003 //:
00004 // \file
00005 
00006 #include "pdf1d_flat_builder.h"
00007 
00008 #include <vcl_cassert.h>
00009 #include <vcl_string.h>
00010 #include <vcl_cstdlib.h> // vcl_abort()
00011 
00012 #include <mbl/mbl_data_wrapper.h>
00013 #include <mbl/mbl_data_array_wrapper.h>
00014 #include <pdf1d/pdf1d_flat.h>
00015 
00016 //=======================================================================
00017 // Dflt ctor
00018 //=======================================================================
00019 
00020 pdf1d_flat_builder::pdf1d_flat_builder()
00021     : min_var_(1.0e-6)
00022 {
00023 }
00024 
00025 //=======================================================================
00026 // Destructor
00027 //=======================================================================
00028 
00029 pdf1d_flat_builder::~pdf1d_flat_builder()
00030 {
00031 }
00032 
00033 //=======================================================================
00034 
00035 pdf1d_flat& pdf1d_flat_builder::flat(pdf1d_pdf& model) const
00036 {
00037   // require a pdf1d_flat
00038   assert(model.is_class("pdf1d_flat"));
00039   return static_cast<pdf1d_flat&>(model);
00040 }
00041 
00042 pdf1d_pdf* pdf1d_flat_builder::new_model() const
00043 {
00044   return new pdf1d_flat;
00045 }
00046 
00047 vcl_string pdf1d_flat_builder::new_model_type() const
00048 {
00049   return vcl_string("pdf1d_flat");
00050 }
00051 
00052 //=======================================================================
00053 //: Define lower threshold on variance for built models
00054 //=======================================================================
00055 void pdf1d_flat_builder::set_min_var(double min_var)
00056 {
00057   min_var_ = min_var;
00058 }
00059 
00060 //=======================================================================
00061 //: Get lower threshold on variance for built models
00062 //=======================================================================
00063 double pdf1d_flat_builder::min_var() const
00064 {
00065   return min_var_;
00066 }
00067 
00068 void pdf1d_flat_builder::build(pdf1d_pdf& model, double mean) const
00069 {
00070   pdf1d_flat& f = flat(model);
00071   f.set(mean,min_var_);
00072 }
00073 
00074 //: Build flat from n elements in data[i]
00075 void pdf1d_flat_builder::build_from_array(pdf1d_pdf& model, const double* data, int n) const
00076 {
00077   if (n<2)
00078   {
00079     vcl_cerr<<"pdf1d_flat_builder::build_from_array(): too few examples available.\n";
00080     vcl_abort();
00081   }
00082 
00083   double lo = data[0];
00084   double hi = lo;
00085   for (int i=1;i<n;++i)
00086   {
00087     if (data[i]<lo) lo=data[i];
00088     else
00089       if (data[i]>hi) hi=data[i];
00090   }
00091 
00092   double min_w = vcl_sqrt(12*min_var_);
00093   if (hi-lo<min_w)
00094   {
00095     double c = 0.5*(lo+hi);
00096     lo = c-0.5*min_w;
00097     hi = c+0.5*min_w;
00098   }
00099 
00100   pdf1d_flat& f = flat(model);
00101   f.set(lo,hi);
00102 }
00103 
00104 void pdf1d_flat_builder::build(pdf1d_pdf& model, mbl_data_wrapper<double>& data) const
00105 {
00106   int n_samples = data.size();
00107 
00108   if (n_samples<2)
00109   {
00110     vcl_cerr<<"pdf1d_flat_builder::build(): too few examples available.\n";
00111     vcl_abort();
00112   }
00113 
00114   if (data.is_class("mbl_data_array_wrapper<T>"))
00115   {
00116     // Use more efficient build_from_array algorithm
00117     mbl_data_array_wrapper<double>& data_array =
00118                        static_cast<mbl_data_array_wrapper<double>&>(data);
00119     build_from_array(model,data_array.data(),n_samples);
00120     return;
00121   }
00122 
00123   data.reset();
00124   double lo = data.current();
00125   double hi = lo;
00126   for (int i=0;i<n_samples;i++)
00127   {
00128     double x = data.current();
00129     if (x<lo) lo=x;
00130     else
00131       if (x>hi) hi=x;
00132     data.next();
00133   }
00134 
00135   double min_w = vcl_sqrt(12*min_var_);
00136   if (hi-lo<min_w)
00137   {
00138     double c = 0.5*(lo+hi);
00139     lo = c-0.5*min_w;
00140     hi = c+0.5*min_w;
00141   }
00142 
00143   pdf1d_flat& f = flat(model);
00144   f.set(lo,hi);
00145 }
00146 
00147 void pdf1d_flat_builder::weighted_build(pdf1d_pdf& model,
00148                                         mbl_data_wrapper<double>& data,
00149                                         const vcl_vector<double>& /*wts*/) const
00150 {
00151   // TODO - Currently ignore weights
00152   build(model,data);
00153 }
00154 //=======================================================================
00155 // Method: is_a
00156 //=======================================================================
00157 
00158 vcl_string pdf1d_flat_builder::is_a() const
00159 {
00160   return vcl_string("pdf1d_flat_builder");
00161 }
00162 
00163 //=======================================================================
00164 // Method: is_class
00165 //=======================================================================
00166 
00167 bool pdf1d_flat_builder::is_class(vcl_string const& s) const
00168 {
00169   return pdf1d_builder::is_class(s) || s==pdf1d_flat_builder::is_a();
00170 }
00171 
00172 //=======================================================================
00173 // Method: version_no
00174 //=======================================================================
00175 
00176 short pdf1d_flat_builder::version_no() const
00177 {
00178   return 1;
00179 }
00180 
00181 //=======================================================================
00182 // Method: clone
00183 //=======================================================================
00184 
00185 pdf1d_builder* pdf1d_flat_builder::clone() const
00186 {
00187   return new pdf1d_flat_builder(*this);
00188 }
00189 
00190 //=======================================================================
00191 // Method: print
00192 //=======================================================================
00193 
00194 void pdf1d_flat_builder::print_summary(vcl_ostream& os) const
00195 {
00196   os << "Min. var.: "<< min_var_;
00197 }
00198 
00199 //=======================================================================
00200 // Method: save
00201 //=======================================================================
00202 
00203 void pdf1d_flat_builder::b_write(vsl_b_ostream& bfs) const
00204 {
00205   vsl_b_write(bfs,version_no());
00206   vsl_b_write(bfs,min_var_);
00207 }
00208 
00209 //=======================================================================
00210 // Method: load
00211 //=======================================================================
00212 
00213 void pdf1d_flat_builder::b_read(vsl_b_istream& bfs)
00214 {
00215   if (!bfs) return;
00216 
00217   short version;
00218   vsl_b_read(bfs,version);
00219   switch (version)
00220   {
00221     case (1):
00222       vsl_b_read(bfs,min_var_);
00223       break;
00224     default:
00225       vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream&, pdf1d_flat_builder &)\n"
00226                << "           Unknown version number "<< version << '\n';
00227       bfs.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00228       return;
00229   }
00230 }
00231