* cholesky

This commit is contained in:
Caner Candan 2010-08-03 18:54:41 +02:00
commit 22602154fc
8 changed files with 195 additions and 33 deletions

View file

@ -25,9 +25,13 @@ INCLUDE(FindPkgConfig)
PKG_CHECK_MODULES(EO eo REQUIRED) PKG_CHECK_MODULES(EO eo REQUIRED)
PKG_CHECK_MODULES(MO mo REQUIRED) PKG_CHECK_MODULES(MO mo REQUIRED)
FIND_PACKAGE(Boost 1.33.0)
INCLUDE_DIRECTORIES( INCLUDE_DIRECTORIES(
${EO_INCLUDE_DIRS} ${EO_INCLUDE_DIRS}
${MO_INCLUDE_DIRS} ${MO_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
/Dev/ometah-0.3/common
) )
###################################################################################### ######################################################################################

View file

@ -1,7 +1,12 @@
PROJECT(cma_sa) PROJECT(cma_sa)
FIND_PACKAGE(Boost 1.33.0)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})
SET(RESOURCES SET(RESOURCES
cma_sa.param cma_sa.param
plot.py plot.py
@ -20,4 +25,4 @@ FILE(GLOB SOURCES *.cpp)
SET(EXECUTABLE_OUTPUT_PATH ${DO_BINARY_DIR}) SET(EXECUTABLE_OUTPUT_PATH ${DO_BINARY_DIR})
ADD_EXECUTABLE(${PROJECT_NAME} ${SOURCES}) ADD_EXECUTABLE(${PROJECT_NAME} ${SOURCES})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} do ${EO_LIBRARIES} ${MO_LIBRARIES}) TARGET_LINK_LIBRARIES(${PROJECT_NAME} do ${EO_LIBRARIES} ${MO_LIBRARIES} ${Boost_LIBRARIES})

View file

@ -168,7 +168,7 @@ public:
for (int i = 0; i < size; ++i) for (int i = 0; i < size; ++i)
{ {
hv.update( distrib.variance()[i] ); //hv.update( distrib.varcovar()[i] );
} }
_ofs_params_var << hv << std::endl; _ofs_params_var << hv << std::endl;
@ -286,7 +286,7 @@ public:
ofs << size << " "; ofs << size << " ";
std::copy(distrib.mean().begin(), distrib.mean().end(), std::ostream_iterator< double >(ofs, " ")); std::copy(distrib.mean().begin(), distrib.mean().end(), std::ostream_iterator< double >(ofs, " "));
std::copy(distrib.variance().begin(), distrib.variance().end(), std::ostream_iterator< double >(ofs, " ")); //std::copy(distrib.varcovar().begin(), distrib.varcovar().end(), std::ostream_iterator< double >(ofs, " "));
ofs << std::endl; ofs << std::endl;
} }
@ -336,7 +336,7 @@ public:
for (int i = 0; i < size; ++i) for (int i = 0; i < size; ++i)
{ {
hv.update( distrib.variance()[i] ); //hv.update( distrib.varcovar()[i] );
} }
_ofs_params_var << hv << std::endl; _ofs_params_var << hv << std::endl;

View file

@ -9,6 +9,8 @@ template < typename EOT >
class doEstimatorNormal : public doEstimator< doNormal< EOT > > class doEstimatorNormal : public doEstimator< doNormal< EOT > >
{ {
public: public:
typedef typename EOT::AtomType AtomType;
doNormal< EOT > operator()(eoPop<EOT>& pop) doNormal< EOT > operator()(eoPop<EOT>& pop)
{ {
unsigned int popsize = pop.size(); unsigned int popsize = pop.size();
@ -17,23 +19,12 @@ public:
unsigned int dimsize = pop[0].size(); unsigned int dimsize = pop[0].size();
assert(dimsize > 0); assert(dimsize > 0);
doCovMatrix cov(dimsize); //doCovMatrix cov(dimsize);
doUblasCovMatrix< EOT > cov;
for (unsigned int i = 0; i < popsize; ++i) cov.update(pop);
{
cov.update(pop[i]);
}
EOT mean(dimsize); return doNormal< EOT >(cov.get_mean(), cov.get_varcovar());
EOT covariance(dimsize);
for (unsigned int d = 0; d < dimsize; ++d)
{
mean[d] = cov.get_mean(d);
covariance[d] = cov.get_var(d);
}
return doNormal< EOT >(mean, covariance);
} }
}; };

View file

@ -8,8 +8,10 @@ template < typename EOT >
class doNormal : public doDistrib< EOT >, public doNormalParams< EOT > class doNormal : public doDistrib< EOT >, public doNormalParams< EOT >
{ {
public: public:
doNormal(EOT mean, EOT variance) typedef typename EOT::AtomType AtomType;
: doNormalParams< EOT >(mean, variance)
doNormal( const EOT& mean, const ublas::symmetric_matrix< AtomType, ublas::lower >& varcovar )
: doNormalParams< EOT >( mean, varcovar )
{} {}
}; };

View file

