00001 // This is mul/pdf1d/pdf1d_pdf.h 00002 #ifndef pdf1d_pdf_h 00003 #define pdf1d_pdf_h 00004 00005 //: 00006 // \file 00007 // \brief Base class for Univariate Probability Density Function classes. 00008 // \author Tim Cootes 00009 00010 #include <vsl/vsl_binary_io.h> 00011 #include <vcl_string.h> 00012 #include <vnl/vnl_vector.h> // HACK: IMS: don't replace this with vnl_fwd.h 00013 00014 //======================================================================= 00015 00016 class pdf1d_sampler; 00017 00018 //: Base class for Univariate Probability Density Function classes. 00019 // Functions are available to test the plausibility of a vector or 00020 // set of parameters, to modify a set of parameters so it is plausible 00021 // and to choose a threshold of plausibility. Also, for cases where 00022 // the distributions of parameters are multi-modal, the number and 00023 // centres of each peak can be recorded. 00024 // This is particularly useful for non-linear and mixture model 00025 // representations of the parameter distributions. 00026 class pdf1d_pdf 00027 { 00028 double mean_; 00029 double var_; 00030 protected: 00031 void set_mean(double m) { mean_ = m; } 00032 void set_variance(double v) { var_ = v; } 00033 public: 00034 00035 //: Dflt ctor 00036 pdf1d_pdf(); 00037 00038 //: Destructor 00039 virtual ~pdf1d_pdf(); 00040 00041 //: Mean of distribution 00042 double mean() const { return mean_; } 00043 00044 //: Variance of each dimension 00045 double variance() const { return var_; } 00046 00047 //: Number of peaks of distribution 00048 virtual int n_peaks() const { return 1; } 00049 00050 //: Position of the i'th peak 00051 virtual double peak(int) const { return mean_; } 00052 00053 //: Log of probability density at x 00054 virtual double log_p(double x) const =0; 00055 00056 //: Probability density at x 00057 virtual double operator()(double x) const; 00058 00059 //: Cumulative Probability (P(x'<x) for x' drawn from the distribution. 00060 // By default this can be calculated by drawing random samples from 00061 // the distribution and computing the number less than x. 00062 virtual double cdf(double x) const; 00063 00064 //: Return true if cdf() uses an analytic implementation. 00065 // Default is false, as the base implementation is to draw samples 00066 // from the distribution randomly to estimate cdf(x) 00067 virtual bool cdf_is_analytic() const; 00068 00069 //: The inverse cdf. 00070 // The value of x: P(x'<x) = P for x' drawn from distribution pdf. 00071 // The default version of this algorithm uses sampling if !cdf_is_analytic(), 00072 // and Newton-Raphson root finding otherwise. 00073 virtual double inverse_cdf(double P) const; 00074 00075 //: Gradient and value of PDF at x 00076 // Computes gradient of PDF at x, and returns the prob at x in p 00077 virtual double gradient(double x, double& p) const =0; 00078 00079 //: Create a sampler object on the heap 00080 // Caller is responsible for deletion. 00081 virtual pdf1d_sampler* new_sampler()const=0 ; 00082 00083 //: Compute threshold for PDF to pass a given proportion 00084 virtual double log_prob_thresh(double pass_proportion) const; 00085 00086 //: Compute nearest point to x which has a density above a threshold 00087 // If log_p(x)>log_p_min then x returned unchanged. Otherwise move 00088 // (typically up the gradient) until log_p(x)>=log_p_min. 00089 virtual double nearest_plausible(double x, double log_p_min)const =0; 00090 00091 //: Return true if the object represents a valid PDF. 00092 // This will return false, if n_dims() is 0, for example just ofter 00093 // default construction. 00094 virtual bool is_valid_pdf() const; 00095 00096 //: Fill x with samples drawn from distribution 00097 // Utility function. This calls new_sampler() to 00098 // do the work, then deletes the sampler again. 00099 // If you intend calling this repeatedly, create 00100 // a sampler yourself. 00101 void get_samples(vnl_vector<double>& x) const; 00102 00103 //: Version number for I/O 00104 short version_no() const; 00105 00106 //: Name of the class 00107 virtual vcl_string is_a() const; 00108 00109 //: Does the name of the class match the argument? 00110 virtual bool is_class(vcl_string const& s) const; 00111 00112 //: Create a copy on the heap and return base class pointer 00113 virtual pdf1d_pdf* clone() const = 0; 00114 00115 //: Print class to os 00116 virtual void print_summary(vcl_ostream& os) const = 0; 00117 00118 //: Save class to binary file stream 00119 virtual void b_write(vsl_b_ostream& bfs) const = 0; 00120 00121 //: Load class from binary file stream 00122 virtual void b_read(vsl_b_istream& bfs) = 0; 00123 00124 //: Write values (x,p(x)) to text file suitable for plotting 00125 // Evaluate pdf at n points in range [min_x,max_x] and write a text file, 00126 // each line of which is {x p(x)}, suitable for plotting with many graph packages 00127 bool write_plot_file(const vcl_string& plot_file, double min_x, double max_x, int n) const; 00128 }; 00129 00130 //: Allows derived class to be loaded by base-class pointer 00131 // A loader object exists which is invoked by calls 00132 // of the form "bfs>>base_ptr;". This loads derived class 00133 // objects from the disk, places them on the heap and 00134 // returns a base class pointer. 00135 // In order to work the loader object requires 00136 // an instance of each derived class that might be 00137 // found. This function gives the model class to 00138 // the appropriate loader. 00139 void vsl_add_to_binary_loader(const pdf1d_pdf& b); 00140 00141 //: Binary file stream output operator for class reference 00142 void vsl_b_write(vsl_b_ostream& bfs, const pdf1d_pdf& b); 00143 00144 //: Binary file stream input operator for class reference 00145 void vsl_b_read(vsl_b_istream& bfs, pdf1d_pdf& b); 00146 00147 //: Stream output operator for class reference 00148 void vsl_print_summary(vcl_ostream& os,const pdf1d_pdf& b); 00149 00150 //: Stream output operator for class pointer 00151 void vsl_print_summary(vcl_ostream& os,const pdf1d_pdf* b); 00152 00153 //: Stream output operator for class reference 00154 vcl_ostream& operator<<(vcl_ostream& os,const pdf1d_pdf& b); 00155 00156 //: Stream output operator for class pointer 00157 vcl_ostream& operator<<(vcl_ostream& os,const pdf1d_pdf* b); 00158 00159 #endif // pdf1d_pdf_h