Go to the documentation of this file.00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008
00009
00010
00011 #include "vpdfl_axis_gaussian.h"
00012 #include <vcl_cmath.h>
00013 #include <vnl/vnl_math.h>
00014 #include <vcl_cstdlib.h>
00015 #include <vcl_string.h>
00016 #include <vcl_cassert.h>
00017 #include <vsl/vsl_indent.h>
00018 #include <vpdfl/vpdfl_axis_gaussian_sampler.h>
00019 #include <vpdfl/vpdfl_sampler_base.h>
00020 #include <vpdfl/vpdfl_prob_chi2.h>
00021
00022
00023
00024
00025
00026
00027 vpdfl_axis_gaussian::vpdfl_axis_gaussian()
00028 {
00029 }
00030
00031
00032
00033
00034
00035 vpdfl_axis_gaussian::~vpdfl_axis_gaussian()
00036 {
00037 }
00038
00039
00040
00041 void vpdfl_axis_gaussian::calcLogK()
00042 {
00043 const double *v_data = variance().data_block();
00044 int n = n_dims();
00045 double log_v_sum = 0.0;
00046 for (int i=0;i<n;i++)
00047 log_v_sum+=vcl_log(v_data[i]);
00048
00049 log_k_ = -0.5 * (n*vcl_log(2 * vnl_math::pi) + log_v_sum);
00050 }
00051
00052 void vpdfl_axis_gaussian::calcSD()
00053 {
00054 sd_ = variance();
00055 int n = sd_.size();
00056 for (int i=0;i<n;i++) sd_[i] = vcl_sqrt(sd_[i]);
00057 }
00058
00059
00060 void vpdfl_axis_gaussian::set(const vnl_vector<double>& m,
00061 const vnl_vector<double>& v)
00062 {
00063 set_mean(m);
00064 set_variance(v);
00065
00066 calcLogK();
00067 calcSD();
00068 }
00069
00070
00071
00072
00073 double vpdfl_axis_gaussian::dx_sigma_dx(const vnl_vector<double> &x) const
00074 {
00075 int n = x.size();
00076 #ifndef NDEBUG
00077 if (n!=n_dims())
00078 {
00079 vcl_cerr<<"ERROR: vpdfl_axis_gaussian::log_p: Target vector has "
00080 <<n<<" dimensions, not the required "<<n_dims()<<vcl_endl;
00081 vcl_abort();
00082 }
00083 #endif
00084
00085 const double* x_data = x.data_block();
00086 const double* m_data = mean().data_block();
00087 const double* v_data = variance().data_block();
00088
00089 double sum=0.0;
00090 for (int i=0;i<n;++i)
00091 {
00092 double dx=x_data[i]-m_data[i];
00093 sum+=(dx*dx)/v_data[i];
00094 }
00095 return sum;
00096 }
00097
00098
00099 double vpdfl_axis_gaussian::log_p(const vnl_vector<double>& x) const
00100 {
00101 return log_k() - 0.5*dx_sigma_dx(x);
00102 }
00103
00104 void vpdfl_axis_gaussian::gradient(vnl_vector<double>& g,
00105 const vnl_vector<double>& x,
00106 double& p) const
00107 {
00108 unsigned int n = n_dims();
00109 assert(x.size() == n);
00110
00111 if (g.size()!=n) g.set_size(n);
00112
00113 double* g_data = g.data_block();
00114 const double* x_data = x.data_block();
00115 const double* m_data = mean().data_block();
00116 const double* v_data = variance().data_block();
00117
00118 double sum=0.0;
00119
00120 for (unsigned int i=0;i<n;++i)
00121 {
00122 double dx=x_data[i]-m_data[i];
00123 sum+=(dx*dx)/v_data[i];
00124 g_data[i]= -dx/v_data[i];
00125 }
00126
00127 p = vcl_exp(log_k() - 0.5*sum);
00128
00129 g*=p;
00130 }
00131
00132
00133
00134 void vpdfl_axis_gaussian::gradient_logp(vnl_vector<double>& g,
00135 const vnl_vector<double>& x) const
00136 {
00137 unsigned int n = n_dims();
00138 assert(x.size() == n);
00139
00140 if (g.size()!=n) g.set_size(n);
00141
00142 double* g_data = g.data_block();
00143 const double* x_data = x.data_block();
00144 const double* m_data = mean().data_block();
00145 const double* v_data = variance().data_block();
00146
00147 for (unsigned int i=0;i<n;++i)
00148 {
00149 g_data[i]= (m_data[i]-x_data[i])/v_data[i];
00150 }
00151 }
00152
00153
00154
00155 vpdfl_sampler_base* vpdfl_axis_gaussian::new_sampler() const
00156 {
00157 vpdfl_axis_gaussian_sampler *i = new vpdfl_axis_gaussian_sampler;
00158 i->set_model(*this);
00159 return i;
00160 }
00161
00162
00163 double vpdfl_axis_gaussian::log_prob_thresh(double pass_proportion) const
00164 {
00165
00166
00167 return log_k() - 0.5 * vpdfl_chi2_for_cum_prob (pass_proportion, n_dims());
00168 }
00169
00170
00171 void vpdfl_axis_gaussian::nearest_plausible(vnl_vector<double>& x,
00172 double log_p_min) const
00173 {
00174 unsigned n = x.size();
00175
00176
00177 log_p_min -= log_k();
00178 assert(log_p_min <0);
00179
00180 const double sd_limit_sqr = -2.0*log_p_min;
00181
00182 const double x_dist_sqr = dx_sigma_dx(x);
00183
00184 if (sd_limit_sqr >= x_dist_sqr) return;
00185
00186 const double corrective_factor = vcl_sqrt(sd_limit_sqr / x_dist_sqr);
00187
00188 for (unsigned i=0;i<n;++i)
00189 x(i) = ((x(i)-mean()(i)) * corrective_factor) + mean()(i);
00190 }
00191
00192
00193
00194 vcl_string vpdfl_axis_gaussian::is_a() const
00195 {
00196 static const vcl_string s_ = "vpdfl_axis_gaussian";
00197 return s_;
00198 }
00199
00200
00201
00202 bool vpdfl_axis_gaussian::is_class(vcl_string const& s) const
00203 {
00204 return s==vpdfl_axis_gaussian::is_a() || vpdfl_pdf_base::is_class(s);
00205 }
00206
00207
00208
00209 short vpdfl_axis_gaussian::version_no() const
00210 {
00211 return 1;
00212 }
00213
00214
00215
00216 vpdfl_pdf_base* vpdfl_axis_gaussian::clone() const
00217 {
00218 return new vpdfl_axis_gaussian(*this);
00219 }
00220
00221
00222
00223 void vpdfl_axis_gaussian::print_summary(vcl_ostream& os) const
00224 {
00225 vpdfl_pdf_base::print_summary(os);
00226 }
00227
00228
00229
00230 void vpdfl_axis_gaussian::b_write(vsl_b_ostream& bfs) const
00231 {
00232 vsl_b_write(bfs,version_no());
00233 vpdfl_pdf_base::b_write(bfs);
00234 }
00235
00236
00237
00238 void vpdfl_axis_gaussian::b_read(vsl_b_istream& bfs)
00239 {
00240 if (!bfs) return;
00241
00242 short version;
00243 vsl_b_read(bfs,version);
00244 switch (version)
00245 {
00246 case (1):
00247 vpdfl_pdf_base::b_read(bfs);
00248 break;
00249 default:
00250 vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream&, vpdfl_axis_gaussian &)\n"
00251 << " Unknown version number "<< version << vcl_endl;
00252 bfs.is().clear(vcl_ios::badbit);
00253 return;
00254 }
00255
00256 calcLogK();
00257 calcSD();
00258 }