contrib/mul/vpdfl/vpdfl_kernel_pdf.cxx
Go to the documentation of this file.
00001 // This is mul/vpdfl/vpdfl_kernel_pdf.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 // \file
00007 // \brief Multi-variate kernel PDF
00008 // \author Tim Cootes
00009 
00010 #include "vpdfl_kernel_pdf.h"
00011 #include <vcl_string.h>
00012 #include <vcl_cassert.h>
00013 #include <vsl/vsl_indent.h>
00014 #include <vsl/vsl_vector_io.h>
00015 
00016 //=======================================================================
00017 // Dflt ctor
00018 //=======================================================================
00019 
00020 vpdfl_kernel_pdf::vpdfl_kernel_pdf()
00021 {
00022 }
00023 
00024 //=======================================================================
00025 // Destructor
00026 //=======================================================================
00027 
00028 vpdfl_kernel_pdf::~vpdfl_kernel_pdf()
00029 {
00030 }
00031 
00032 //: Compute mean/variance given current centres and widths
00033 void vpdfl_kernel_pdf::calc_mean_var()
00034 {
00035   int n = x_.size();
00036   assert(n>0);
00037   int t = x_[0].size();
00038   vnl_vector<double> m(t),v2(t);
00039   m.fill(0); v2.fill(0);
00040   double* v2_data = v2.data_block();
00041 
00042   for (int i=0;i<n;++i)
00043   {
00044     m += x_[i];
00045     double* x_data = x_[i].data_block();
00046     for (int j=0;j<t;++j)
00047       v2_data[j]+= x_data[j]*x_data[j];
00048   }
00049   m/=n;
00050 
00051   double sd=width_.rms();
00052   double extra_var = sd*sd;
00053   for (int j=0;j<t;++j)
00054   {
00055     v2_data[j]/=n;
00056     v2_data[j]+= extra_var - m[j]*m[j];
00057   }
00058 
00059 
00060   set_mean(m);
00061   set_variance(v2);
00062 }
00063 
00064 //: Initialise so all kernels have the same width
00065 void vpdfl_kernel_pdf::set_centres(const vnl_vector<double>* x, int n, double width)
00066 {
00067   x_.resize(n);
00068   for (int i=0;i<n;++i) x_[i] = x[i];
00069 
00070   width_.set_size(n);
00071   width_.fill(width);
00072   all_same_width_ = true;
00073 
00074   calc_mean_var();
00075 }
00076 
00077 //: Initialise so all kernels have given width
00078 void vpdfl_kernel_pdf::set_centres(const vnl_vector<double>* x, int n,
00079                                    const vnl_vector<double>& width)
00080 {
00081   assert((unsigned int)n==width.size());
00082   x_.resize(n);
00083   for (int i=0;i<n;++i) x_[i] = x[i];
00084   width_= width;
00085   all_same_width_ = false;
00086 
00087   calc_mean_var();
00088 }
00089 
00090 //=======================================================================
00091 // Method: is_a
00092 //=======================================================================
00093 
00094 vcl_string vpdfl_kernel_pdf::is_a() const
00095 {
00096   static const vcl_string s_ = "vpdfl_kernel_pdf";
00097   return s_;
00098 }
00099 
00100 //=======================================================================
00101 // Method: is_class
00102 //=======================================================================
00103 
00104 bool vpdfl_kernel_pdf::is_class(vcl_string const& s) const
00105 {
00106   return s==vpdfl_kernel_pdf::is_a() || vpdfl_pdf_base::is_class(s);
00107 }
00108 
00109 //=======================================================================
00110 // Method: version_no
00111 //=======================================================================
00112 
00113 short vpdfl_kernel_pdf::version_no() const
00114 {
00115   return 1;
00116 }
00117 
00118 //=======================================================================
00119 // Method: print
00120 //=======================================================================
00121 
00122 void vpdfl_kernel_pdf::print_summary(vcl_ostream& os) const
00123 {
00124   vpdfl_pdf_base::print_summary(os);
00125 }
00126 
00127 //=======================================================================
00128 // Method: save
00129 //=======================================================================
00130 
00131 void vpdfl_kernel_pdf::b_write(vsl_b_ostream& bfs) const
00132 {
00133   vsl_b_write(bfs,version_no());
00134   vpdfl_pdf_base::b_write(bfs);
00135   vsl_b_write(bfs,x_);
00136   vsl_b_write(bfs,width_);
00137 }
00138 
00139 //=======================================================================
00140 // Method: load
00141 //=======================================================================
00142 
00143 void vpdfl_kernel_pdf::b_read(vsl_b_istream& bfs)
00144 {
00145   if (!bfs) return;
00146 
00147   short version;
00148   vsl_b_read(bfs,version);
00149   switch (version)
00150   {
00151     case (1):
00152       vpdfl_pdf_base::b_read(bfs);
00153       vsl_b_read(bfs,x_);
00154       vsl_b_read(bfs,width_);
00155       break;
00156     default:
00157       vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream&, vpdfl_kernel_pdf &)\n"
00158                << "           Unknown version number "<< version << vcl_endl;
00159       bfs.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00160       return;
00161   }
00162 }