Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 #include "pdf1d_gaussian_kernel_pdf.h"
00009
00010 #include <vcl_cstdlib.h>
00011 #include <vcl_string.h>
00012 #include <vcl_cmath.h>
00013
00014 #include <vnl/vnl_math.h>
00015 #include <vnl/vnl_erf.h>
00016 #include <pdf1d/pdf1d_gaussian_kernel_pdf_sampler.h>
00017 #include <pdf1d/pdf1d_sampler.h>
00018 #include <mbl/mbl_index_sort.h>
00019
00020
00021
00022 pdf1d_gaussian_kernel_pdf::pdf1d_gaussian_kernel_pdf()
00023 {
00024 }
00025
00026
00027 pdf1d_gaussian_kernel_pdf::pdf1d_gaussian_kernel_pdf(
00028 int n, double sep, double width)
00029 {
00030 vnl_vector<double> x(n);
00031 for (int i=0;i<n;++i) x[i]=i*sep;
00032 set_centres(x,width);
00033 }
00034
00035
00036
00037 pdf1d_gaussian_kernel_pdf::~pdf1d_gaussian_kernel_pdf()
00038 {
00039 }
00040
00041
00042
00043
00044 pdf1d_sampler* pdf1d_gaussian_kernel_pdf::new_sampler() const
00045 {
00046 pdf1d_gaussian_kernel_pdf_sampler *i = new pdf1d_gaussian_kernel_pdf_sampler;
00047 i->set_model(*this);
00048 return i;
00049 }
00050
00051
00052
00053 double pdf1d_gaussian_kernel_pdf::operator()(double x0) const
00054 {
00055 double p;
00056 const double* x = x_.data_block();
00057 const double* w = width_.data_block();
00058 int n = x_.size();
00059 double k = 1.0/(n*vcl_sqrt(2*vnl_math::pi));
00060 double sum = 0;
00061
00062 for (int i=0;i<n;++i)
00063 {
00064 double dx = (x[i]-x0)/w[i];
00065 sum += vcl_exp(-0.5*dx*dx)/w[i];
00066 }
00067
00068 p = k*sum;
00069
00070 return p;
00071 }
00072
00073
00074 double pdf1d_gaussian_kernel_pdf::log_p(double x) const
00075 {
00076 return vcl_log(pdf1d_gaussian_kernel_pdf::operator()(x));
00077 }
00078
00079
00080 double pdf1d_gaussian_kernel_pdf::cdf(double x0) const
00081 {
00082 const double* x = x_.data_block();
00083 const double* w = width_.data_block();
00084 int n = x_.size();
00085 double sum = 0;
00086 #if 1
00087
00088 for (int i=0;i<n;++i)
00089 sum += vnl_erfc( (x[i]-x0)/(vnl_math::sqrt2*w[i]) );
00090
00091
00092 return 0.5*(sum/n);
00093
00094 #else // a slower but clearer and easier to debug version of above
00095
00096 if (index_.empty())
00097 mbl_index_sort(x_.data_block(), x_.size(), index_);
00098 for (int i=0;i<n;++i)
00099 sum += 0.5 * (vnl_erfc( -(x0-x[index_[i]])/(vnl_math::sqrt2*w[index_[i]]) ) )/n;
00100
00101 return sum;
00102 #endif
00103 }
00104
00105
00106 bool pdf1d_gaussian_kernel_pdf::cdf_is_analytic() const
00107 {
00108 return true;
00109 }
00110
00111
00112
00113
00114 double pdf1d_gaussian_kernel_pdf::gradient(double x0,
00115 double& p) const
00116 {
00117 const double* x = x_.data_block();
00118 const double* w = width_.data_block();
00119 int n = x_.size();
00120 double k = 1.0/(n*vcl_sqrt(2*vnl_math::pi));
00121 double sum_p = 0;
00122 double sum_g = 0;
00123
00124 for (int i=0;i<n;++i)
00125 {
00126 double wi = w[i];
00127 double dx = (x[i]-x0)/wi;
00128 double p_i = vcl_exp(-0.5*dx*dx)/wi;
00129 sum_p += p_i;
00130 sum_g -= p_i*dx/wi;
00131 }
00132
00133 p = k*sum_p;
00134
00135 return k*sum_g;
00136 }
00137
00138
00139
00140 double pdf1d_gaussian_kernel_pdf::nearest_plausible(double , double ) const
00141 {
00142 vcl_cerr<<"pdf1d_gaussian_kernel_pdf::nearest_plausible() not yet implemented.\n";
00143 vcl_abort();
00144 return 0.0;
00145 }
00146
00147
00148
00149 vcl_string pdf1d_gaussian_kernel_pdf::is_a() const
00150 {
00151 static vcl_string class_name_ = "pdf1d_gaussian_kernel_pdf";
00152 return class_name_;
00153 }
00154
00155
00156
00157 bool pdf1d_gaussian_kernel_pdf::is_class(vcl_string const& s) const
00158 {
00159 return pdf1d_kernel_pdf::is_class(s) || s==pdf1d_gaussian_kernel_pdf::is_a();
00160 }
00161
00162
00163
00164 short pdf1d_gaussian_kernel_pdf::version_no() const
00165 {
00166 return 1;
00167 }
00168
00169
00170
00171 pdf1d_pdf* pdf1d_gaussian_kernel_pdf::clone() const
00172 {
00173 return new pdf1d_gaussian_kernel_pdf(*this);
00174 }
00175
00176
00177
00178 void pdf1d_gaussian_kernel_pdf::print_summary(vcl_ostream& os) const
00179 {
00180 pdf1d_pdf::print_summary(os);
00181 os << '\n';
00182 }
00183
00184
00185
00186 void pdf1d_gaussian_kernel_pdf::b_write(vsl_b_ostream& bfs) const
00187 {
00188 vsl_b_write(bfs,is_a());
00189 vsl_b_write(bfs,version_no());
00190 pdf1d_kernel_pdf::b_write(bfs);
00191 }
00192
00193
00194
00195 void pdf1d_gaussian_kernel_pdf::b_read(vsl_b_istream& bfs)
00196 {
00197 if (!bfs) return;
00198
00199 vcl_string name;
00200 vsl_b_read(bfs,name);
00201 if (name != is_a())
00202 {
00203 vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream&, pdf1d_gaussian_kernel_pdf &)\n"
00204 << " Attempted to load object of type "
00205 << name <<" into object of type " << is_a() << vcl_endl;
00206 bfs.is().clear(vcl_ios::badbit);
00207 return;
00208 }
00209
00210 short version;
00211 vsl_b_read(bfs,version);
00212 switch (version)
00213 {
00214 case (1):
00215 pdf1d_kernel_pdf::b_read(bfs);
00216 break;
00217 default:
00218 vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream&, pdf1d_gaussian_kernel_pdf &)\n"
00219 << " Unknown version number "<< version << vcl_endl;
00220 bfs.is().clear(vcl_ios::badbit);
00221 return;
00222 }
00223 }
00224