Refactor edoBinomialMulti to allow more complex data structures

Refactor distribution, sampler and estimator related to the multi-binomial distribution.
This introduce tomic methods which may be overloaded for data structures more complex than eoReal of vector of bool (the
default implentation).
This commit is contained in:
Johann Dreo 2013-04-18 10:11:32 +02:00 committed by LPTK
commit 5caa49012f
3 changed files with 89 additions and 42 deletions

View file

@ -49,6 +49,13 @@ public:
edoBinomialMulti( T initial_probas ) edoBinomialMulti( T initial_probas )
: T(initial_probas) {} : T(initial_probas) {}
/** Initialize all the probabilities to a constant
*
* 0.5 by default
*/
edoBinomialMulti( unsigned int rows, unsigned int cols, double proba=0.5 )
: T::Constant(rows,cols,proba) {}
/** Constructor without any assumption. /** Constructor without any assumption.
*/ */
edoBinomialMulti() {} edoBinomialMulti() {}

View file

@ -42,18 +42,35 @@ template< class EOT, class D = edoBinomialMulti<EOT> >
class edoEstimatorBinomialMulti : public edoEstimator<D> class edoEstimatorBinomialMulti : public edoEstimator<D>
{ {
protected: protected:
D eot2d( EOT from, unsigned int rows, unsigned int cols ) // FIXME maybe more elegant with Eigen::Map? /** Decide whether a given element of the distribution is true or false.
*
* The default implementation is to set the item to the value of the atom itself
* (which is a boolean in the basic version).
* If you have a more complex data structure, you can just overload this.
*/
virtual void make( D & to, unsigned int i, unsigned int j, typename EOT::AtomType::const_iterator iatom )
{
to(i,j) = *iatom;
}
/** Transliterate a EOT in a boolean matrix
*/
D eot2d( const EOT & from, unsigned int rows, unsigned int cols ) // FIXME maybe more elegant with Eigen::Map?
{ {
assert( rows > 0 ); assert( rows > 0 );
assert( from.size() == rows ); assert( from.size() == rows );
assert( cols > 0 ); assert( cols > 0 );
D to( Eigen::MatrixXd(rows, cols) ); D to( Eigen::MatrixXd(rows, cols) );
for( unsigned int i=0; i < rows; ++i ) { unsigned int i=0;
assert( from[i].size() == cols ); for( typename EOT::const_iterator irow = from.begin(), end=from.end(); irow != end; ++irow ) {
for( unsigned int j=0; j < cols; ++j ) { assert( irow->size() == cols );
to(i,j) = from[i][j]; unsigned int j=0;
for( typename EOT::AtomType::const_iterator icol = irow->begin(), end=irow->end(); icol != end; ++icol ) {
make( to, i, j, icol );
j++;
} }
i++;
} }
return to; return to;
@ -67,9 +84,9 @@ class edoEstimatorBinomialMulti : public edoEstimator<D>
unsigned int popsize = pop.size(); unsigned int popsize = pop.size();
assert(popsize > 0); assert(popsize > 0);
unsigned int rows = pop[0].size(); unsigned int rows = pop.begin()->size();
assert( rows > 0 ); assert( rows > 0 );
unsigned int cols = pop[0][0].size(); unsigned int cols = pop.begin()->begin()->size();
assert( cols > 0 ); assert( cols > 0 );
D probas( D::Zero(rows, cols) ); D probas( D::Zero(rows, cols) );

View file

@ -44,6 +44,24 @@ template< class EOT, class D = edoBinomialMulti<EOT> >
class edoSamplerBinomialMulti : public edoSampler<D> class edoSamplerBinomialMulti : public edoSampler<D>
{ {
public: public:
typedef typename EOT::AtomType AtomType;
/** Called if the sampler draw the item at (i,j)
*
* The default implementation is to push back a true boolean.
* If you have a more complex data structure, you can just overload this.
*/
virtual void make_true( AtomType & atom, unsigned int i, unsigned int j )
{
atom.push_back( 1 );
}
/** @see make_true */
virtual void make_false( AtomType & atom, unsigned int i, unsigned int j )
{
atom.push_back( 0 );
}
EOT sample( D& distrib ) EOT sample( D& distrib )
{ {
unsigned int rows = distrib.rows(); unsigned int rows = distrib.rows();
@ -52,17 +70,22 @@ public:
assert(cols > 0); assert(cols > 0);
// The point we want to draw // The point we want to draw
// x = {x1, x2, ..., xn} // X = {x1, x2, ..., xn}
// with xn a container of booleans
EOT solution; EOT solution;
// Sampling all dimensions // Sampling all dimensions
for( unsigned int i = 0; i < rows; ++i ) { for( unsigned int i = 0; i < rows; ++i ) {
typename EOT::AtomType vec; AtomType atom;
for( unsigned int j = 0; j < cols; ++j ) { for( unsigned int j = 0; j < cols; ++j ) {
// Toss a coin, biased by the proba of being 1. // Toss a coin, biased by the proba of being 1.
vec.push_back( rng.flip( distrib(i,j) ) ); if( rng.flip( distrib(i,j) ) ) {
make_true( atom, i, j );
} else {
make_false( atom, i, j );
} }
solution.push_back( vec ); }
solution.push_back( atom );
} }
return solution; return solution;