00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00041 
#include "VMatrixFromDistribution.h"
00042 
00043 
namespace PLearn {
00044 
using namespace std;
00045 
00046 VMatrixFromDistribution::VMatrixFromDistribution() 
00047   :
mode("
sample"), generator_seed(0), nsamples(0)
00048   
00049 {
00050   
samples_per_dim = 10;
00051 }
00052 
00053 
PLEARN_IMPLEMENT_OBJECT(
VMatrixFromDistribution, 
"A VMatrix built from sampling a distribution", 
00054                         
"VMatrixFromDistribution implements a VMatrix whose data rows are drawn from a distribution\n"
00055                         
"or that contains the density or log density sampled on a grid (depending on \"mode\").\n"
00056                         
"The matrix is computed in memory at build time\n");
00057 
00058 void VMatrixFromDistribution::declareOptions(
OptionList& ol)
00059 {
00060   
declareOption(ol, 
"distr", &VMatrixFromDistribution::distr, OptionBase::buildoption,
00061                 
"The distribution this matrix will be generated from\n");
00062 
00063   
declareOption(ol, 
"mode", &VMatrixFromDistribution::mode, OptionBase::buildoption,
00064                 
"mode can be one of:\n"
00065                 
"   \"sample\" : will draw nsamples from the distribution initializing the generator with the generator_seed \n"
00066                 
"   \"density\" : for 1d or 2d distributions, will report the density along a grid of samples_per_dim \n"
00067                 
"                 gridpoints per dimension. The resulting matrix will contain rows of the form [ coordinates density ] \n"
00068                 
"   \"log_density\" : same as density, but reports the log of the density instead. \n"
00069                 );
00070 
00071   
declareOption(ol, 
"generator_seed", &VMatrixFromDistribution::generator_seed, OptionBase::buildoption,
00072                 
"The initial generator_seed to initialize the distribution's generator");
00073 
00074   
declareOption(ol, 
"nsamples", &VMatrixFromDistribution::nsamples, OptionBase::buildoption,
00075                 
"number of samples to draw");
00076 
00077   
declareOption(ol, 
"samples_per_dim", &VMatrixFromDistribution::samples_per_dim, OptionBase::buildoption,
00078                 
"number of samples on each dimensions of the grid");
00079 
00080   
declareOption(ol, 
"mins", &VMatrixFromDistribution::mins, OptionBase::buildoption,
00081                 
"the minimum of the grid on each dimensions");
00082 
00083   
declareOption(ol, 
"maxs", &VMatrixFromDistribution::maxs, OptionBase::buildoption,
00084                 
"the maximum of the grid on each dimensions");
00085 
00086   inherited::declareOptions(ol);
00087 }
00088 
00089 void VMatrixFromDistribution::build_()
00090 {
00091   
if(
distr)
00092     {
00093       
if(
mode==
"sample")
00094       {
00095         length_ = 
nsamples;
00096         width_ = 
distr->inputsize();
00097         inputsize_ = width_;
00098         targetsize_ = 0;
00099         weightsize_ = 0;
00100         
data.
resize(length_, width_);
00101         
distr->resetGenerator(
generator_seed);
00102         
distr->generateN(
data);
00103       }
00104       
else if(
mode==
"density" || 
mode==
"log_density")
00105       {
00106         length_ = (
int)
pow(
double(
samples_per_dim),
double(
distr->inputsize()));
00107         width_ = 
distr->inputsize()+1;
00108         inputsize_ = 
distr->inputsize();
00109         targetsize_ = 0;
00110         weightsize_ = 1;
00111         
00112         
data.
resize(length_, width_);
00113         
Vec v(
data.
width());
00114         
int k=0;
00115         
switch(
distr->inputsize())
00116         {
00117         
case 1:
00118           
for(
int j=0;j<samples_per_dim;j++)
00119           {
00120             v[0] = 
mins[0] + ((
real)j / (samples_per_dim-1)) * (
maxs[0]-mins[0]);
00121             
if(
mode==
"density")
00122               v[1] = 
distr->density(v.
subVec(0,1));
00123             
else 
00124               v[1] = 
distr->log_density(v.
subVec(0,1));
00125             
data(
k++)<<v;
00126           }
00127           
break;
00128         
case 2:
00129           
for(
int i=0;i<samples_per_dim;i++)
00130           {
00131             v[0] = 
mins[0] + ((
real)i / (samples_per_dim-1)) * (
maxs[0]-mins[0]);
00132             
for(
int j=0;j<samples_per_dim;j++)
00133             {
00134               v[1] = mins[1] + ((
real)j / (samples_per_dim-1)) * (
maxs[1]-mins[1]);
00135               
if(
mode==
"density")
00136                 v[2] = 
distr->density(v.
subVec(0,2));
00137               
else 
00138                 v[2] = 
distr->log_density(v.
subVec(0,2));
00139               
data(
k++)<<v;
00140             }
00141           }
00142           
break;
00143         
default: 
00144           
PLERROR(
"density and log_density modes only supported for distribution of dimension 1 or 2");
break;
00145         }
00146       }
00147       
else
00148         
PLERROR(
"In VMatrixFromDistribution: invalid mode: %s",
mode.c_str());
00149     }
00150 }
00151 
00152 
00153 void VMatrixFromDistribution::build()
00154 {
00155   inherited::build();
00156   
build_();
00157 }
00158 
00159 void VMatrixFromDistribution::makeDeepCopyFromShallowCopy(map<const void*, void*>& copies)
00160 {
00161   inherited::makeDeepCopyFromShallowCopy(copies);
00162 }
00163 
00164 real VMatrixFromDistribution::get(
int i, 
int j)
 const
00165 
{ 
return data(i,j); }
00166 
00167 void VMatrixFromDistribution::getColumn(
int i, 
Vec v)
 const
00168 
{ v << 
data.
column(i); }
00169 
00170 void VMatrixFromDistribution::getSubRow(
int i, 
int j, 
Vec v)
 const
00171 
{ v << 
data(i).subVec(j,v.
length()); }
00172 
00173 void VMatrixFromDistribution::getRow(
int i, 
Vec v)
 const
00174 
{ v << 
data(i); }
00175 
00176 void VMatrixFromDistribution::getMat(
int i, 
int j, 
Mat m)
 const
00177 
{ m << 
data.
subMat(i,j,m.
length(),m.
width()); }
00178 
00179 Mat VMatrixFromDistribution::toMat()
 const
00180 
{ 
return data; }
00181 
00182 }