예제 #1
0
    inline void gen_matrix_copy(const MatrixSrc& src, MatrixDest& dest, bool with_reset)
    {
	MTL_THROW_IF(num_rows(src) != num_rows(dest) || num_cols(src) != num_cols(dest), incompatible_size());

	if (with_reset)
	    detail::zero_with_sparse_src(dest, typename traits::category<MatrixSrc>::type());
	
	typename traits::row<MatrixSrc>::type             row(src); 
	typename traits::col<MatrixSrc>::type             col(src); 
	typename traits::const_value<MatrixSrc>::type     value(src); 
	typedef typename traits::range_generator<tag::major, MatrixSrc>::type  cursor_type;
	
	//std::cout << "Slot size is " << detail::copy_inserter_size<Updater>::apply(src, dest) << "\n";
	matrix::inserter<MatrixDest, Updater>   ins(dest, detail::copy_inserter_size<Updater>::apply(src, dest));
	for (cursor_type cursor = begin<tag::major>(src), cend = end<tag::major>(src); 
	     cursor != cend; ++cursor) {
	    // std::cout << dest << '\n';
	    
	    typedef typename traits::range_generator<tag::nz, cursor_type>::type icursor_type;
	    for (icursor_type icursor = begin<tag::nz>(cursor), icend = end<tag::nz>(cursor); 
		 icursor != icend; ++icursor) {
		//std::cout << "in " << row(*icursor) << ", " << col(*icursor) << " insert " << value(*icursor) << '\n';
		ins(row(*icursor), col(*icursor)) << value(*icursor); }
	}
    }
예제 #2
0
    void mult(const VectorIn& v, VectorOut& w, Assign) const
    {
	MTL_DEBUG_THROW_IF(std::size_t(size(v)) != n, incompatible_size());
	MTL_DEBUG_THROW_IF(size(w) != 0 && std::size_t(size(w)) != m, incompatible_size());

	if (size(w) == 0)
	    w.change_dim(m);

	if (m == n) 
	    Assign::first_update(w, v);
	else if (m < n)
	    Assign::first_update(w, v[irange(m)]);
	else {
	    VectorOut w1(w[irange(n)]), w2(w[irange(n, imax)]);
	    Assign::first_update(w1, v);
	    Assign::init(w2);
	}
    }
예제 #3
0
    void mult(const VectorIn& v, VectorOut& w, Assign) const
    {
	MTL_DEBUG_THROW_IF(int(size(v)) != s, incompatible_size());
	MTL_DEBUG_THROW_IF(size(v) != size(w), incompatible_size());

	const int nb = n < 3 ? 1 : (n - 2) / 4 * 4 + 1;

	// Inner domain
	for (int i= 1; i < m-1; i++) {
	    int kmax= i * n + nb;
	    for (int k= i * n + 1; k < kmax; k+= 4) {
		typename Collection<VectorIn>::value_type const v0= v[k], v1= v[k+1], v2= v[k+2], v3= v[k+3];
		Assign::apply(w[k], 4 * v0 - v[k-n] - v[k+n] - v[k-1] - v1); 
		Assign::apply(w[k+1], 4 * v1 - v[k-n+1] - v[k+n+1] - v0 - v2); 
		Assign::apply(w[k+2], 4 * v2 - v[k-n+2] - v[k+n+2] - v1 - v3); 
		Assign::apply(w[k+3], 4 * v3 - v[k-n+3] - v[k+n+3] - v2 - v[k+4]); 
	    }
	    for (int j= nb, k= i * n + j; j < n-1; j++, k++) 
		Assign::apply(w[k], 4 * v[k] - v[k-n] - v[k+n] - v[k-1] - v[k+1]); 
	}
	    
	// Upper border
	for (int j= 1; j < n-1; j++) 
	    Assign::apply(w[j], 4 * v[j] - v[j+n] - v[j-1] - v[j+1]);

	// Lower border
	for (int j= 1, k= (m-1) * n + j; j < n-1; j++, k++) 
	    Assign::apply(w[k], 4 * v[k] - v[k-n] - v[k-1] - v[k+1]); 
	
	// Left border
	for (int i= 1, k= n; i < m-1; i++, k+= n)
	    Assign::apply(w[k], 4 * v[k] - v[k-n] - v[k+n] - v[k+1]); 

	// Right border
	for (int i= 1, k= n+n-1; i < m-1; i++, k+= n)
	    Assign::apply(w[k], 4 * v[k] - v[k-n] - v[k+n] - v[k-1]); 

	// Corners
	Assign::apply(w[0], 4 * v[0] - v[1] - v[n]);
	Assign::apply(w[n-1], 4 * v[n-1] - v[n-2] - v[2*n - 1]);
	Assign::apply(w[(m-1)*n], 4 * v[(m-1)*n] - v[(m-2)*n] - v[(m-1)*n+1]);
	Assign::apply(w[m*n-1], 4 * v[m*n-1] - v[m*n-2] - v[m*n-n-1]);
    }
