예제 #1
0
    /// Constructor takes matrix reference
    explicit diagonal(const Matrix& A) : inv_diag(num_rows(A))
    {
	mtl::vampir_trace<5050> tracer;
	MTL_THROW_IF(num_rows(A) != num_cols(A), mtl::matrix_not_square());
	using math::reciprocal;

	for (size_type i= 0; i < num_rows(A); ++i)
	    inv_diag[i]= reciprocal(A[i][i]);
    }
예제 #2
0
    // Undefined if matrix is not symmetric 
    void factorize(const Matrix& A, mtl::tag::sparse)
    {
        using namespace mtl; using namespace mtl::tag;  using mtl::traits::range_generator;  
	using math::reciprocal; using mtl::matrix::upper;

        typedef typename range_generator<row, U_type>::type       cur_type;    
        typedef typename range_generator<nz, cur_type>::type      icur_type;            

	MTL_THROW_IF(num_rows(A) != num_cols(A), mtl::matrix_not_square());
	U= upper(A); crop(U);
	U_type L(lower(A)); // needed to find non-zeros in column

        typename mtl::traits::col<U_type>::type                   col(U), col_l(L);
        typename mtl::traits::value<U_type>::type                 value(U); 


	cur_type kc= begin<row>(U), kend= end<row>(U);
	for (size_type k= 0; kc != kend; ++kc, ++k) {

	    icur_type ic= begin<nz>(kc), iend= end<nz>(kc);
	    MTL_DEBUG_THROW_IF(col(*ic) != k, mtl::missing_diagonal());

	    // U[k][k]= 1.0 / sqrt(U[k][k]);
	    value_type inv_dia= reciprocal(sqrt(value(*ic)));
	    value(*ic, inv_dia);
	    icur_type jbegin= ++ic;
	    for (; ic != iend; ++ic) {
		// U[k][i] *= U[k][k]
		value_type d= value(*ic) * inv_dia;
		value(*ic, d);
		size_type i= col(*ic);

		// find non-zeros U[j][i] below U[k][i] for j in (k, i]
		// 1. Go to ith row in L (== ith column in U)
		cur_type irow= begin<row>(L); irow+= i;
		// 2. Find nonzeros with col() in (k, i]
		icur_type jc= begin<nz>(irow), jend= end<nz>(irow);
		while (col_l(*jc) <= k) ++jc;
		while (col_l(*--jend) > i);
		++jend; 
		
		for (; jc != jend; ++jc) {
		    size_type j= col_l(*jc);
		    U.lvalue(j, i)-= d * U[k][j];
		}
		// std::cout << "U after eliminating U[" << i << "][" << k << "] =\n" << U;
	    }
	}
    }
예제 #3
0
    void factorize(const Matrix& A, L_type& L, U_type& U, boost::mpl::true_)
    {
	using namespace mtl; using namespace mtl::tag;  using mtl::traits::range_generator;  
	using math::reciprocal; 
	MTL_THROW_IF(num_rows(A) != num_cols(A), mtl::matrix_not_square());
	mtl::vampir_trace<5038> tracer;

	typedef typename mtl::Collection<Matrix>::value_type      value_type;
	typedef typename mtl::Collection<Matrix>::size_type       size_type;
	typedef mtl::mat::parameters<mtl::row_major, mtl::index::c_index, mtl::non_fixed::dimensions, false, size_type> para;
	typedef mtl::mat::compressed2D<value_type, para>  LU_type;
	LU_type LU(A);

	typedef typename range_generator<row, LU_type>::type      cur_type;    
	typedef typename range_generator<nz, cur_type>::type      icur_type;            
	typename mtl::traits::col<LU_type>::type                  col(LU);
	typename mtl::traits::value<LU_type>::type                value(LU); 
	mtl::vec::dense_vector<value_type, mtl::vec::parameters<> > inv_dia(num_rows(A));
	cur_type ic= begin<row>(LU), iend= end<row>(LU);
	for (size_type i= 0; ic != iend; ++ic, ++i) {

	    for (icur_type kc= begin<nz>(ic), kend= end<nz>(ic); kc != kend; ++kc) {
		size_type k= col(*kc);
		if (k == i) break;

		value_type aik= value(*kc) * inv_dia[k];
		value(*kc, aik);

		for (icur_type jc= kc + 1; jc != kend; ++jc)
		    value(*jc, value(*jc) - aik * LU[k][col(*jc)]);
		// std::cout << "LU after eliminating A[" << i << "][" << k << "] =\n" << LU;			  
	    }
	    inv_dia[i]= reciprocal(LU[i][i]);
	}
	invert_diagonal(LU); 
	L= strict_lower(LU);
	U= upper(LU);
    }