void BasketProduct::setCorrelations(boost::numeric::ublas::symmetric_matrix<double, boost::numeric::ublas::lower> corr) { for(int i=0;i<corr.size1();i++) { for(int j=0;j<corr.size2();j++) { if(abs(corr(i,j))>1) { throw out_of_range("La corrélation doit être comprise entre -1 et +1"); } } } correlations = corr; }
boost::numeric::ublas::triangular_matrix< T, boost::numeric::ublas::lower > cholesky_decomposition( const boost::numeric::ublas::symmetric_matrix< T, boost::numeric::ublas::upper >& A) { std::clog<<"flat::cholesky_decomposition"<<std::endl<<std::flush; assert(A.size1()==A.size2()); //Cholesky Decomposition //Numerical Recipes in C++ (Second Edition), page 100 std::vector< T > d( A.size1() ); T sum; boost::numeric::ublas::triangular_matrix< T, boost::numeric::ublas::lower > L( A.size1(), A.size2() ); for( size_t i = 0; i < A.size1(); i++ ) { for( size_t j = 0; j < i; j++ ) { sum = A(i,j); for(size_t k = 0; k < j; ++k) sum -= L(i,k)*L(j,k); L(i,j) = sum / L(j,j); } sum = A(i,i); for(size_t k = 0; k < i; ++k) sum -= L(i,k) * L(i,k); assert( sum > 0 ); L(i,i) = std::sqrt( sum ); } /*for( size_t i = 0; i < A.size1(); i++ ) for( size_t j = i; j < A.size1(); j++ ) { sum = A(i,j); for( int k = int(i)-1; k >= 0; k-- ) sum -= A(i,k) * A(j,k); if( i == j ) { std::cerr << "choleski sum " << sum << std::endl; assert( sum > 0 ); // is A really positive definite? d[i] = std::sqrt( sum ); } else L(j,i) = sum / d[i]; } for( size_t i = 0; i < A.size1(); ++i ) L(i,i) = d[i]; */ std::clog<<"flat::cholesky_decomposition\t|complete"<<std::endl<<std::flush; return L; };
// Ideally, this template should handle a non-square symmetric_matrix // using upper and lower. template <typename T> inline T norm_max(ublas::symmetric_matrix<T>& M) { size_t n1 = M.size1(); size_t n2 = M.size2(); T m = 0; for (size_t i=0; i<n1; i++) for (size_t j=i; j<n2; j++) m = max(M(i,j),m); return m; }