@ -1,29 +1,38 @@
#ifndef _doNormalParams_h #ifndef _doNormalParams_h
#define _doNormalParams_h #define _doNormalParams_h
#include <boost/numeric/ublas/symmetric.hpp>
#include <boost/numeric/ublas/lu.hpp>
namespace ublas = boost::numeric::ublas;
template < typename EOT > template < typename EOT >
class doNormalParams class doNormalParams
{ {
public: public:
doNormalParams(EOT mean, EOT variance) typedef typename EOT::AtomType AtomType;
: _mean(mean), _variance(variance)
doNormalParams(const EOT& mean, const ublas::symmetric_matrix< AtomType, ublas::lower >& varcovar)
: _mean(mean), _varcovar(varcovar)
{ {
assert(_mean.size() > 0); assert(_mean.size() > 0);
assert(_mean.size() == _variance.size()); assert(_mean.size() == _varcovar.size1());
assert(_mean.size() == _varcovar.size2());
} }
EOT& mean(){return _mean;} EOT& mean(){return _mean;}
EOT& variance(){return _variance;} ublas::symmetric_matrix< AtomType, ublas::lower >& varcovar(){return _varcovar;}
unsigned int size() unsigned int size()
{ {
assert(_mean.size() == _variance.size()); assert(_mean.size() == _varcovar.size1());
assert(_mean.size() == _varcovar.size2());
return _mean.size(); return _mean.size();
} }
private: private:
EOT _mean; EOT _mean;
EOT _variance; ublas::symmetric_matrix< AtomType, ublas::lower > _varcovar;
}; };
#endif // !_doNormalParams_h #endif // !_doNormalParams_h

View file

@ -6,6 +6,7 @@
#include "doSampler.h" #include "doSampler.h"
#include "doNormal.h" #include "doNormal.h"
#include "doBounder.h" #include "doBounder.h"
#include "doStats.h"
/** /**
* doSamplerNormal * doSamplerNormal
@ -45,10 +46,16 @@ public:
for (unsigned int i = 0; i < size; ++i) for (unsigned int i = 0; i < size; ++i)
{ {
solution.push_back( Cholesky< EOT > cholesky;
rng.normal(distrib.mean()[i],
distrib.variance()[i]) cholesky.update( distrib.varcovar() );
);
// solution.push_back(
// rng.normal(distrib.mean()[i],
// distrib.varcovar()[i])
// );
//rng.normal() +
} }
//------------------------------------------------------------- //-------------------------------------------------------------

View file

@ -18,7 +18,14 @@
#ifndef _doStats_h #ifndef _doStats_h
#define _doStats_h #define _doStats_h
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/symmetric.hpp>
#include <boost/numeric/ublas/lu.hpp>
#include <eoPrintable.h> #include <eoPrintable.h>
#include <eoPop.h>
namespace ublas = boost::numeric::ublas;
class doStats : public eoPrintable class doStats : public eoPrintable
{ {
@ -110,9 +117,146 @@ protected:
double _hv; double _hv;
}; };
class doCholesky : public doStats template < typename EOT >
class doUblasCovMatrix : public doStats
{ {
public:
typedef typename EOT::AtomType AtomType;
virtual void update( const eoPop< EOT >& pop )
{
unsigned int p_size = pop.size(); // population size
assert(p_size > 0);
unsigned int s_size = pop[0].size(); // solution size
assert(s_size > 0);
ublas::matrix< AtomType > sample( p_size, s_size );
for (unsigned int i = 0; i < p_size; ++i)
{
for (unsigned int j = 0; j < s_size; ++j)
{
sample(i, j) = pop[i][j];
}
}
_varcovar.resize(s_size, s_size);
// variance-covariance matrix are symmetric (and semi-definite positive),
// thus a triangular storage is sufficient
ublas::symmetric_matrix< AtomType, ublas::lower > var(s_size, s_size);
// variance-covariance matrix computation : A * transpose(A)
var = ublas::prod( sample, ublas::trans( sample ) );
for (unsigned int i = 0; i < s_size; ++i)
{
// triangular LOWER matrix, thus j is not going further than i
for (unsigned int j = 0; j <= i; ++j)
{
// we want a reducted covariance matrix
_varcovar(i, j) = var(i, j) / p_size;
}
}
//_varcovar = varcovar;
_mean.resize(s_size);
// unit vector
ublas::scalar_vector< AtomType > u( p_size, 1 );
// sum over columns
ublas::vector< AtomType > mean = ublas::prod( ublas::trans( sample ), u );
// division by n
mean /= p_size;
// copy results in the params std::vector
std::copy(mean.begin(), mean.end(), _mean.begin());
}
const ublas::symmetric_matrix< AtomType, ublas::lower >& get_varcovar() const {return _varcovar;}
const EOT& get_mean() const {return _mean;}
private:
ublas::symmetric_matrix< AtomType, ublas::lower > _varcovar;
EOT _mean;
};
template < typename EOT >
class Cholesky : public doStats
{
public:
typedef typename EOT::AtomType AtomType;
virtual void update( const ublas::symmetric_matrix< AtomType, ublas::lower >& V)
{
unsigned int Vl = V.size1();
assert(Vl > 0);
unsigned int Vc = V.size2();
assert(Vc > 0);
_L.resize(Vl, Vc);
unsigned int i,j,k;
// first column
i=0;
// diagonal
j=0;
_L(0, 0) = sqrt( V(0, 0) );
// end of the column
for ( j = 1; j < Vc; ++j )
{
_L(j, 0) = V(0, j) / _L(0, 0);
}
// end of the matrix
for ( i = 1; i < Vl; ++i )
{ // each column
// diagonal
double sum = 0.0;
for ( k = 0; k < i; ++k)
{
sum += _L(i, k) * _L(i, k);
}
assert( ( V(i, i) - sum ) > 0 );
_L(i, i) = sqrt( V(i, i) - sum );
for ( j = i + 1; j < Vl; ++j )
{ // rows
// one element
sum = 0.0;
for ( k = 0; k < i; ++k )
{
sum += _L(j, k) * _L(i, k);
}
_L(j, i) = (V(j, i) - sum) / _L(i, i);
}
}
}
const ublas::symmetric_matrix< AtomType, ublas::lower >& get_L() const {return _L;}
private:
ublas::symmetric_matrix< AtomType, ublas::lower > _L;
}; };
#endif // !_doStats_h #endif // !_doStats_h