Go to the documentation of this file.00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008 #include "vpdfl_axis_gaussian_builder.h"
00009
00010 #include <vcl_cassert.h>
00011 #include <vcl_string.h>
00012 #include <vcl_cstdlib.h>
00013
00014 #include <mbl/mbl_data_wrapper.h>
00015 #include <vpdfl/vpdfl_axis_gaussian.h>
00016
00017 #include <mbl/mbl_parse_block.h>
00018 #include <mbl/mbl_read_props.h>
00019 #include <vul/vul_string.h>
00020 #include <mbl/mbl_exception.h>
00021
00022
00023
00024
00025
00026 vpdfl_axis_gaussian_builder::vpdfl_axis_gaussian_builder()
00027 : min_var_(1.0e-6)
00028 {
00029 }
00030
00031
00032
00033
00034
00035 vpdfl_axis_gaussian_builder::~vpdfl_axis_gaussian_builder()
00036 {
00037 }
00038
00039
00040
00041 vpdfl_axis_gaussian& vpdfl_axis_gaussian_builder::gaussian(vpdfl_pdf_base& model) const
00042 {
00043
00044 assert(model.is_class("vpdfl_axis_gaussian"));
00045 return static_cast<vpdfl_axis_gaussian&>(model);
00046 }
00047
00048 vpdfl_pdf_base* vpdfl_axis_gaussian_builder::new_model() const
00049 {
00050 return new vpdfl_axis_gaussian;
00051 }
00052
00053
00054
00055
00056 void vpdfl_axis_gaussian_builder::set_min_var(double min_var)
00057 {
00058 min_var_ = min_var;
00059 }
00060
00061
00062
00063
00064 double vpdfl_axis_gaussian_builder::min_var() const
00065 {
00066 return min_var_;
00067 }
00068
00069 void vpdfl_axis_gaussian_builder::build(vpdfl_pdf_base& model,
00070 const vnl_vector<double>& mean) const
00071 {
00072 vpdfl_axis_gaussian& g = gaussian(model);
00073
00074 vnl_vector<double> var(mean.size());
00075 for (unsigned int i=0;i<mean.size();i++)
00076 var(i)=min_var_;
00077
00078 g.set(mean,var);
00079 }
00080
00081 void vpdfl_axis_gaussian_builder::build(vpdfl_pdf_base& model,
00082 mbl_data_wrapper<vnl_vector<double> >& data) const
00083 {
00084 vpdfl_axis_gaussian& g = gaussian(model);
00085
00086 unsigned long n_samples = data.size();
00087
00088 if (n_samples<1L)
00089 {
00090 vcl_cerr<<"vpdfl_axis_gaussian_builder::build() Too few examples available.\n";
00091 vcl_abort();
00092 }
00093
00094 data.reset();
00095 if (n_samples==1)
00096 {
00097
00098 build(model,data.current());
00099 return;
00100 }
00101
00102 unsigned long n_dims = data.current().size();
00103 vnl_vector<double> sum(n_dims),sum_sq(n_dims),var(n_dims);
00104
00105 double* var_data = var.data_block();
00106 double* sum_data = sum.data_block();
00107 double* sum_sq_data = sum_sq.data_block();
00108 for (unsigned long j=0;j<n_dims;j++)
00109 {
00110 sum_data[j]=0.0;
00111 sum_sq_data[j]=0.0;
00112 }
00113
00114 data.reset();
00115 for (unsigned long i=0;i<n_samples;i++)
00116 {
00117 const double *v = data.current().data_block();
00118 for (unsigned long j=0;j<n_dims;j++)
00119 {
00120 sum_data[j] += v[j];
00121 sum_sq_data[j] += v[j]*v[j];
00122 }
00123
00124 data.next();
00125 }
00126
00127 sum/=n_samples;
00128 for (unsigned long j=0;j<n_dims;j++)
00129 {
00130 var_data[j] = sum_sq_data[j]/n_samples - sum_data[j]*sum_data[j];
00131 if (var_data[j]<min_var_) var_data[j]=min_var_;
00132 }
00133
00134 g.set(sum,var);
00135 }
00136
00137 void vpdfl_axis_gaussian_builder::weighted_build(vpdfl_pdf_base& model,
00138 mbl_data_wrapper<vnl_vector<double> >& data,
00139 const vcl_vector<double>& wts) const
00140 {
00141 vpdfl_axis_gaussian& g = gaussian(model);
00142
00143 unsigned long n_samples = data.size();
00144
00145 if (n_samples<2L)
00146 {
00147 vcl_cerr<<"vpdfl_axis_gaussian_builder::build() Too few examples available.\n";
00148 vcl_abort();
00149 }
00150
00151 if (wts.size()!=n_samples)
00152 {
00153 vcl_cerr<<"vpdfl_axis_gaussian_builder::build() Weight array must contain "
00154 <<n_samples<<" not "<<wts.size()<<vcl_endl;
00155 vcl_abort();
00156 }
00157 data.reset();
00158 unsigned long n_dims = data.current().size();
00159
00160 double w_sum = wts[0];
00161 vnl_vector<double> sum = data.current(); sum *= w_sum;
00162
00163 for (unsigned long i=1;i<n_samples;i++)
00164 {
00165 data.next();
00166 double wt = wts[i];
00167 sum += wt * data.current();
00168 w_sum += wts[i];
00169 }
00170
00171 vnl_vector<double> mean = sum/w_sum;
00172
00173
00174 vnl_vector<double> sum_sq(n_dims), var(n_dims);
00175 double* var_data = var.data_block();
00176 double* m_data = mean.data_block();
00177 double* sum_sq_data = sum_sq.data_block();
00178 for (unsigned long j=0;j<n_dims;j++)
00179 {
00180 sum_sq_data[j]=0.0;
00181 }
00182
00183 data.reset();
00184 for (unsigned long i=0;i<n_samples;i++)
00185 {
00186 const double *v = data.current().data_block();
00187 double w = wts[i];
00188 for (unsigned long j=0;j<n_dims;j++)
00189 {
00190 double dx = v[j]-m_data[j];
00191 sum_sq_data[j] += w * dx*dx;
00192 }
00193
00194 data.next();
00195 }
00196
00197 for (unsigned long j=0;j<n_dims;j++)
00198 {
00199 var_data[j] = sum_sq_data[j]/w_sum;
00200 if (var_data[j]<min_var_) var_data[j]=min_var_;
00201 }
00202
00203 g.set(mean,var);
00204 }
00205
00206
00207
00208
00209 vcl_string vpdfl_axis_gaussian_builder::is_a() const
00210 {
00211 return vcl_string("vpdfl_axis_gaussian_builder");
00212 }
00213
00214
00215
00216
00217
00218 bool vpdfl_axis_gaussian_builder::is_class(vcl_string const& s) const
00219 {
00220 return vpdfl_builder_base::is_class(s) || s==vpdfl_axis_gaussian_builder::is_a();
00221 }
00222
00223
00224
00225
00226
00227 short vpdfl_axis_gaussian_builder::version_no() const
00228 {
00229 return 1;
00230 }
00231
00232
00233
00234
00235
00236 vpdfl_builder_base* vpdfl_axis_gaussian_builder::clone() const
00237 {
00238 return new vpdfl_axis_gaussian_builder(*this);
00239 }
00240
00241
00242
00243
00244
00245 void vpdfl_axis_gaussian_builder::print_summary(vcl_ostream& os) const
00246 {
00247 os << "Min. var.: "<< min_var_;
00248 }
00249
00250
00251
00252
00253
00254 void vpdfl_axis_gaussian_builder::b_write(vsl_b_ostream& bfs) const
00255 {
00256 vsl_b_write(bfs,version_no());
00257 vsl_b_write(bfs,min_var_);
00258 }
00259
00260
00261
00262
00263
00264 void vpdfl_axis_gaussian_builder::b_read(vsl_b_istream& bfs)
00265 {
00266 if (!bfs) return;
00267
00268 short version;
00269 vsl_b_read(bfs,version);
00270 switch (version)
00271 {
00272 case (1):
00273 vsl_b_read(bfs,min_var_);
00274 break;
00275 default:
00276 vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream&, vpdfl_axis_gaussian_builder &)\n"
00277 << " Unknown version number "<< version << vcl_endl;
00278 bfs.is().clear(vcl_ios::badbit);
00279 return;
00280 }
00281 }
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 void vpdfl_axis_gaussian_builder::config_from_stream(vcl_istream & is)
00292 {
00293 vcl_string s = mbl_parse_block(is);
00294
00295 vcl_istringstream ss(s);
00296 mbl_read_props_type props = mbl_read_props_ws(ss);
00297
00298 double mv=1.0e-6;
00299
00300 if (props.find("min_var")!=props.end())
00301 {
00302 mv=vul_string_atof(props["min_var"]);
00303 props.erase("min_var");
00304 }
00305 set_min_var(mv);
00306
00307 try
00308 {
00309 mbl_read_props_look_for_unused_props(
00310 "vpdfl_axis_gaussian_builder::config_from_stream", props);
00311 }
00312 catch(mbl_exception_unused_props &e)
00313 {
00314 throw mbl_exception_parse_error(e.what());
00315 }
00316
00317 }
00318