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