contrib/mul/pdf1d/pdf1d_mixture_sampler.cxx
Go to the documentation of this file.
00001 // This is mul/pdf1d/pdf1d_mixture_sampler.cxx
00002 #include "pdf1d_mixture_sampler.h"
00003 //:
00004 // \file
00005 // \brief Implements sampling for a mixture model pdf sampler
00006 // \author Tim Cootes and Ian Scott
00007 //
00008 //=======================================================================
00009 
00010 #include "pdf1d_sampler.h"
00011 #include "pdf1d_mixture.h"
00012 #include <vcl_string.h>
00013 
00014 //=======================================================================
00015 
00016 void pdf1d_mixture_sampler::init()
00017 {
00018 }
00019 
00020 pdf1d_mixture_sampler::pdf1d_mixture_sampler():
00021   rng_(9667566ul)
00022 {
00023   init();
00024 }
00025 
00026 pdf1d_mixture_sampler::pdf1d_mixture_sampler(const pdf1d_mixture_sampler& m):
00027   pdf1d_sampler()
00028 {
00029   init();
00030   *this = m;
00031 }
00032 
00033 pdf1d_mixture_sampler& pdf1d_mixture_sampler::operator=(const pdf1d_mixture_sampler& m)
00034 {
00035   if (this==&m) return *this;
00036 
00037   delete_stuff();
00038 
00039   int n = m.inst_.size();
00040   inst_.resize(n);
00041   for (int i=0;i<n;++i)
00042     inst_[i] = m.inst_[i]->clone();
00043 
00044   return *this;
00045 }
00046 
00047 //=======================================================================
00048 
00049 void pdf1d_mixture_sampler::delete_stuff()
00050 {
00051   int n = inst_.size();
00052   for (int i=0;i<n;++i)
00053     delete inst_[i];
00054   inst_.resize(0);
00055 }
00056 
00057 pdf1d_mixture_sampler::~pdf1d_mixture_sampler()
00058 {
00059   delete_stuff();
00060 }
00061 
00062 //=======================================================================
00063 
00064 const pdf1d_mixture& pdf1d_mixture_sampler::mixture() const
00065 {
00066   return static_cast<const pdf1d_mixture&>(model());
00067 }
00068 
00069 // ====================================================================
00070 
00071 //: Set model for which this is an instance
00072 void pdf1d_mixture_sampler::set_model(const pdf1d_pdf& m)
00073 {
00074   pdf1d_sampler::set_model(m);
00075 
00076   const pdf1d_mixture& mix = mixture();
00077 
00078   int n = mix.n_components();
00079   delete_stuff();
00080   inst_.resize(n);
00081   for (int i=0;i<n;++i)
00082     inst_[i]=mix.components()[i]->new_sampler();
00083 }
00084 
00085 
00086 // ====================================================================
00087 
00088 //: For generating plausible examples
00089 double pdf1d_mixture_sampler::sample()
00090 {
00091   const pdf1d_mixture& mix = mixture();
00092   int max_comp = mix.n_components()-1;
00093 
00094   // Randomly choose a component according to the weights (assumed to sum to 1)
00095   double r = rng_.drand32(0.0, 1.0); // in [0,1]
00096   int i=0;
00097   r-=mix.weights()[i];
00098   while (r>0 && (i<max_comp))
00099   {
00100     i++;
00101     r-=mix.weights()[i];
00102   }
00103 
00104   return inst_[i]->sample();
00105 }
00106 
00107 //=======================================================================
00108 
00109 //: Reseeds the static random number generator (one per derived class)
00110 void pdf1d_mixture_sampler::reseed(unsigned long seed)
00111 {
00112   rng_.reseed(seed);
00113   for (unsigned int i=0; i<inst_.size(); ++i)
00114     inst_[i]->reseed(rng_.lrand32());
00115 }
00116 
00117 
00118 //=======================================================================
00119 
00120 vcl_string pdf1d_mixture_sampler::is_a() const
00121 {
00122   return vcl_string("pdf1d_mixture_sampler");
00123 }
00124 
00125 //=======================================================================
00126 
00127 bool pdf1d_mixture_sampler::is_class(vcl_string const& s) const
00128 {
00129   return pdf1d_sampler::is_class(s) || s==pdf1d_mixture_sampler::is_a();
00130 }
00131 
00132 //=======================================================================
00133 
00134 short pdf1d_mixture_sampler::version_no() const
00135 {
00136   return 1;
00137 }
00138 
00139 //=======================================================================
00140 
00141 pdf1d_sampler* pdf1d_mixture_sampler::clone() const
00142 {
00143   return new pdf1d_mixture_sampler(*this);
00144 }
00145 
00146 
00147 //==================< end of file: pdf1d_mixture_sampler.cxx >====================