00001 // This is mul/vpdfl/vpdfl_gaussian_sampler.cxx 00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE 00003 #pragma implementation 00004 #endif 00005 //: 00006 // \file 00007 // \author Ian Scott 00008 // \date 12-Apr-2001 00009 // \brief Sampler class for Multi-Variate Gaussian classes. 00010 00011 #include "vpdfl_gaussian_sampler.h" 00012 00013 #include <vcl_cmath.h> 00014 #include <vpdfl/vpdfl_gaussian.h> 00015 #include <mbl/mbl_matxvec.h> 00016 00017 //======================================================================= 00018 // Dflt ctor 00019 //======================================================================= 00020 00021 vpdfl_gaussian_sampler::vpdfl_gaussian_sampler(): 00022 rng_(9667566ul) 00023 { 00024 } 00025 00026 //======================================================================= 00027 // Destructor 00028 //======================================================================= 00029 00030 vpdfl_gaussian_sampler::~vpdfl_gaussian_sampler() 00031 { 00032 } 00033 00034 00035 //======================================================================= 00036 // Method: is_a 00037 //======================================================================= 00038 00039 vcl_string vpdfl_gaussian_sampler::is_a() const 00040 { 00041 return vcl_string("vpdfl_gaussian_sampler"); 00042 } 00043 00044 //======================================================================= 00045 // Method: is_class 00046 //======================================================================= 00047 00048 bool vpdfl_gaussian_sampler::is_class(vcl_string const& s) const 00049 { 00050 return vpdfl_sampler_base::is_class(s) || s==vpdfl_gaussian_sampler::is_a(); 00051 } 00052 00053 //======================================================================= 00054 00055 00056 void vpdfl_gaussian_sampler::reseed(unsigned long seed) 00057 { 00058 rng_.reseed(seed); 00059 } 00060 00061 //======================================================================= 00062 00063 00064 //: Return a reference to the pdf model 00065 // This is properly cast. 00066 const vpdfl_gaussian& vpdfl_gaussian_sampler::gaussian() const 00067 { 00068 return static_cast<const vpdfl_gaussian&>(model()); 00069 } 00070 00071 //======================================================================= 00072 00073 void vpdfl_gaussian_sampler::sample(vnl_vector<double>& x) 00074 { 00075 const vpdfl_gaussian& gauss = gaussian(); 00076 00077 const double *evals = gauss.eigenvals().data_block(); 00078 00079 int n = gauss.n_dims(); 00080 00081 // Generate random sample in coordinate frame of PCA 00082 b_.set_size(n); 00083 00084 double* b_data = b_.data_block(); 00085 for (int i=0;i<n;++i) 00086 b_data[i] = vcl_sqrt(evals[i])*rng_.normal(); 00087 00088 // Transform sample into x space 00089 mbl_matxvec_prod_mv(gauss.eigenvecs(),b_,x); 00090 x+=gauss.mean(); 00091 } 00092 00093 //======================================================================= 00094 // Method: clone 00095 //======================================================================= 00096 00097 vpdfl_sampler_base* vpdfl_gaussian_sampler::clone() const 00098 { 00099 return new vpdfl_gaussian_sampler(*this); 00100 }