contrib/mul/pdf1d/pdf1d_exponential.cxx
Go to the documentation of this file.
00001 // This is mul/pdf1d/pdf1d_exponential.cxx
00002 
00003 //:
00004 // \file
00005 // \brief Univariate exponential PDF.
00006 // \author Tim Cootes
00007 
00008 #include "pdf1d_exponential.h"
00009 
00010 #include <vcl_cassert.h>
00011 #include <vcl_string.h>
00012 #include <vcl_cmath.h>
00013 
00014 #include <pdf1d/pdf1d_exponential_sampler.h>
00015 #include <pdf1d/pdf1d_sampler.h>
00016 
00017 //=======================================================================
00018 
00019 pdf1d_exponential::pdf1d_exponential()
00020 {
00021   set_lambda(1);
00022 }
00023 
00024 pdf1d_exponential::pdf1d_exponential(double lambda)
00025 {
00026   set_lambda(lambda);
00027 }
00028 
00029 //=======================================================================
00030 
00031 pdf1d_exponential::~pdf1d_exponential()
00032 {
00033 }
00034 
00035 //=======================================================================
00036 
00037 //: Initialise
00038 void pdf1d_exponential::set_lambda(double lambda)
00039 {
00040   assert(lambda>0);
00041   lambda_ = lambda;
00042   log_lambda_ = vcl_log(lambda_);
00043 
00044   pdf1d_pdf::set_mean(1.0/lambda);
00045   pdf1d_pdf::set_variance(1.0/(lambda*lambda));
00046 }
00047 
00048 //=======================================================================
00049 
00050 
00051 pdf1d_sampler* pdf1d_exponential::new_sampler() const
00052 {
00053   pdf1d_exponential_sampler *i = new pdf1d_exponential_sampler;
00054   i->set_model(*this);
00055   return i;
00056 }
00057 
00058 //=======================================================================
00059 //: Probability density at x
00060 double pdf1d_exponential::operator()(double x) const
00061 {
00062   if (x<0) return 0;
00063   return lambda_ * vcl_exp(-1*lambda_*x);
00064 }
00065 
00066 
00067   // Probability densities:
00068 double pdf1d_exponential::log_p(double x) const
00069 {
00070   if (x<0) return -9999;  // Very unlikely!
00071 
00072   return log_lambda_ - lambda_*x;
00073 }
00074 //: Cumulative Probability (P(x'<x) for x' drawn from the distribution)
00075 double pdf1d_exponential::cdf(double x) const
00076 {
00077   return 1.0 - vcl_exp(-1*lambda_*x);
00078 }
00079 
00080 //: Return true if cdf() uses an analytic implementation
00081 bool pdf1d_exponential::cdf_is_analytic() const
00082 {
00083   return true;
00084 }
00085 
00086 //=======================================================================
00087 
00088 
00089 double pdf1d_exponential::gradient(double x,
00090                                    double& p) const
00091 {
00092   if (x<0)
00093   {
00094     p=0;
00095     return 0;
00096   }
00097 
00098   p = lambda_ * vcl_exp(-1*lambda_*x);
00099   return -1.0*lambda_*p;
00100 }
00101 
00102 // ====================================================================
00103 
00104 
00105 double pdf1d_exponential::log_prob_thresh(double pass_proportion) const
00106 {
00107   if (pass_proportion<=0) return 0.0;
00108   if (pass_proportion>=0) return lambda_;
00109 
00110   // CFD = 1-exp(-Lx)
00111   // So exp(-Lx)=(1-pp)
00112   return lambda_ * (1-pass_proportion);
00113 }
00114 
00115 //=======================================================================
00116 
00117 double pdf1d_exponential::nearest_plausible(double x, double log_p_min) const
00118 {
00119   if (x<=0) return 0;
00120   double x_lim = (log_lambda_-log_p_min)/lambda_;
00121   if (x>x_lim) return x_lim;
00122   return x;
00123 }
00124 
00125 //=======================================================================
00126 // Method: is_a
00127 //=======================================================================
00128 
00129 vcl_string pdf1d_exponential::is_a() const
00130 {
00131   static vcl_string class_name_ = "pdf1d_exponential";
00132   return class_name_;
00133 }
00134 
00135 //=======================================================================
00136 // Method: is_class
00137 //=======================================================================
00138 
00139 bool pdf1d_exponential::is_class(vcl_string const& s) const
00140 {
00141   return pdf1d_pdf::is_class(s) || s==pdf1d_exponential::is_a();
00142 }
00143 
00144 //=======================================================================
00145 // Method: version_no
00146 //=======================================================================
00147 
00148 short pdf1d_exponential::version_no() const
00149 {
00150   return 1;
00151 }
00152 
00153 //=======================================================================
00154 // Method: clone
00155 //=======================================================================
00156 
00157 pdf1d_pdf* pdf1d_exponential::clone() const
00158 {
00159   return new pdf1d_exponential(*this);
00160 }
00161 
00162 //=======================================================================
00163 // Method: print
00164 //=======================================================================
00165 
00166 
00167 void pdf1d_exponential::print_summary(vcl_ostream& os) const
00168 {
00169   os<<"Lambda="<<lambda_;
00170 }
00171 
00172 //=======================================================================
00173 // Method: save
00174 //=======================================================================
00175 
00176 void pdf1d_exponential::b_write(vsl_b_ostream& bfs) const
00177 {
00178   vsl_b_write(bfs,is_a());
00179   vsl_b_write(bfs,version_no());
00180   vsl_b_write(bfs,lambda_);
00181 }
00182 
00183 //=======================================================================
00184 // Method: load
00185 //=======================================================================
00186 
00187 void pdf1d_exponential::b_read(vsl_b_istream& bfs)
00188 {
00189   if (!bfs) return;
00190 
00191   vcl_string name;
00192   vsl_b_read(bfs,name);
00193   if (name != is_a())
00194   {
00195     vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream&, pdf1d_exponential &)\n";
00196     vcl_cerr << "           Attempted to load object of type ";
00197     vcl_cerr << name <<" into object of type " << is_a() << vcl_endl;
00198     bfs.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00199     return;
00200   }
00201 
00202   short version;
00203   vsl_b_read(bfs,version);
00204   switch (version)
00205   {
00206     case (1):
00207       vsl_b_read(bfs,lambda_);
00208       break;
00209     default:
00210       vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream&, pdf1d_exponential &)\n";
00211       vcl_cerr << "           Unknown version number "<< version << vcl_endl;
00212       bfs.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00213       return;
00214   }
00215 
00216   set_lambda(lambda_);
00217 }
00218 
00219 //==================< end of pdf1d_exponential.cxx >====================