contrib/mul/vpdfl/vpdfl_gaussian_sampler.cxx
Go to the documentation of this file.
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 }