edoEstimatorNormalMulti.h
00001 /*
00002 The Evolving Distribution Objects framework (EDO) is a template-based,
00003 ANSI-C++ evolutionary computation library which helps you to write your
00004 own estimation of distribution algorithms.
00005 
00006 This library is free software; you can redistribute it and/or
00007 modify it under the terms of the GNU Lesser General Public
00008 License as published by the Free Software Foundation; either
00009 version 2.1 of the License, or (at your option) any later version.
00010 
00011 This library is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 Lesser General Public License for more details.
00015 
00016 You should have received a copy of the GNU Lesser General Public
00017 License along with this library; if not, write to the Free Software
00018 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00019 
00020 Copyright (C) 2010 Thales group
00021 */
00022 /*
00023 Authors:
00024     Johann Dréo <johann.dreo@thalesgroup.com>
00025     Caner Candan <caner.candan@thalesgroup.com>
00026 */
00027 
00028 
00029 #ifndef _edoEstimatorNormalMulti_h
00030 #define _edoEstimatorNormalMulti_h
00031 
00032 
00033 #include "edoEstimator.h"
00034 #include "edoNormalMulti.h"
00035 
00036 #ifdef WITH_BOOST
00037 #include <boost/numeric/ublas/symmetric.hpp>
00038 #include <boost/numeric/ublas/lu.hpp>
00039 namespace ublas = boost::numeric::ublas;
00040 #else
00041 #ifdef WITH_EIGEN
00042 #include <Eigen/Dense>
00043 #endif // WITH_EIGEN
00044 #endif // WITH_BOOST
00045 
00046 
00057 template < typename EOT, typename D=edoNormalMulti<EOT> >
00058 class edoEstimatorNormalMulti : public edoEstimator<D>
00059 {
00060 
00061 #ifdef WITH_BOOST
00062 public:
00063     class CovMatrix
00064     {
00065     public:
00066         typedef typename EOT::AtomType AtomType;
00067 
00068         CovMatrix( const eoPop< EOT >& pop )
00069         {
00070             //-------------------------------------------------------------
00071             // Some checks before starting to estimate covar
00072             //-------------------------------------------------------------
00073 
00074             unsigned int p_size = pop.size(); // population size
00075             assert(p_size > 0);
00076 
00077             unsigned int s_size = pop[0].size(); // solution size
00078             assert(s_size > 0);
00079 
00080             //-------------------------------------------------------------
00081 
00082 
00083             //-------------------------------------------------------------
00084             // Copy the population to an ublas matrix
00085             //-------------------------------------------------------------
00086 
00087             ublas::matrix< AtomType > sample( p_size, s_size );
00088 
00089             for (unsigned int i = 0; i < p_size; ++i)
00090                 {
00091                     for (unsigned int j = 0; j < s_size; ++j)
00092                         {
00093                             sample(i, j) = pop[i][j];
00094                         }
00095                 }
00096 
00097             //-------------------------------------------------------------
00098 
00099 
00100             _varcovar.resize(s_size);
00101 
00102 
00103             //-------------------------------------------------------------
00104             // variance-covariance matrix are symmetric (and semi-definite
00105             // positive), thus a triangular storage is sufficient
00106             //
00107             // variance-covariance matrix computation : transpose(A) * A
00108             //-------------------------------------------------------------
00109 
00110             ublas::symmetric_matrix< AtomType, ublas::lower > var = ublas::prod( ublas::trans( sample ), sample );
00111 
00112             // Be sure that the symmetric matrix got the good size
00113 
00114             assert(var.size1() == s_size);
00115             assert(var.size2() == s_size);
00116             assert(var.size1() == _varcovar.size1());
00117             assert(var.size2() == _varcovar.size2());
00118 
00119             //-------------------------------------------------------------
00120 
00121 
00122             // TODO: to remove the comment below
00123 
00124             // for (unsigned int i = 0; i < s_size; ++i)
00125             //         {
00126             //             // triangular LOWER matrix, thus j is not going further than i
00127             //             for (unsigned int j = 0; j <= i; ++j)
00128             //                 {
00129             //                     // we want a reducted covariance matrix
00130             //                     _varcovar(i, j) = var(i, j) / p_size;
00131             //                 }
00132             //         }
00133 
00134             _varcovar = var / p_size;
00135 
00136             _mean.resize(s_size); // FIXME: check if it is really used because of the assignation below
00137 
00138             // unit vector
00139             ublas::scalar_vector< AtomType > u( p_size, 1 );
00140 
00141             // sum over columns
00142             _mean = ublas::prod( ublas::trans( sample ), u );
00143 
00144             // division by n
00145             _mean /= p_size;
00146         }
00147 
00148         const ublas::symmetric_matrix< AtomType, ublas::lower >& get_varcovar() const {return _varcovar;}
00149 
00150         const ublas::vector< AtomType >& get_mean() const {return _mean;}
00151 
00152     private:
00153         ublas::symmetric_matrix< AtomType, ublas::lower > _varcovar;
00154         ublas::vector< AtomType > _mean;
00155     };
00156 
00157 public:
00158     typedef typename EOT::AtomType AtomType;
00159 
00160     edoNormalMulti< EOT > operator()(eoPop<EOT>& pop)
00161     {
00162         unsigned int popsize = pop.size();
00163         assert(popsize > 0);
00164 
00165         unsigned int dimsize = pop[0].size();
00166         assert(dimsize > 0);
00167 
00168         CovMatrix cov( pop );
00169 
00170         return edoNormalMulti< EOT >( cov.get_mean(), cov.get_varcovar() );
00171     }
00172 };
00173 
00174 #else
00175 #ifdef WITH_EIGEN
00176 
00177 public:
00178     class CovMatrix
00179     {
00180     public:
00181         typedef typename EOT::AtomType AtomType;
00182         typedef typename D::Vector Vector;
00183         typedef typename D::Matrix Matrix;
00184 
00185         CovMatrix( const eoPop< EOT >& pop )
00186         {
00187             // Some checks before starting to estimate covar
00188             unsigned int p_size = pop.size(); // population size
00189             assert(p_size > 0);
00190             unsigned int s_size = pop[0].size(); // solution size
00191             assert(s_size > 0);
00192 
00193             // Copy the population to an ublas matrix
00194             Matrix sample( p_size, s_size );
00195 
00196             for (unsigned int i = 0; i < p_size; ++i) {
00197                     for (unsigned int j = 0; j < s_size; ++j) {
00198                             sample(i, j) = pop[i][j];
00199                     }
00200             }
00201 
00202             // variance-covariance matrix are symmetric, thus a triangular storage is sufficient
00203             // variance-covariance matrix computation : transpose(A) * A
00204             Matrix var = sample.transpose() * sample;
00205 
00206             // Be sure that the symmetric matrix got the good size
00207             assert(var.innerSize() == s_size);
00208             assert(var.outerSize() == s_size);
00209 
00210             _varcovar = var / p_size;
00211 
00212             // unit vector
00213             Vector u( p_size);
00214             u = Vector::Constant(p_size, 1);
00215 
00216             // sum over columns
00217             _mean = sample.transpose() * u;
00218 
00219             // division by n
00220             _mean /= p_size;
00221         }
00222 
00223         const Matrix& get_varcovar() const {return _varcovar;}
00224 
00225         const Vector& get_mean() const {return _mean;}
00226 
00227     private:
00228         Matrix _varcovar;
00229         Vector _mean;
00230     };
00231 
00232 public:
00233     typedef typename EOT::AtomType AtomType;
00234 
00235     edoNormalMulti< EOT > operator()(eoPop<EOT>& pop)
00236     {
00237         unsigned int p_size = pop.size();
00238         assert(p_size > 0);
00239 
00240         unsigned int s_size = pop[0].size();
00241         assert(s_size > 0);
00242 
00243         CovMatrix cov( pop );
00244 
00245         assert( cov.get_mean().innerSize() == s_size );
00246         assert( cov.get_mean().outerSize() == 1 );
00247         assert( cov.get_varcovar().innerSize() == s_size );
00248         assert( cov.get_varcovar().outerSize() == s_size );
00249 
00250         return edoNormalMulti< EOT >( cov.get_mean(), cov.get_varcovar() );
00251     }
00252 #endif // WITH_EIGEN
00253 #endif // WITH_BOOST
00254 }; // class edoNormalMulti
00255 
00256 #endif // !_edoEstimatorNormalMulti_h
 All Classes Functions Variables Typedefs