contrib/brl/bbas/bsta/bsta_parzen_sphere.txx
Go to the documentation of this file.
00001 // This is brl/bbas/bsta/bsta_parzen_sphere.txx
00002 #ifndef bsta_parzen_sphere_txx_
00003 #define bsta_parzen_sphere_txx_
00004 //:
00005 // \file
00006 
00007 #include "bsta_parzen_sphere.h"
00008 //
00009 #include <vnl/vnl_vector_fixed.h>
00010 #include <vnl/vnl_matrix_fixed.h> // needed for bsta_parzen_sphere<T,n>::covar_type
00011 #include <vnl/vnl_numeric_traits.h>
00012 #include "bsta_gaussian_sphere.h"
00013 #include <vcl_cassert.h>
00014 
00015 //helper classes to support partial template instantiation on dimension
00016 //these functions work for any dimension
00017 namespace
00018 {
00019   template <class T, unsigned int n>
00020   typename bsta_distribution<T,n>::vector_type
00021   compute_mean(vcl_vector<typename bsta_distribution<T,n>::vector_type > const& samples)
00022   {
00023     typedef typename bsta_distribution<T,n>::vector_type vect_t;
00024     typedef typename vcl_vector<vect_t >::const_iterator sit_t;
00025     vect_t sum(T(0));
00026     sit_t sit = samples.begin();
00027     T nsamp = static_cast<T>(samples.size());
00028     for (; sit != samples.end(); ++sit)
00029       sum += (*sit);
00030     sum /= nsamp;
00031     return sum;
00032   }
00033 
00034 
00035   template <class T , unsigned int n >
00036   T compute_prob_density(typename bsta_distribution<T,n>::vector_type const& pt,
00037                          vcl_vector<typename bsta_distribution<T,n>::vector_type > const& samples, T var)
00038   {
00039     typedef typename bsta_distribution<T,n>::vector_type vect_t;
00040     typedef typename vcl_vector<vect_t >::const_iterator sit_t;
00041     unsigned size = samples.size();
00042     if (!size) return T(0);
00043     T nsamp = static_cast<T>(size);
00044     T density = static_cast<T>(0);
00045     vect_t null(T(0)); // works even if vector_ is equivalent to T, i.e. n =1
00046     bsta_gaussian_sphere<T,n> gs(null, var);
00047     sit_t sit = samples.begin();
00048     for (; sit != samples.end(); ++sit)
00049     {
00050       vect_t s = *sit;
00051       gs.set_mean(s);
00052       density += gs.prob_density(pt);
00053     }
00054     density/=nsamp;
00055     return density;
00056   }
00057 
00058   template <class T, unsigned int n>
00059   T compute_probability(typename bsta_distribution<T,n>::vector_type const& min_pt, typename bsta_distribution<T,n>::vector_type const& max_pt, vcl_vector<typename bsta_distribution<T,n>::vector_type > const& samples, T var)
00060   {
00061     typedef typename bsta_distribution<T,n>::vector_type vect_t;
00062     typedef typename vcl_vector<vect_t >::const_iterator sit_t;
00063     unsigned size = samples.size();
00064     if (!size) return static_cast<T>(0);
00065     T nsamp = static_cast<T>(size);
00066     T prob = static_cast<T>(0);
00067     vect_t null(T(0)); // works even if vector_ is equivalent to T, i.e. n =1
00068     bsta_gaussian_sphere<T,n> gs(null, var);
00069     sit_t sit = samples.begin();
00070     for (; sit != samples.end(); ++sit)
00071     {
00072       vect_t s = *sit;
00073       gs.set_mean(s);
00074       prob += gs.probability(min_pt, max_pt);
00075     }
00076     prob/=nsamp;
00077     return prob;
00078   }
00079 }; // end namespace
00080 
00081 // general case
00082 template <class T, unsigned int n>
00083 vnl_vector_fixed<T,n> bsta_parzen_sphere<T,n>::mean() const
00084 {
00085   return compute_mean<T,n>(bsta_parzen<T,n>::samples_);
00086 }
00087 
00088 // for scalar samples
00089 template <class T >
00090 T bsta_parzen_sphere<T,1>::mean() const
00091 {
00092   return compute_mean<T,1>(bsta_parzen<T,1>::samples_);
00093 }
00094 
00095 //: the covariance matrix for a Parzen distribution, general case
00096 template <class T, unsigned int n>
00097 typename bsta_parzen_sphere<T,n>::covar_type bsta_parzen_sphere<T,n>::covar() const
00098 {
00099   typedef typename bsta_distribution<T,n>::vector_type vect_t;
00100   typedef typename bsta_parzen<T,n>::sv_const_it sit_t;
00101   typedef typename bsta_parzen_sphere<T,n>::covar_type mat_t;
00102 
00103   unsigned size = bsta_parzen<T,n>::samples_.size();
00104   if (!size)
00105     return mat_t(T(0));
00106   // compute the sample covariance matrix
00107   mat_t scovar; // fill with zeros
00108   scovar.fill(T(0));
00109   for (sit_t sit = bsta_parzen<T,n>::samples_.begin();
00110        sit != bsta_parzen<T,n>::samples_.end(); ++sit)
00111   {
00112     vect_t s = *sit;
00113     for (unsigned r = 0; r<n; ++r){
00114       if (n>1)
00115         for (unsigned c = r; c<n; ++c)
00116           scovar[r][c] += s[r]*s[c];
00117       for (unsigned c = 0; c<r; ++c)
00118         scovar[r][c] = scovar[c][r];
00119     }
00120   }
00121   scovar/=static_cast<T>(size);
00122   vect_t mu = this->mean();
00123   for (unsigned r = 0; r<n; ++r) {
00124     if (n>1)
00125       for (unsigned c = r; c<n; ++c) {
00126         scovar[r][c] -= mu[r]*mu[c];
00127         if (r==c)
00128           scovar[r][c] += bandwidth_*bandwidth_;
00129       }
00130     for (unsigned c = 0; c<r; ++c)
00131       scovar[r][c] = scovar[c][r];
00132   }
00133   return scovar;
00134 }
00135 
00136 //: the covariance matrix for a Parzen distribution, specialization for 1-d case
00137 template <class T >
00138 T bsta_parzen_sphere<T,1>::covar() const
00139 {
00140   typedef typename bsta_parzen<T,1>::vect_t v_type;
00141   typedef typename bsta_parzen<T,1>::sv_const_it sit_t;
00142   unsigned size = bsta_parzen<T,1>::samples_.size();
00143   if (!size)
00144     return T(0);
00145   // compute the sample covariance matrix
00146   T scovar(0);
00147   for (sit_t sit = bsta_parzen<T,1>::samples_.begin();
00148        sit != bsta_parzen<T,1>::samples_.end(); ++sit)
00149   {
00150     v_type s = *sit;
00151     scovar += s*s;
00152   }
00153   scovar/=static_cast<T>(size);
00154   v_type mu = this->mean();
00155   scovar -= mu*mu;
00156   scovar += bandwidth_*bandwidth_;
00157   return scovar;
00158 }
00159 
00160 //: The probability density at sample pt, the general case
00161 template <class T, unsigned int n>
00162 T bsta_parzen_sphere<T,n>::prob_density(typename bsta_distribution<T,n>::vector_type const& pt) const
00163 {
00164   return compute_prob_density<T,n>(pt, bsta_parzen<T,n>::samples_,
00165                                    bandwidth_*bandwidth_);
00166 }
00167 
00168 //: The probability density at sample pt, specialized to scalar samples
00169 template <class T >
00170 T bsta_parzen_sphere<T,1>::
00171 prob_density(typename bsta_distribution<T,1>::vector_type const& pt) const
00172 {
00173   return compute_prob_density<T,1>(pt, bsta_parzen<T,1>::samples_,
00174                                    bandwidth_*bandwidth_);
00175 }
00176 
00177 //: The probability density integrated over a box, general case
00178 // \returns a probability
00179 template <class T, unsigned int n>
00180 T bsta_parzen_sphere<T,n>::probability(typename bsta_distribution<T,n>::vector_type const& min_pt,
00181                                        typename bsta_distribution<T,n>::vector_type const& max_pt) const
00182 {
00183   return compute_probability<T,n>(min_pt, max_pt, bsta_parzen<T,n>::samples_,
00184                                   bandwidth_*bandwidth_);
00185 }
00186 
00187 //: The probability density integrated over a box, specialized to scalar case
00188 // \returns a probability
00189 template <class T >
00190 T bsta_parzen_sphere<T,1>::
00191 probability(typename bsta_distribution<T,1>::vector_type const& min_pt,
00192             typename bsta_distribution<T,1>::vector_type const& max_pt) const
00193 {
00194   return compute_probability<T,1>(min_pt, max_pt, bsta_parzen<T,1>::samples_,
00195                                   bandwidth_*bandwidth_);
00196 }
00197 
00198 //: general case for distance and index of nearest sample
00199 template <class T, unsigned int n>
00200 T bsta_parzen_sphere<T,n>::nearest_sample(const typename bsta_distribution<T,n>::vector_type& pt, unsigned & index) const
00201 {
00202   typedef typename bsta_distribution<T,n>::vector_type vect_t;
00203   typedef typename bsta_parzen<T,n>::sv_const_it sit_t;
00204   T min_dist = vnl_numeric_traits<T>::maxval;
00205   unsigned count = 0; index = 0;
00206   for (sit_t sit = bsta_parzen<T,n>::samples_.begin();
00207        sit != bsta_parzen<T,n>::samples_.end(); ++sit, ++count)
00208   {
00209     vect_t s = *sit;
00210     vect_t dif = s-pt;
00211     T d = dif.magnitude();
00212     if (d<min_dist){
00213       index = count;
00214       min_dist = d;
00215     }
00216   }
00217   return min_dist;
00218 }
00219 
00220 //: distance to nearest sample, specialized to scalar case
00221 template <class T >
00222 T bsta_parzen_sphere<T,1>::nearest_sample(const typename bsta_distribution<T,1>::vector_type & pt, unsigned& index) const
00223 {
00224   typedef typename bsta_distribution<T,1>::vector_type vect_t;
00225   typedef typename bsta_parzen<T,1>::sv_const_it sit_t;
00226   T min_dist = vnl_numeric_traits<T>::maxval;
00227   unsigned count = 0; index = 0;
00228   for (sit_t sit = bsta_parzen<T,1>::samples_.begin();
00229        sit != bsta_parzen<T,1>::samples_.end(); ++sit, ++count)
00230   {
00231     vect_t s = *sit;
00232     vect_t dif = s-pt;
00233     T d = dif;
00234     if (d<0) d=-d;
00235     if (d<min_dist){
00236       index = count;
00237       min_dist = d;
00238     }
00239   }
00240   return min_dist;
00241 }
00242 
00243 #define BSTA_PARZEN_SPHERE_INSTANTIATE(T,n) \
00244 template class bsta_parzen_sphere<T,n >
00245 
00246 #endif // bsta_parzen_sphere_txx_