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