RTOpPack::SparseSubVector AbstractLinAlgPack::sub_vec_view( const SpVectorSlice& sv_in ,const Range1D& rng_in ) { using Teuchos::null; const Range1D rng = RangePack::full_range(rng_in,1,sv_in.dim()); const SpVectorSlice sv = sv_in(rng); RTOpPack::SparseSubVector sub_vec; if(!sv.nz()) { sub_vec.initialize( rng.lbound()-1 // global_offset ,rng.size() // sub_dim ,0 // nz ,null // vlaues ,1 // values_stride ,null // indices ,1 // indices_stride ,0 // local_offset ,1 // is_sorted ); } else { SpVectorSlice::const_iterator itr = sv.begin(); TEUCHOS_TEST_FOR_EXCEPT( !( itr != sv.end() ) ); if( sv.dim() && sv.nz() == sv.dim() && sv.is_sorted() ) { const Teuchos::ArrayRCP<const value_type> values = Teuchos::arcp(&itr->value(), 0, values_stride*rng.size(), false) ; sub_vec.initialize( rng.lbound()-1 // global_offset ,rng.size() // sub_dim ,values // values ,values_stride // values_stride ); } else { const Teuchos::ArrayRCP<const value_type> values = Teuchos::arcp(&itr->value(), 0, values_stride*sv.nz(), false) ; const Teuchos::ArrayRCP<const index_type> indexes = Teuchos::arcp(&itr->index(), 0, indices_stride*sv.nz(), false); sub_vec.initialize( rng.lbound()-1 // global_offset ,sv.dim() // sub_dim ,sv.nz() // sub_nz ,values // values ,values_stride // values_stride ,indexes // indices ,indices_stride // indices_stride ,sv.offset() // local_offset ,sv.is_sorted() // is_sorted ); } } return sub_vec; }
std::ostream& AbstractLinAlgPack::operator<<(std::ostream& os, const SpVectorSlice& svs) { os << std::left << std::setw(0) << svs.dim() << " " << svs.nz() << std::endl << std::right; if( !svs.dim() ) return os; const SpVectorSlice::difference_type offset = svs.offset(); for(SpVectorSlice::const_iterator itr = svs.begin(); itr != svs.end(); ++itr ) os << " " << itr->value() << ":" << (itr->index() + offset); return os << std::endl; }
void MultiVectorMutableCols::Vp_StMtV( VectorMutable* y, value_type a, BLAS_Cpp::Transp M_trans ,const SpVectorSlice& x, value_type b ) const { using AbstractLinAlgPack::dot; // y = b*y LinAlgOpPack::Vt_S(y,b); if( M_trans == BLAS_Cpp::no_trans ) { // // y += a*M*x // // => // // y += a * x(1) * M(:,1) + a * x(2) * M(:,2) + ... // SpVectorSlice::difference_type o = x.offset(); for( SpVectorSlice::const_iterator itr = x.begin(); itr != x.end(); ++itr ) { const size_type j = itr->index() + o; LinAlgOpPack::Vp_StV( y, a * itr->value(), *col_vecs_[j-1] ); } } else { // // y += a*M'*x // // => // // y(1) += a M(:,1)*x // y(2) += a M(:,2)*x // ... // for( size_type j = 1; j <= col_vecs_.size(); ++j ) y->set_ele( j ,y->get_ele(j) + a * dot(*col_vecs_[j-1],x) ); } }
void AbstractLinAlgPack::add_elements( SpVector* sv_lhs, value_type alpha, const SpVectorSlice& sv_rhs , size_type offset, bool add_zeros ) { typedef SpVector::element_type ele_t; const bool assume_sorted = ( !sv_lhs->nz() || ( sv_lhs->nz() && sv_lhs->is_sorted() ) ) && ( !sv_rhs.nz() || ( sv_rhs.nz() || sv_rhs.is_sorted() ) ); if(add_zeros) { for( SpVectorSlice::const_iterator itr = sv_rhs.begin(); itr != sv_rhs.end(); ++itr ) sv_lhs->add_element( ele_t( itr->index() + sv_rhs.offset() + offset, alpha * (itr->value()) ) ); } else { for( SpVectorSlice::const_iterator itr = sv_rhs.begin(); itr != sv_rhs.end(); ++itr ) if(itr->value() != 0.0 ) sv_lhs->add_element( ele_t( itr->index() + sv_rhs.offset() + offset, alpha * (itr->value()) ) ); } sv_lhs->assume_sorted(assume_sorted); }