contrib/mul/mfpf/mfpf_ssd_vec_cost_builder.cxx
Go to the documentation of this file.
00001 #include "mfpf_ssd_vec_cost_builder.h"
00002 //:
00003 // \file
00004 // \brief Builder for mfpf_ssd_vec_cost objects.
00005 // \author Tim Cootes
00006 
00007 #include <mfpf/mfpf_ssd_vec_cost.h>
00008 #include <vsl/vsl_binary_loader.h>
00009 #include <vul/vul_string.h>
00010 #include <vcl_cassert.h>
00011 #include <vcl_algorithm.h>
00012 #include <vcl_sstream.h>
00013 
00014 #include <mbl/mbl_parse_block.h>
00015 #include <mbl/mbl_read_props.h>
00016 #include <mbl/mbl_stats_1d.h>
00017 
00018 #include <vnl/io/vnl_io_vector.h>
00019 #include <vsl/vsl_vector_io.h>
00020 
00021 //=======================================================================
00022 // Dflt ctor
00023 //=======================================================================
00024 
00025 mfpf_ssd_vec_cost_builder::mfpf_ssd_vec_cost_builder()
00026 {
00027   set_defaults();
00028 }
00029 
00030 //: Define default values
00031 void mfpf_ssd_vec_cost_builder::set_defaults()
00032 {
00033   min_var_=1.0;
00034 }
00035 
00036 //=======================================================================
00037 // Destructor
00038 //=======================================================================
00039 
00040 mfpf_ssd_vec_cost_builder::~mfpf_ssd_vec_cost_builder()
00041 {
00042 }
00043 
00044 //: Create new mfpf_ssd_vec_cost on heap
00045 mfpf_vec_cost* mfpf_ssd_vec_cost_builder::new_cost() const
00046 {
00047   return new mfpf_ssd_vec_cost();
00048 }
00049 
00050 
00051 //: Initialise building
00052 // Must be called before any calls to add_example(...)
00053 void mfpf_ssd_vec_cost_builder::clear(unsigned n_egs)
00054 {
00055   data_.resize(0);
00056 }
00057 
00058 //: Add one example to the model
00059 void mfpf_ssd_vec_cost_builder::add_example(const vnl_vector<double>& v)
00060 {
00061   data_.push_back(v);
00062 }
00063 
00064 //: dv[i] = |v1[i]-v2[i]|
00065 inline void abs_diff(const vnl_vector<double>& v1,
00066                      const vnl_vector<double>& v2,
00067                      vnl_vector<double>& dv)
00068 {
00069   unsigned n = v1.size();
00070   dv.set_size(n);
00071   for (unsigned i=0;i<n;++i) dv[i]=vcl_fabs(v1[i]-v2[i]);
00072 }
00073 
00074 //: Build this object from the data supplied in add_example()
00075 void mfpf_ssd_vec_cost_builder::build(mfpf_vec_cost& pf)
00076 {
00077   assert(pf.is_a()=="mfpf_ssd_vec_cost");
00078   mfpf_ssd_vec_cost& nc = static_cast<mfpf_ssd_vec_cost&>(pf);
00079 
00080   unsigned n = data_.size();
00081 
00082   if (n==1)
00083   {
00084     // Create from only one example
00085     vnl_vector<double> wts(data_[0].size(),1.0/min_var_);
00086     nc.set(data_[0],wts);
00087     return;
00088   }
00089 
00090   // First compute mean
00091   vnl_vector<double> mean=data_[0];
00092   for (unsigned i=1;i<n;++i) mean+=data_[i];
00093   mean/=n;
00094 
00095   // Now compute mean absolute difference from mean
00096   vnl_vector<double> dv, dv_sum;
00097   abs_diff(mean,data_[0],dv_sum);
00098   for (unsigned i=1;i<n;++i)
00099   {
00100     abs_diff(mean,data_[i],dv);
00101     dv_sum+=dv;
00102   }
00103 
00104   // Estimate weights using mean absolute difference
00105   // More robust than variance
00106   vnl_vector<double> wts(mean.size());
00107   for (unsigned i=0;i<mean.size();++i)
00108   {
00109     double mad = dv_sum[i]/n;
00110     wts[i]=1.0/vcl_max(min_var_,mad*mad);
00111   }
00112 
00113   nc.set(mean,wts);
00114 
00115   // Now compute the statistics of the output on the training set
00116   mbl_stats_1d stats;
00117   for (unsigned i=0;i<n;++i)
00118     stats.obs(nc.evaluate(data_[i]));
00119 
00120   // Tweak the weights so that the SD of this will be unity
00121   wts/=stats.sd();
00122 
00123   nc.set(mean,wts);
00124 
00125   // Discard data
00126   data_.resize(0);
00127 }
00128 
00129 //=======================================================================
00130 // Method: set_from_stream
00131 //=======================================================================
00132 //: Initialise from a string stream
00133 bool mfpf_ssd_vec_cost_builder::set_from_stream(vcl_istream &is)
00134 {
00135   // Cycle through string and produce a map of properties
00136   vcl_string s = mbl_parse_block(is);
00137   vcl_istringstream ss(s);
00138   mbl_read_props_type props = mbl_read_props_ws(ss);
00139 
00140   set_defaults();
00141 
00142   // Extract the properties
00143   if (props.find("min_var")!=props.end())
00144   {
00145     min_var_=vul_string_atof(props["min_var"]);
00146     props.erase("min_var");
00147   }
00148 
00149   // Check for unused props
00150   mbl_read_props_look_for_unused_props(
00151       "mfpf_ssd_vec_cost_builder::set_from_stream", props, mbl_read_props_type());
00152   return true;
00153 }
00154 
00155 //=======================================================================
00156 // Method: is_a
00157 //=======================================================================
00158 
00159 vcl_string mfpf_ssd_vec_cost_builder::is_a() const
00160 {
00161   return vcl_string("mfpf_ssd_vec_cost_builder");
00162 }
00163 
00164 //: Create a copy on the heap and return base class pointer
00165 mfpf_vec_cost_builder* mfpf_ssd_vec_cost_builder::clone() const
00166 {
00167   return new mfpf_ssd_vec_cost_builder(*this);
00168 }
00169 
00170 //=======================================================================
00171 // Method: print
00172 //=======================================================================
00173 
00174 void mfpf_ssd_vec_cost_builder::print_summary(vcl_ostream& os) const
00175 {
00176   os << "{ min_var: " << min_var_ << " }";
00177 }
00178 
00179 //: Version number for I/O
00180 short mfpf_ssd_vec_cost_builder::version_no() const
00181 {
00182   return 1;
00183 }
00184 
00185 
00186 void mfpf_ssd_vec_cost_builder::b_write(vsl_b_ostream& bfs) const
00187 {
00188   vsl_b_write(bfs,version_no());
00189   vsl_b_write(bfs,min_var_);
00190   vsl_b_write(bfs,data_);
00191 }
00192 
00193 //=======================================================================
00194 // Method: load
00195 //=======================================================================
00196 
00197 void mfpf_ssd_vec_cost_builder::b_read(vsl_b_istream& bfs)
00198 {
00199   if (!bfs) return;
00200   short version;
00201   vsl_b_read(bfs,version);
00202   switch (version)
00203   {
00204     case (1):
00205       vsl_b_read(bfs,min_var_);
00206       vsl_b_read(bfs,data_);
00207       break;
00208     default:
00209       vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream&)\n"
00210                << "           Unknown version number "<< version << vcl_endl;
00211       bfs.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00212       return;
00213   }
00214 }
00215