void FillMatrix(boost::numeric::ublas::symmetric_matrix<_TReal> &matrix, const size_t cities, const size_t index) { matrix.resize(cities, cities); for (size_t i = 0; i < matrix.size1(); ++i) { for (size_t j = 0; j <= i; ++j) matrix(i, j) = index; } }
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; };
boost::numeric::ublas::matrix< T > pseudoinverse( const boost::numeric::ublas::symmetric_matrix< coord_t, boost::numeric::ublas::upper >& X ) { using namespace boost::numeric::ublas; std::clog << "flat::pseudoinverse" << "\t| computing ..."//<<std::endl<<V << std::endl << std::flush; // TODO regularizer. right name? triangular_matrix< T, lower > L( cholesky_decomposition< T >( X ) ); std::clog << "flat::pseudoinverse" << "\t| L" << std::endl << L << std::endl << std::flush; auto Xinverse = solve( L, solve( L, identity_matrix< T >( X.size1() ), lower_tag() ), lower_tag() ); std::clog << "flat::pseudoinverse" << "\t| complete - pseudoinverse of V " << std::endl << Xinverse << std::endl; return Xinverse; }
BOOST_UBLAS_INLINE typename ublas::symmetric_matrix<T,F1,F2,A>::pointer matrix_storage (ublas::symmetric_matrix<T,F1,F2,A> &m) { return &m.data().begin()[0]; }
BOOST_UBLAS_INLINE int matrix_storage_size (const ublas::symmetric_matrix<T,F1,F2,A> &m) { return (int) ((m.size1() * (m.size1() + 1)) / 2); }
// 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; }