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<2L)
00089 {
00090 vcl_cerr<<"vpdfl_axis_gaussian_builder::build() Too few examples available.\n";
00091 vcl_abort();
00092 }
00093
00094 unsigned long n_dims = data.current().size();
00095 vnl_vector<double> sum(n_dims),sum_sq(n_dims),var(n_dims);
00096
00097 double* var_data = var.data_block();
00098 double* sum_data = sum.data_block();
00099 double* sum_sq_data = sum_sq.data_block();
00100 for (unsigned long j=0;j<n_dims;j++)
00101 {
00102 sum_data[j]=0.0;
00103 sum_sq_data[j]=0.0;
00104 }
00105
00106 data.reset();
00107 for (unsigned long i=0;i<n_samples;i++)
00108 {
00109 const double *v = data.current().data_block();
00110 for (unsigned long j=0;j<n_dims;j++)
00111 {
00112 sum_data[j] += v[j];
00113 sum_sq_data[j] += v[j]*v[j];
00114 }
00115
00116 data.next();
00117 }
00118
00119 sum/=n_samples;
00120 for (unsigned long j=0;j<n_dims;j++)
00121 {
00122 var_data[j] = sum_sq_data[j]/n_samples - sum_data[j]*sum_data[j];
00123 if (var_data[j]<min_var_) var_data[j]=min_var_;
00124 }
00125
00126 g.set(sum,var);
00127 }
00128
00129 void vpdfl_axis_gaussian_builder::weighted_build(vpdfl_pdf_base& model,
00130 mbl_data_wrapper<vnl_vector<double> >& data,
00131 const vcl_vector<double>& wts) const
00132 {
00133 vpdfl_axis_gaussian& g = gaussian(model);
00134
00135 unsigned long n_samples = data.size();
00136
00137 if (n_samples<2L)
00138 {
00139 vcl_cerr<<"vpdfl_axis_gaussian_builder::build() Too few examples available.\n";
00140 vcl_abort();
00141 }
00142
00143 if (wts.size()!=n_samples)
00144 {
00145 vcl_cerr<<"vpdfl_axis_gaussian_builder::build() Weight array must contain "
00146 <<n_samples<<" not "<<wts.size()<<vcl_endl;
00147 vcl_abort();
00148 }
00149 data.reset();
00150 unsigned long n_dims = data.current().size();
00151
00152 double w_sum = wts[0];
00153 vnl_vector<double> sum = data.current(); sum *= w_sum;
00154
00155 for (unsigned long i=1;i<n_samples;i++)
00156 {
00157 data.next();
00158 double wt = wts[i];
00159 sum += wt * data.current();
00160 w_sum += wts[i];
00161 }
00162
00163 vnl_vector<double> mean = sum/w_sum;
00164
00165
00166 vnl_vector<double> sum_sq(n_dims), var(n_dims);
00167 double* var_data = var.data_block();
00168 double* m_data = mean.data_block();
00169 double* sum_sq_data = sum_sq.data_block();
00170 for (unsigned long j=0;j<n_dims;j++)
00171 {
00172 sum_sq_data[j]=0.0;
00173 }
00174
00175 data.reset();
00176 for (unsigned long i=0;i<n_samples;i++)
00177 {
00178 const double *v = data.current().data_block();
00179 double w = wts[i];
00180 for (unsigned long j=0;j<n_dims;j++)
00181 {
00182 double dx = v[j]-m_data[j];
00183 sum_sq_data[j] += w * dx*dx;
00184 }
00185
00186 data.next();
00187 }
00188
00189 for (unsigned long j=0;j<n_dims;j++)
00190 {
00191 var_data[j] = sum_sq_data[j]/w_sum;
00192 if (var_data[j]<min_var_) var_data[j]=min_var_;
00193 }
00194
00195 g.set(mean,var);
00196 }
00197
00198
00199
00200
00201 vcl_string vpdfl_axis_gaussian_builder::is_a() const
00202 {
00203 return vcl_string("vpdfl_axis_gaussian_builder");
00204 }
00205
00206
00207
00208
00209
00210 bool vpdfl_axis_gaussian_builder::is_class(vcl_string const& s) const
00211 {
00212 return vpdfl_builder_base::is_class(s) || s==vpdfl_axis_gaussian_builder::is_a();
00213 }
00214
00215
00216
00217
00218
00219 short vpdfl_axis_gaussian_builder::version_no() const
00220 {
00221 return 1;
00222 }
00223
00224
00225
00226
00227
00228 vpdfl_builder_base* vpdfl_axis_gaussian_builder::clone() const
00229 {
00230 return new vpdfl_axis_gaussian_builder(*this);
00231 }
00232
00233
00234
00235
00236
00237 void vpdfl_axis_gaussian_builder::print_summary(vcl_ostream& os) const
00238 {
00239 os << "Min. var.: "<< min_var_;
00240 }
00241
00242
00243
00244
00245
00246 void vpdfl_axis_gaussian_builder::b_write(vsl_b_ostream& bfs) const
00247 {
00248 vsl_b_write(bfs,version_no());
00249 vsl_b_write(bfs,min_var_);
00250 }
00251
00252
00253
00254
00255
00256 void vpdfl_axis_gaussian_builder::b_read(vsl_b_istream& bfs)
00257 {
00258 if (!bfs) return;
00259
00260 short version;
00261 vsl_b_read(bfs,version);
00262 switch (version)
00263 {
00264 case (1):
00265 vsl_b_read(bfs,min_var_);
00266 break;
00267 default:
00268 vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream&, vpdfl_axis_gaussian_builder &)\n"
00269 << " Unknown version number "<< version << vcl_endl;
00270 bfs.is().clear(vcl_ios::badbit);
00271 return;
00272 }
00273 }
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 void vpdfl_axis_gaussian_builder::config_from_stream(vcl_istream & is)
00284 {
00285 vcl_string s = mbl_parse_block(is);
00286
00287 vcl_istringstream ss(s);
00288 mbl_read_props_type props = mbl_read_props_ws(ss);
00289
00290 double mv=1.0e-6;
00291
00292 if (!props["min_var"].empty())
00293 {
00294 mv=vul_string_atof(props["min_var"]);
00295 props.erase("min_var");
00296 }
00297 set_min_var(mv);
00298
00299 try
00300 {
00301 mbl_read_props_look_for_unused_props(
00302 "vpdfl_axis_gaussian_builder::config_from_stream", props);
00303 }
00304 catch(mbl_exception_unused_props &e)
00305 {
00306 throw mbl_exception_parse_error(e.what());
00307 }
00308
00309 }
00310