contrib/mul/pdf1d/pdf1d_weighted_kernel_pdf.cxx
Go to the documentation of this file.
00001 // This is mul/pdf1d/pdf1d_weighted_kernel_pdf.cxx
00002 
00003 //:
00004 // \file
00005 // \brief ...
00006 // \author Ian Scott
00007 // \date   Tue Apr  9 14:00:27 2002
00008 
00009 
00010 #include "pdf1d_weighted_kernel_pdf.h"
00011 #include <vcl_iostream.h>
00012 #include <vcl_string.h>
00013 #include <vcl_cassert.h>
00014 #include <vsl/vsl_indent.h>
00015 #include <vnl/vnl_math.h>
00016 #include <vnl/io/vnl_io_vector.h>
00017 #include <vsl/vsl_binary_loader.h>
00018 
00019 
00020 //:calc the weighted mean and var of kernels.
00021 // w is expected to sum to n.
00022 void pdf1d_weighted_kernel_pdf::pdf1d_weighted_kernel_mean_var(double& mean, double& var,
00023                                                                const vnl_vector<double>& centres,
00024                                                                const vnl_vector<double>& widths,
00025                                                                const vnl_vector<double>& weights)
00026 {
00027   const unsigned n = centres.size();
00028   assert(n > 1 && widths.size() == n && weights.size() ==n);
00029 
00030   double sum=0;
00031   double sum2 = 0;
00032   double sum3 = 0;
00033   double sum_weights = 0.0;
00034   for (unsigned i=0;i<n;++i)
00035   {
00036     sum+=weights(i) * centres(i);
00037     sum2+=weights(i) * vnl_math_sqr(centres(i));
00038     sum3+=weights(i) * vnl_math_sqr(widths(i));
00039     sum_weights += weights(i);
00040   }
00041 
00042   mean = sum/sum_weights;
00043   //variance = weighted variance of centres + weighted mean square of widths
00044   var  = (sum2 - n*mean*mean)/(n-1) + sum3/sum_weights;
00045 }
00046 
00047   //: Initialise so all kernels have the same width
00048 void pdf1d_weighted_kernel_pdf::set_centres(const vnl_vector<double>& x, double width)
00049 {
00050   pdf1d_kernel_pdf::set_centres(x, width);
00051   weight_.set_size(x.size());
00052   weight_.fill(1.0);
00053   sum_weights_ = x.size();
00054 }
00055 
00056   //: Initialise so all kernels have given width
00057 void pdf1d_weighted_kernel_pdf::set_centres(const vnl_vector<double>& x,
00058                                             const vnl_vector<double>& width)
00059 {
00060   pdf1d_kernel_pdf::set_centres(x, width);
00061   weight_.set_size(x.size());
00062   weight_.fill(1.0);
00063   sum_weights_ = x.size();
00064 }
00065 
00066 
00067 //=======================================================================
00068 
00069   //: Set the weights
00070 void pdf1d_weighted_kernel_pdf::set_weight(const vnl_vector<double>& weights)
00071 {
00072   assert(weights.size() == x_.size());
00073 
00074   weight_ = weights;
00075   sum_weights_ = vnl_c_vector<double>::sum(weight_.data_block(), weight_.size());
00076 
00077   double m,v;
00078   pdf1d_weighted_kernel_mean_var(m,v,x_, width_, weight_);
00079   set_mean(m);
00080   set_variance(v);
00081 }
00082 
00083 //=======================================================================
00084 
00085   //: Swap in the weights values.
00086   // This function is fast when you are changing the weights regularly
00087   // The weights will be scaled to sum to n
00088 void pdf1d_weighted_kernel_pdf::swap_weight(vnl_vector<double>& weights)
00089 {
00090   assert(weights.size() == x_.size());
00091 
00092   swap(weights, weight_);
00093   sum_weights_ = vnl_c_vector<double>::sum(weight_.data_block(), weight_.size());
00094 }
00095 
00096 //=======================================================================
00097 
00098 short pdf1d_weighted_kernel_pdf::version_no() const
00099 {
00100   return 1;
00101 }
00102 
00103 //=======================================================================
00104 
00105 bool pdf1d_weighted_kernel_pdf::is_class(vcl_string const& s) const
00106 {
00107   return s == pdf1d_weighted_kernel_pdf::is_a() || pdf1d_kernel_pdf::is_class(s);
00108 }
00109 
00110 //=======================================================================
00111 
00112 vcl_string pdf1d_weighted_kernel_pdf::is_a() const
00113 {
00114   return vcl_string("pdf1d_weighted_kernel_pdf");
00115 }
00116 
00117 
00118 //=======================================================================
00119 
00120     // required if data is present in this base class
00121 void pdf1d_weighted_kernel_pdf::print_summary(vcl_ostream& os) const
00122 {
00123   pdf1d_kernel_pdf::print_summary(os);
00124   os << vsl_indent() << "Weights: "; vsl_print_summary(os, weight_) ; os << '\n';
00125 }
00126 
00127 //=======================================================================
00128 
00129   // required if data is present in this base class
00130 void pdf1d_weighted_kernel_pdf::b_write(vsl_b_ostream& bfs) const
00131 {
00132   vsl_b_write(bfs, version_no());
00133   pdf1d_kernel_pdf::b_write(bfs);
00134   vsl_b_write(bfs, weight_);
00135 }
00136 
00137 //=======================================================================
00138 
00139   // required if data is present in this base class
00140 void pdf1d_weighted_kernel_pdf::b_read(vsl_b_istream& bfs)
00141 {
00142   if (!bfs) return;
00143 
00144   short version;
00145   vsl_b_read(bfs,version);
00146   switch (version)
00147   {
00148   case (1):
00149     pdf1d_kernel_pdf::b_read(bfs);
00150     vsl_b_read(bfs,weight_);
00151     sum_weights_ = vnl_c_vector<double>::sum(weight_.data_block(), weight_.size());
00152 
00153     break;
00154   default:
00155     vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream&, pdf1d_weighted_kernel_pdf&)\n"
00156              << "           Unknown version number "<< version << '\n';
00157     bfs.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00158     return;
00159   }
00160 }