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