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 >====================