contrib/brl/bbas/bsta/algo/bsta_parzen_updater.txx
Go to the documentation of this file.
00001 // This is brl/bbas/bsta/algo/bsta_parzen_updater.txx
00002 #ifndef bsta_parzen_updater_txx_
00003 #define bsta_parzen_updater_txx_
00004 //:
00005 // \file
00006 #include "bsta_parzen_updater.h"
00007 
00008 #if 0 // needs to be restructured in light of scalar samples
00009 //: The main function
00010 template <class parzen_dist_>
00011 void bsta_parzen_updater<parzen_dist_>::
00012 operator() ( parzen_dist_& pdist, const typename bsta_parzen_updater<parzen_dist_>::vector_& sample) const
00013 {
00014   typedef typename parzen_dist_::math_type T;
00015   unsigned n = pdist.size();
00016   T min_dist = vnl_numeric_traits<T>::maxval;
00017   unsigned closest_index = 0; // initialise to avoid compiler warning
00018   for (unsigned i = 0; i<n; ++i)
00019   {
00020     vector_ s = pdist.sample(i);
00021     vector_ dif = sample-s;
00022     T mag = dif.magnitude();
00023     if (mag<tol_) // no need to insert a sample within tol of and
00024       return;    // existing sample
00025     if (mag<min_dist)
00026     {
00027       min_dist = mag;
00028       closest_index = i;
00029     }
00030   }
00031   if (n==max_samples_) // replace closest parzen sample with new sample
00032     pdist.remove_sample(closest_index);
00033   pdist.insert_sample(sample);
00034 }
00035 
00036 template <class parzen_dist_>
00037 void bsta_parzen_adapt_bw_updater<parzen_dist_>::
00038 operator() ( parzen_dist_& pdist,
00039              const typename bsta_parzen_adapt_bw_updater<parzen_dist_>::vector_& sample) const
00040 {
00041   typedef typename parzen_dist_::math_type T;
00042   if (pdist.bandwidth_adapted())
00043     return;//don't update after bandwidth is set
00044   unsigned n = pdist.size();
00045   //set the bandwidth when max samples is reached
00046   if (n == max_samples_&&!pdist.bandwidth_adapted())
00047   {
00048     vcl_vector<vector_> all_samples = pdist.samples();
00049     // sort the samples. vless provides a descending
00050     // order based on the probability density of a sample, given
00051     // the Parzen distribution of the samples
00052     vless<T, data_dimension> pred(&pdist);
00053     vcl_sort(all_samples.begin(), all_samples.end(), pred);
00054     unsigned nback = static_cast<unsigned>(n*frac_background_);
00055     T fr = T(1)/static_cast<T>(nback);
00056     vector_ mean, xsq, mean_sq;
00057     mean.fill(T(0)), xsq.fill(T(0));
00058     for (unsigned i = 0; i<nback; ++i)
00059     {
00060       vector_ s = all_samples[i];
00061       mean += s;
00062       xsq += element_product(s,s);
00063     }
00064     mean_sq = element_product(mean,mean);
00065     vector_ var = fr*xsq - fr*fr*mean_sq;
00066     double max = 0;
00067     for (unsigned id = 0; id<data_dimension; ++id)
00068     {
00069       double v = static_cast<double>(var[id]);
00070       if (v>max)
00071         max = v;
00072     }
00073     double sd = vcl_sqrt(max);
00074     float bandwidth = static_cast<float>(2.65*sd*vcl_pow(double(nback), 0.2));
00075     pdist.set_bandwidth(bandwidth);
00076     pdist.set_bandwidth_adapted(true);
00077   }
00078   T min_dist = vnl_numeric_traits<T>::maxval;
00079   unsigned closest_index = 0; // initialise to avoid compiler warning
00080   for (unsigned i = 0; i<n; ++i)
00081   {
00082     vector_ s = pdist.sample(i);
00083     vector_ dif = sample-s;
00084     T mag = dif.magnitude();
00085     if (mag<tol_) // no need to insert a sample within tol of and
00086       return;    // existing sample
00087     if (mag<min_dist)
00088     {
00089       min_dist = mag;
00090       closest_index = i;
00091     }
00092   }
00093   if (n==max_samples_)//replace closest parzen sample with new sample
00094     pdist.remove_sample(closest_index);
00095   pdist.insert_sample(sample);
00096 }
00097 #else
00098 
00099 template <class parzen_dist_>
00100 void bsta_parzen_updater<parzen_dist_>::
00101 operator() ( parzen_dist_&, const typename bsta_parzen_updater<parzen_dist_>::vector_&) const {}
00102 
00103 template <class parzen_dist_>
00104 void bsta_parzen_adapt_bw_updater<parzen_dist_>::
00105 operator() ( parzen_dist_&, const typename bsta_parzen_adapt_bw_updater<parzen_dist_>::vector_&) const {}
00106 #endif
00107 
00108 #define BSTA_PARZEN_UPDATER_INSTANTIATE(T) \
00109 template class bsta_parzen_updater<T >; \
00110 template class bsta_parzen_adapt_bw_updater<T >
00111 
00112 #endif // bsta_parzen_updater_txx_