core/vpdl/vpdl_kernel_base.h
Go to the documentation of this file.
00001 // This is core/vpdl/vpdl_kernel_base.h
00002 #ifndef vpdl_kernel_base_h_
00003 #define vpdl_kernel_base_h_
00004 //:
00005 // \file
00006 // \author Matthew Leotta
00007 // \date February 24, 2009
00008 // \brief Base classes for kernel (aka Parzen window) distributions
00009 //
00010 // \verbatim
00011 //  Modifications
00012 //   None
00013 // \endverbatim
00014 
00015 #include <vpdl/vpdl_multi_cmp_dist.h>
00016 #include <vpdl/vpdt/vpdt_access.h> // function vpdt_size(v)
00017 #include <vcl_cassert.h>
00018 #include <vcl_vector.h>
00019 
00020 //: A base class for kernel (aka Parzen window) distributions
00021 // A kernel distribution is restricted form of a mixture where each component
00022 // has the same weight and takes the same form.  Essentially, a copy of a single
00023 // distribution is translated (and possibly scaled) to each point in a collection
00024 // of samples
00025 template<class T, unsigned int n=0>
00026 class vpdl_kernel_base : public vpdl_multi_cmp_dist<T,n>
00027 {
00028  public:
00029   //: the data type used for vectors
00030   typedef typename vpdt_field_default<T,n>::type vector;
00031   //: the data type used for matrices
00032   typedef typename vpdt_field_traits<vector>::matrix_type matrix;
00033 
00034   // Default Constructor
00035   vpdl_kernel_base()  {}
00036 
00037   // Constructor from sample points
00038   vpdl_kernel_base(const vcl_vector<vector>& samplez)
00039   : samples_(samplez) {}
00040 
00041   //: Return the number of components in the mixture
00042   unsigned int num_components() const { return samples_.size(); }
00043 
00044   //: Return the run time dimension, which does not equal \c n when \c n==0
00045   virtual unsigned int dimension() const
00046   {
00047     if (n > 0 || num_components() == 0)
00048       return n;
00049     return vpdt_size(samples_[0]);
00050   }
00051 
00052   //: Add a new sample point
00053   virtual void add_sample(const vector& s)
00054   {
00055     // set variable dimension from the first inserted component
00056     assert(vpdt_size(s) == this->dimension() || num_components() == 0);
00057     samples_.push_back(s);
00058   }
00059 
00060   //: Remove all sample points
00061   virtual void clear_samples()
00062   {
00063     samples_.clear();
00064   }
00065 
00066   //: Set the collection of sample points
00067   virtual void set_samples(const vcl_vector<vector>& samplez)
00068   {
00069     samples_ = samplez;
00070   }
00071 
00072   //: Access the sample points
00073   const vcl_vector<vector>& samples() const
00074   {
00075     return samples_;
00076   }
00077 
00078   //: Compute the mean of the distribution.
00079   // Assume that each kernel has its mean at the sample point
00080   virtual void compute_mean(vector& mean) const
00081   {
00082     const unsigned int d = this->dimension();
00083     vpdt_set_size(mean,d);
00084     vpdt_fill(mean,T(0));
00085     if (samples_.empty())
00086       return;
00087     typedef typename vcl_vector<vector>::const_iterator samp_itr;
00088     for (samp_itr s = samples_.begin(); s != samples_.end(); ++s) {
00089       mean += *s;
00090     }
00091     mean /= T(samples_.size());
00092   }
00093 
00094  private:
00095   //: The sample points around which the kernels are centered
00096   vcl_vector<vector> samples_;
00097 };
00098 
00099 
00100 //: A base class for fixed bandwidth kernel distributions
00101 // This class assumes that the bandwidth is fixed for all kernels
00102 template<class T, unsigned int n=0>
00103 class vpdl_kernel_fbw_base : public vpdl_kernel_base<T,n>
00104 {
00105  public:
00106   //: the data type used for vectors
00107   typedef typename vpdt_field_default<T,n>::type vector;
00108   //: the data type used for matrices
00109   typedef typename vpdt_field_traits<vector>::matrix_type matrix;
00110 
00111   // Default Constructor
00112   vpdl_kernel_fbw_base()
00113   : bandwidth_(T(1)) {}
00114 
00115   // Constructor from sample points and a bandwidth
00116   vpdl_kernel_fbw_base(const vcl_vector<vector>& samplez, T bandwid = T(1))
00117   : vpdl_kernel_base<T,n>(samplez), bandwidth_(bandwid) {}
00118 
00119   //: Access the bandwidth
00120   T bandwidth() const { return bandwidth_; }
00121 
00122   //: Set the kernel bandwidth
00123   void set_bandwidth(T b) { bandwidth_ = b; }
00124 
00125   //: The normalization constant for the kernel
00126   virtual T kernel_norm_const() const = 0;
00127 
00128   //: The normalization constant for the density
00129   // When density() is multiplied by this value it becomes prob_density
00130   // norm_const() is reciprocal of the integral of density over the entire field
00131   virtual T norm_const() const
00132   {
00133     return kernel_norm_const()/this->num_components();
00134   }
00135 
00136  private:
00137   //: the fixed bandwidth for all kernels
00138   T bandwidth_;
00139 };
00140 
00141 
00142 //: A base class for variable bandwidth kernel distributions
00143 // This class assumes that each sample has its own bandwidth
00144 template<class T, unsigned int n=0>
00145 class vpdl_kernel_vbw_base : public vpdl_kernel_base<T,n>
00146 {
00147  public:
00148   //: the data type used for vectors
00149   typedef typename vpdt_field_default<T,n>::type vector;
00150   //: the data type used for matrices
00151   typedef typename vpdt_field_traits<vector>::matrix matrix;
00152 
00153   // Default Constructor
00154   vpdl_kernel_vbw_base(unsigned int var_dim = n)
00155   : vpdl_kernel_base<T,n>(var_dim) {}
00156 
00157   // Constructor from sample points and bandwidths
00158   vpdl_kernel_vbw_base(const vcl_vector<vector>& samplez,
00159                        const vcl_vector<T>& bandwidthz)
00160   : vpdl_kernel_base<T,n>(samplez), bandwidths_(bandwidthz) {}
00161 
00162   //: Add a new sample point
00163   virtual void add_sample(const vector& s)
00164   {
00165     vpdl_kernel_base<T,n>::add_sample(s);
00166     bandwidths_.push_back(T(1));
00167   }
00168 
00169   //: Add a new sample point with bandwidth
00170   virtual void add_sample(const vector& s, T bw)
00171   {
00172     vpdl_kernel_base<T,n>::add_sample(s);
00173     bandwidths_.push_back(bw);
00174   }
00175 
00176   //: Remove all sample points
00177   virtual void clear_samples()
00178   {
00179     vpdl_kernel_base<T,n>::clear_samples();
00180     bandwidths_.clear();
00181   }
00182 
00183   //: Set the collection of sample points
00184   virtual void set_samples(const vcl_vector<vector>& samplez)
00185   {
00186     vpdl_kernel_base<T,n>::set_samples(samplez);
00187     bandwidths_.clear();
00188     bandwidths_.resize(samplez.size(),T(1));
00189   }
00190 
00191   //: Set the collection of sample points and bandwidths
00192   virtual void set_samples(const vcl_vector<vector>& samplez,
00193                            const vcl_vector<T>& bandwidthz)
00194   {
00195     assert(samplez.size() == bandwidthz.size());
00196     vpdl_kernel_base<T,n>::set_samples(samplez);
00197     bandwidths_ = bandwidthz;
00198   }
00199 
00200   //: Access the bandwidths
00201   const vcl_vector<T>& bandwidths() const { return bandwidths_; }
00202 
00203  private:
00204   //: the bandwidths for each kernel
00205   vcl_vector<T> bandwidths_;
00206 };
00207 
00208 
00209 #endif // vpdl_kernel_base_h_