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 #ifndef _edoSamplerNormalMulti_h
00029 #define _edoSamplerNormalMulti_h
00030
00031 #include <cmath>
00032 #include <limits>
00033
00034 #include <edoSampler.h>
00035
00036
00037 #ifdef WITH_BOOST
00038 #include <utils/edoCholesky.h>
00039 #include <boost/numeric/ublas/lu.hpp>
00040 #include <boost/numeric/ublas/symmetric.hpp>
00041 namespace ublas = boost::numeric::ublas;
00042 #else
00043 #ifdef WITH_EIGEN
00044 #include <Eigen/Dense>
00045 #endif // WITH_EIGEN
00046 #endif // WITH_BOOST
00047
00048
00064 template< typename EOT, typename D = edoNormalMulti< EOT > >
00065 class edoSamplerNormalMulti : public edoSampler< D >
00066 {
00067
00068 #ifdef WITH_BOOST
00069
00070 public:
00071 typedef typename EOT::AtomType AtomType;
00072
00073 edoSamplerNormalMulti( edoRepairer<EOT> & repairer )
00074 : edoSampler< D >( repairer)
00075 {}
00076
00077
00078 EOT sample( D& distrib )
00079 {
00080 unsigned int size = distrib.size();
00081 assert(size > 0);
00082
00083
00084 const typename cholesky::CholeskyBase<AtomType>::FactorMat& L = _cholesky( distrib.varcovar() );
00085
00086
00087 ublas::vector< AtomType > T( size );
00088 for ( unsigned int i = 0; i < size; ++i ) {
00089 T( i ) = rng.normal();
00090 }
00091
00092
00093 ublas::vector< AtomType > LT = ublas::prod( L, T );
00094
00095
00096 ublas::vector< AtomType > mean = distrib.mean();
00097 ublas::vector< AtomType > ublas_solution = mean + LT;
00098 EOT solution( size );
00099 std::copy( ublas_solution.begin(), ublas_solution.end(), solution.begin() );
00100
00101 return solution;
00102 }
00103
00104 protected:
00105 cholesky::CholeskyLLT<AtomType> _cholesky;
00106
00107 #else
00108 #ifdef WITH_EIGEN
00109
00110 public:
00111 typedef typename EOT::AtomType AtomType;
00112
00113 typedef typename D::Vector Vector;
00114 typedef typename D::Matrix Matrix;
00115
00116 edoSamplerNormalMulti( edoRepairer<EOT> & repairer )
00117 : edoSampler< D >( repairer)
00118 {}
00119
00120
00121 EOT sample( D& distrib )
00122 {
00123 unsigned int size = distrib.size();
00124 assert(size > 0);
00125
00126
00127
00128
00129 Eigen::LDLT<Matrix> cholesky( distrib.varcovar() );
00130 Matrix L = cholesky.matrixL();
00131 assert(L.innerSize() == size);
00132 assert(L.outerSize() == size);
00133
00134 Matrix mD = cholesky.vectorD().asDiagonal();
00135 assert(mD.innerSize() == size);
00136 assert(mD.outerSize() == size);
00137
00138
00139
00140
00141
00142 Matrix sqrtD = mD.cwiseSqrt();
00143 assert(sqrtD.innerSize() == size);
00144 assert(sqrtD.outerSize() == size);
00145
00146 Matrix LsD = L * sqrtD;
00147 assert(LsD.innerSize() == size);
00148 assert(LsD.outerSize() == size);
00149
00150
00151 Vector T( size );
00152 for ( unsigned int i = 0; i < size; ++i ) {
00153 T( i ) = rng.normal();
00154 }
00155 assert(T.innerSize() == size);
00156 assert(T.outerSize() == 1);
00157
00158
00159 Vector LDT = LsD * T;
00160 assert(LDT.innerSize() == size);
00161 assert(LDT.outerSize() == 1);
00162
00163
00164 Vector mean = distrib.mean();
00165 assert(mean.innerSize() == size);
00166 assert(mean.outerSize() == 1);
00167
00168 Vector typed_solution = mean + LDT;
00169 assert(typed_solution.innerSize() == size);
00170 assert(typed_solution.outerSize() == 1);
00171
00172
00173 EOT solution( size );
00174 for( unsigned int i = 0; i < mean.innerSize(); i++ ) {
00175 solution[i]= typed_solution(i);
00176 }
00177 assert( solution.size() == size );
00178
00179 return solution;
00180 }
00181 #endif // WITH_EIGEN
00182 #endif // WITH_BOOST
00183 };
00184
00185
00186 #endif // !_edoSamplerNormalMulti_h