00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef THYRA_MULTI_VECTOR_COLS_HPP
00030 #define THYRA_MULTI_VECTOR_COLS_HPP
00031
00032 #include "Thyra_MultiVectorColsDecl.hpp"
00033 #include "Thyra_MultiVectorBase.hpp"
00034 #include "Thyra_VectorSpaceFactoryBase.hpp"
00035 #include "Teuchos_TestForException.hpp"
00036
00037 namespace Thyra {
00038
00039
00040
00041 template<class Scalar>
00042 MultiVectorCols<Scalar>::MultiVectorCols()
00043 {}
00044
00045 template<class Scalar>
00046 MultiVectorCols<Scalar>::MultiVectorCols(
00047 const Teuchos::RefCountPtr<VectorBase<Scalar> > &col_vec
00048 )
00049 {
00050 this->initialize(col_vec);
00051 }
00052
00053 template<class Scalar>
00054 MultiVectorCols<Scalar>::MultiVectorCols(
00055 const Teuchos::RefCountPtr<const VectorSpaceBase<Scalar> > &range
00056 ,const Teuchos::RefCountPtr<const VectorSpaceBase<Scalar> > &domain
00057 ,const Teuchos::RefCountPtr<VectorBase<Scalar> > col_vecs[]
00058 )
00059 {
00060 this->initialize(range,domain,col_vecs);
00061 }
00062
00063 template<class Scalar>
00064 void MultiVectorCols<Scalar>::initialize(
00065 const Teuchos::RefCountPtr<VectorBase<Scalar> > &col_vec
00066 )
00067 {
00068 #ifdef _DEBUG
00069 const char err_msg[] = "MultiVectorCols<Scalar>::initialize(...): Error!";
00070 TEST_FOR_EXCEPTION( col_vec.get() == NULL, std::invalid_argument, err_msg );
00071 TEST_FOR_EXCEPTION( col_vec->space().get() == NULL, std::invalid_argument, err_msg );
00072 #endif
00073 range_ = col_vec->space();
00074 domain_ = range_->smallVecSpcFcty()->createVecSpc(1);
00075 num_cols_ = 1;
00076 col_vecs_.resize(1);
00077 col_vecs_[0] = col_vec;
00078 }
00079
00080 template<class Scalar>
00081 void MultiVectorCols<Scalar>::initialize(
00082 const Teuchos::RefCountPtr<const VectorSpaceBase<Scalar> > &range
00083 ,const Teuchos::RefCountPtr<const VectorSpaceBase<Scalar> > &domain
00084 ,const Teuchos::RefCountPtr<VectorBase<Scalar> > col_vecs[]
00085 )
00086 {
00087 #ifdef _DEBUG
00088 const char err_msg[] = "MultiVectorCols<Scalar>::initialize(...): Error!";
00089 TEST_FOR_EXCEPTION( range.get() == NULL, std::invalid_argument, err_msg );
00090 TEST_FOR_EXCEPTION( domain.get() == NULL, std::invalid_argument, err_msg );
00091 TEST_FOR_EXCEPTION( range->dim() == 0, std::invalid_argument, err_msg );
00092 TEST_FOR_EXCEPTION( domain->dim() == 0, std::invalid_argument, err_msg );
00093
00094 #endif
00095 range_ = range;
00096 domain_ = domain;
00097 num_cols_ = domain->dim();
00098 col_vecs_.resize(num_cols_);
00099 if(col_vecs) {
00100 for( Index j = 1; j <= num_cols_; ++j )
00101 col_vecs_[j-1] = col_vecs[j-1];
00102 }
00103 else {
00104 for( Index j = 1; j <= num_cols_; ++j )
00105 col_vecs_[j-1] = createMember(range_);
00106 }
00107 }
00108
00109 template<class Scalar>
00110 void MultiVectorCols<Scalar>::set_uninitialized()
00111 {
00112 col_vecs_.resize(0);
00113 range_ = Teuchos::null;
00114 domain_ = Teuchos::null;
00115 }
00116
00117
00118
00119 template<class Scalar>
00120 Teuchos::RefCountPtr<const VectorSpaceBase<Scalar> >
00121 MultiVectorCols<Scalar>::range() const
00122 {
00123 return range_;
00124 }
00125
00126 template<class Scalar>
00127 Teuchos::RefCountPtr<const VectorSpaceBase<Scalar> >
00128 MultiVectorCols<Scalar>::domain() const
00129 {
00130 return domain_;
00131 }
00132
00133
00134
00135 template<class Scalar>
00136 bool MultiVectorCols<Scalar>::opSupported(ETransp M_trans) const
00137 {
00138 typedef Teuchos::ScalarTraits<Scalar> ST;
00139 return ( ST::isComplex ? ( M_trans==NOTRANS || M_trans==CONJTRANS ) : true );
00140 }
00141
00142 template<class Scalar>
00143 void MultiVectorCols<Scalar>::apply(
00144 const ETransp M_trans
00145 ,const VectorBase<Scalar> &x
00146 ,VectorBase<Scalar> *y
00147 ,const Scalar alpha
00148 ,const Scalar beta
00149 ) const
00150 {
00151 #ifdef _DEBUG
00152 THYRA_ASSERT_LINEAR_OP_VEC_APPLY_SPACES("MultiVectorBase<Scalar>::apply()",*this,M_trans,x,y);
00153 #endif
00154 const Index nc = this->domain()->dim();
00155
00156 Vt_S(y,beta);
00157
00158 if(M_trans == NOTRANS) {
00159
00160
00161
00162
00163 RTOpPack::SubVectorT<Scalar> x_sub_vec;
00164 x.getSubVector(Range1D(),&x_sub_vec);
00165
00166 for(Index j = 1; j <= nc; ++j )
00167 Vp_StV( y, Scalar(alpha*x_sub_vec(j)), *this->col(j) );
00168
00169 x.freeSubVector(&x_sub_vec);
00170 }
00171 else {
00172
00173
00174
00175
00176
00177
00178
00179 RTOpPack::MutableSubVectorT<Scalar> y_sub_vec;
00180 y->getSubVector(Range1D(),&y_sub_vec);
00181
00182 for(Index j = 1; j <= nc; ++j )
00183 y_sub_vec(j) += alpha*dot(*this->col(j),x);
00184
00185 y->commitSubVector(&y_sub_vec);
00186 }
00187 }
00188
00189
00190
00191 template<class Scalar>
00192 Teuchos::RefCountPtr<VectorBase<Scalar> >
00193 MultiVectorCols<Scalar>::col(Index j)
00194 {
00195 TEST_FOR_EXCEPTION(
00196 !( 1 <= j && j <= num_cols_ ), std::logic_error
00197 ,"Error, j = " << j << " does not fall in the range [1,"<<num_cols_<< "]!"
00198 );
00199 return col_vecs_[j-1];
00200 }
00201
00202 template<class Scalar>
00203 Teuchos::RefCountPtr<MultiVectorBase<Scalar> >
00204 MultiVectorCols<Scalar>::subView( const Range1D& col_rng_in )
00205 {
00206 const Index cols = domain_->dim();
00207 const Range1D col_rng = RangePack::full_range(col_rng_in,1,cols);
00208 #ifdef _DEBUG
00209 TEST_FOR_EXCEPTION(
00210 !( col_rng.ubound() <= cols )
00211 ,std::logic_error
00212 ,"MultiVectorCols<Scalar>::subView(col_rng): Error, the input range col_rng = ["<<col_rng.lbound()<<","<<col_rng.ubound()<<"] "
00213 "is not in the range [1,"<<cols<<"]!"
00214 );
00215 #endif
00216 return Teuchos::rcp(
00217 new MultiVectorCols<Scalar>(
00218 range_,domain_->smallVecSpcFcty()->createVecSpc(col_rng.size()),&col_vecs_[col_rng.lbound()-1]
00219 ) );
00220 }
00221
00222 }
00223
00224 #endif // THYRA_MULTI_VECTOR_COLS_HPP