예제 #4
0
inline void merge_complex_vector(const VectorReal& r, const VectorImaginary& i, VectorComplex& c)
{
    vampir_trace<2014> tracer;
    typedef typename Collection<VectorComplex>::value_type value_type;

    MTL_THROW_IF(size(r) != size(i), incompatible_size());
    c.checked_change_dim(size(r));

    for (std::size_t j= 0; j < size(r); ++j)
	c[j]= value_type(r[j], i[j]);
}
예제 #5
0
    void forward_eval_loop(const TT& const_first_eval, const UU& const_second_eval, boost::mpl::false_)
    {	
	vampir_trace<6001> tracer;
	// hope there is a more elegant way; copying the arguments causes errors due to double destructor evaluation
	TT& first_eval= const_cast<TT&>(const_first_eval);  
	UU& second_eval= const_cast<UU&>(const_second_eval);
	MTL_DEBUG_THROW_IF(mtl::size(first_eval) != mtl::size(second_eval), incompatible_size());	

	for (std::size_t i= 0, s= size(first_eval); i < s; i++) {
	    first_eval(i); second_eval(i);
	}	
    }
예제 #6
0
inline typename make_sparse_trait<SizeVector1, ValueVector>::type
make_sparse(const SizeVector1& rows, const SizeVector2& cols, const ValueVector& values,
	    std::size_t m, std::size_t n)
{
    MTL_THROW_IF(size(rows) != size(cols), incompatible_size());
    MTL_THROW_IF(size(rows) != size(values), incompatible_size());

    typedef make_sparse_trait<SizeVector1, ValueVector> traits;
    typedef typename traits::type       matrix_type;
    typedef typename traits::value_type value_type;
    typedef typename traits::size_type  size_type;

    size_type               ms(m), ns(n);  // shouldn't be needed :-!
    matrix_type             A(ms, ns);
    matrix::inserter<matrix_type, update_plus<value_type> > ins(A, size_type(size(rows) / m + 1));

    for (std::size_t i= 0; i < size(rows); i++)
	if (values[i] != value_type(0))
	    ins[rows[i]][cols[i]] << values[i];
    return A;
}
예제 #7
0
    void backward_eval_loop(const TT& const_first_eval, const UU& const_second_eval, boost::mpl::false_)
    {	
	vampir_trace<6003> tracer;
	// hope there is a more elegant way; copying the arguments causes errors due to double destructor evaluation
	TT& first_eval= const_cast<TT&>(const_first_eval);  
	UU& second_eval= const_cast<UU&>(const_second_eval);
	MTL_DEBUG_THROW_IF(mtl::vector::size(first_eval) != mtl::vector::size(second_eval), incompatible_size());	

	for (std::size_t i= size(first_eval); i-- > 0; ) {
	    // std::cout << "i is " << i << "\n";
	    first_eval(i); second_eval(i);
	}
    }
예제 #8
0
    inline void matrix_copy_ele_times(const MatrixSrc& src, MatrixDest& dest)
    {
	MTL_THROW_IF(num_rows(src) != num_rows(dest) || num_cols(src) != num_cols(dest), incompatible_size());

	typename traits::row<MatrixDest>::type             row(dest); 
	typename traits::col<MatrixDest>::type             col(dest); 
	typename traits::value<MatrixDest>::type           value(dest); 
	typedef typename traits::range_generator<tag::major, MatrixDest>::type  cursor_type;
	typedef typename traits::range_generator<tag::nz, cursor_type>::type icursor_type;
	
	for (cursor_type cursor = begin<tag::major>(dest), cend = end<tag::major>(dest); cursor != cend; ++cursor)
	    for (icursor_type icursor = begin<tag::nz>(cursor), icend = end<tag::nz>(cursor); icursor != icend; ++icursor)
		value(*icursor, value(*icursor) * src[row(*icursor)][col(*icursor)]);
#if 0   // copy would result in a*0 = a and 0*b = b!!!!
	gen_matrix_copy< operations::update_times<typename MatrixDest::value_type> >(src, dest, false);
#endif
	crop(dest);
    }
