* 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(MO mo REQUIRED)
FIND_PACKAGE(Boost 1.33.0)
INCLUDE_DIRECTORIES(
${EO_INCLUDE_DIRS}
${MO_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
/Dev/ometah-0.3/common
)
######################################################################################

View file

@ -1,7 +1,12 @@
PROJECT(cma_sa)
FIND_PACKAGE(Boost 1.33.0)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})
SET(RESOURCES
cma_sa.param
plot.py
@ -20,4 +25,4 @@ FILE(GLOB SOURCES *.cpp)
SET(EXECUTABLE_OUTPUT_PATH ${DO_BINARY_DIR})
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)
{
hv.update( distrib.variance()[i] );
//hv.update( distrib.varcovar()[i] );
}
_ofs_params_var << hv << std::endl;
@ -286,7 +286,7 @@ public:
ofs << size << " ";
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;
}
@ -336,7 +336,7 @@ public:
for (int i = 0; i < size; ++i)
{
hv.update( distrib.variance()[i] );
//hv.update( distrib.varcovar()[i] );
}
_ofs_params_var << hv << std::endl;

View file

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

View file

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

View file

@ -6,6 +6,7 @@
#include "doSampler.h"
#include "doNormal.h"
#include "doBounder.h"
#include "doStats.h"
/**
* doSamplerNormal
@ -45,10 +46,16 @@ public:
for (unsigned int i = 0; i < size; ++i)
{
solution.push_back(
rng.normal(distrib.mean()[i],
distrib.variance()[i])
);
Cholesky< EOT > cholesky;
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
#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 <eoPop.h>
namespace ublas = boost::numeric::ublas;
class doStats : public eoPrintable
{
@ -110,9 +117,146 @@ protected:
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