예제 #9
0
    void forward_eval_loop(const TT& const_first_eval, const UU& const_second_eval, boost::mpl::true_)
    {	
	vampir_trace<6002> tracer;
	// hope there is a more elegant way; copying the arguments causes errors due to double destructor evaluation
	TT& first_eval= const_cast<TT&>(const_first_eval);  
	UU& second_eval= const_cast<UU&>(const_second_eval);
	MTL_DEBUG_THROW_IF(mtl::vec::size(first_eval) != mtl::vec::size(second_eval), incompatible_size());	

	const std::size_t s= size(first_eval), sb= s >> 2 << 2;

	for (std::size_t i= 0; i < sb; i+= 4) {
	    first_eval.template at<0>(i); second_eval.template at<0>(i);
	    first_eval.template at<1>(i); second_eval.template at<1>(i);
	    first_eval.template at<2>(i); second_eval.template at<2>(i);
	    first_eval.template at<3>(i); second_eval.template at<3>(i);
	}

	for (std::size_t i= sb; i < s; i++) {
	    first_eval(i); second_eval(i);
	}
    }
예제 #10
0
    void backward_eval_loop(const TT& const_first_eval, const UU& const_second_eval, boost::mpl::true_)
    {	
	vampir_trace<6004> tracer;
	// hope there is a more elegant way; copying the arguments causes errors due to double destructor evaluation
	TT& first_eval= const_cast<TT&>(const_first_eval);  
	UU& second_eval= const_cast<UU&>(const_second_eval);
	MTL_DEBUG_THROW_IF(mtl::size(first_eval) != mtl::size(second_eval), incompatible_size());	

	std::size_t s= size(first_eval), i= s-1, m= s % 4;
	for (; m; m--) {
	    // std::cout << "i is " << i << "\n";
	    first_eval(i); second_eval(i--);
	}
	for(long j= i - 3; j >= 0; j-= 4) {
	    // std::cout << "i is " << j+3 << ".." << j << "\n";
	    first_eval.template at<3>(j); second_eval.template at<3>(j);
	    first_eval.template at<2>(j); second_eval.template at<2>(j);
	    first_eval.template at<1>(j); second_eval.template at<1>(j);
	    first_eval.template at<0>(j); second_eval.template at<0>(j);
	}
    }
예제 #11
0
    inline void gen_vector_copy(const VectorSrc& src, VectorDest& dest, bool with_reset)
    {
	// Works only with dense vectors as dest !!!!! (source could be sparse)
	// Needs vector inserter

	BOOST_STATIC_ASSERT((boost::is_same<typename ashape::ashape<VectorSrc>::type,
 			                    typename ashape::ashape<VectorDest>::type>::value));

	MTL_THROW_IF(size(src) != size(dest), incompatible_size());

	if (with_reset)
	    detail::zero_with_sparse_src(dest, typename traits::category<VectorSrc>::type());
	
	typename traits::index<VectorSrc>::type           index(src); 
	typename traits::const_value<VectorSrc>::type     value(src); 

	typedef typename traits::range_generator<tag::nz, VectorSrc>::type  cursor_type;
	for (cursor_type cursor = begin<tag::nz>(src), cend = end<tag::nz>(src); 
	     cursor != cend; ++cursor)
	    Updater()(dest[index(*cursor)], value(*cursor));
    }
    // Either changed matrix is uninitialized (i.e. 0x0) or dimensions are equal
    void check_dim(size_type num_rows, size_type num_cols) const
    {
	MTL_DEBUG_THROW_IF(this->num_rows() * this->num_cols() != 0
			   && (this->num_rows() != num_rows || this->num_cols() != num_cols),
			   incompatible_size());
    }