47 #ifndef ANASAZI_THYRA_ADAPTER_HPP
48 #define ANASAZI_THYRA_ADAPTER_HPP
54 #include <Thyra_DetachedMultiVectorView.hpp>
55 #include <Thyra_MultiVectorBase.hpp>
56 #include <Thyra_MultiVectorStdOps.hpp>
57 #include <Thyra_VectorStdOps.hpp>
59 #include <Teuchos_Ptr.hpp>
60 #include <Teuchos_ArrayRCP.hpp>
61 #include <Teuchos_ArrayView.hpp>
79 template<
class ScalarType>
83 typedef Thyra::MultiVectorBase<ScalarType> TMVB;
84 typedef Teuchos::ScalarTraits<ScalarType> ST;
85 typedef typename ST::magnitudeType magType;
96 static Teuchos::RCP<TMVB>
Clone(
const TMVB & mv,
const int numvecs )
98 Teuchos::RCP<TMVB> c = Thyra::createMembers( mv.range(), numvecs );
106 static Teuchos::RCP<TMVB>
109 const int numvecs = mv.domain()->dim();
111 Teuchos::RCP< TMVB > cc = Thyra::createMembers (mv.range(), numvecs);
113 Thyra::assign (Teuchos::outArg (*cc), mv);
122 static Teuchos::RCP< TMVB >
CloneCopy(
const TMVB & mv,
const std::vector<int>& index )
124 const int numvecs = index.size();
126 Teuchos::RCP<TMVB > cc = Thyra::createMembers (mv.range(), numvecs);
128 Teuchos::RCP<const TMVB > view = mv.subView ( Teuchos::arrayViewFromVector( index ) );
130 Thyra::assign (Teuchos::outArg (*cc), *view);
134 static Teuchos::RCP<TMVB>
135 CloneCopy (
const TMVB& mv,
const Teuchos::Range1D& index)
137 const int numVecs = index.size();
139 Teuchos::RCP<TMVB> cc = Thyra::createMembers (mv.range(), numVecs);
141 Teuchos::RCP<const TMVB> view = mv.subView (index);
143 Thyra::assign (Teuchos::outArg (*cc), *view);
154 int numvecs = index.size();
170 for (
int i=0; i<numvecs; i++) {
171 if (lb+i != index[i]) contig =
false;
174 Teuchos::RCP< TMVB > cc;
176 const Thyra::Range1D rng(lb,lb+numvecs-1);
178 cc = mv.subView(rng);
182 cc = mv.subView( Teuchos::arrayViewFromVector( index ) );
187 static Teuchos::RCP<TMVB>
195 return mv.subView (index);
203 static Teuchos::RCP<const TMVB >
CloneView(
const TMVB & mv,
const std::vector<int>& index )
205 int numvecs = index.size();
221 for (
int i=0; i<numvecs; i++) {
222 if (lb+i != index[i]) contig =
false;
225 Teuchos::RCP< const TMVB > cc;
227 const Thyra::Range1D rng(lb,lb+numvecs-1);
229 cc = mv.subView(rng);
233 cc = mv.subView(Teuchos::arrayViewFromVector( index ) );
238 static Teuchos::RCP<const TMVB>
239 CloneView (
const TMVB& mv,
const Teuchos::Range1D& index)
246 return mv.subView (index);
256 {
return mv.range()->dim(); }
260 {
return mv.domain()->dim(); }
270 const Teuchos::SerialDenseMatrix<int,ScalarType>& B,
271 const ScalarType beta, TMVB & mv )
276 Teuchos::RCP< const TMVB >
277 B_thyra = Thyra::createMembersView(
279 RTOpPack::ConstSubMultiVectorView<ScalarType>(
281 Teuchos::arcpFromArrayView(Teuchos::arrayView(&B(0,0), B.stride()*B.numCols())), B.stride()
285 A.apply(Thyra::NOTRANS,*B_thyra,Teuchos::outArg (mv),alpha,beta);
290 static void MvAddMv(
const ScalarType alpha,
const TMVB & A,
291 const ScalarType beta,
const TMVB & B, TMVB & mv )
293 using Teuchos::tuple;
using Teuchos::ptrInArg;
using Teuchos::inoutArg;
295 Thyra::linear_combination<ScalarType>(
296 tuple(alpha, beta)(), tuple(ptrInArg(A), ptrInArg(B))(), ST::zero(), inoutArg(mv));
301 static void MvTransMv(
const ScalarType alpha,
const TMVB & A,
const TMVB & mv,
302 Teuchos::SerialDenseMatrix<int,ScalarType>& B )
305 int m = A.domain()->dim();
306 int n = mv.domain()->dim();
309 B_thyra = Thyra::createMembersView(
311 RTOpPack::SubMultiVectorView<ScalarType>(
313 Teuchos::arcpFromArrayView(Teuchos::arrayView(&B(0,0), B.stride()*B.numCols())), B.stride()
316 A.apply(Thyra::CONJTRANS,mv,B_thyra.ptr(),alpha,Teuchos::ScalarTraits<ScalarType>::zero());
322 static void MvDot(
const TMVB & mv,
const TMVB & A, std::vector<ScalarType> &b )
323 { Thyra::dots(mv,A,Teuchos::arrayViewFromVector( b )); }
329 const ScalarType alpha)
331 Thyra::scale (alpha, Teuchos::inOutArg (mv));
338 const std::vector<ScalarType>& alpha)
340 for (
unsigned int i=0; i<alpha.size(); i++) {
341 Thyra::scale (alpha[i], mv.col(i).ptr());
353 static void MvNorm(
const TMVB & mv, std::vector<
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &normvec )
354 { Thyra::norms_2(mv,Teuchos::arrayViewFromVector( normvec )); }
363 static void SetBlock(
const TMVB & A,
const std::vector<int>& index, TMVB & mv )
366 int numvecs = index.size();
367 std::vector<int> indexA(numvecs);
368 int numAcols = A.domain()->dim();
369 for (
int i=0; i<numvecs; i++) {
374 if ( numAcols < numvecs ) {
379 else if ( numAcols > numvecs ) {
381 indexA.resize( numAcols );
384 Teuchos::RCP< const TMVB > relsource = A.subView( Teuchos::arrayViewFromVector( indexA ) );
386 Teuchos::RCP< TMVB > reldest = mv.subView( Teuchos::arrayViewFromVector( index ) );
388 Thyra::assign (Teuchos::outArg (*reldest), *relsource);
392 SetBlock (
const TMVB& A,
const Teuchos::Range1D& index, TMVB& mv)
394 const int numColsA = A.domain()->dim();
395 const int numColsMv = mv.domain()->dim();
397 const bool validIndex = index.lbound() >= 0 && index.ubound() < numColsMv;
399 const bool validSource = index.size() <= numColsA;
401 if (! validIndex || ! validSource)
403 std::ostringstream os;
404 os <<
"Anasazi::MultiVecTraits<Scalar, Thyra::MultiVectorBase<Scalar> "
405 ">::SetBlock(A, [" << index.lbound() <<
", " << index.ubound()
407 TEUCHOS_TEST_FOR_EXCEPTION(index.lbound() < 0, std::invalid_argument,
408 os.str() <<
"Range lower bound must be nonnegative.");
409 TEUCHOS_TEST_FOR_EXCEPTION(index.ubound() >= numColsMv, std::invalid_argument,
410 os.str() <<
"Range upper bound must be less than "
411 "the number of columns " << numColsA <<
" in the "
412 "'mv' output argument.");
413 TEUCHOS_TEST_FOR_EXCEPTION(index.size() > numColsA, std::invalid_argument,
414 os.str() <<
"Range must have no more elements than"
415 " the number of columns " << numColsA <<
" in the "
416 "'A' input argument.");
417 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Should never get here!");
423 Teuchos::RCP<TMVB> mv_view;
424 if (index.lbound() == 0 && index.ubound()+1 == numColsMv)
425 mv_view = Teuchos::rcpFromRef (mv);
427 mv_view = mv.subView (index);
432 Teuchos::RCP<const TMVB> A_view;
433 if (index.size() == numColsA)
434 A_view = Teuchos::rcpFromRef (A);
436 A_view = A.subView (Teuchos::Range1D(0, index.size()-1));
439 Thyra::assign (Teuchos::outArg (*mv_view), *A_view);
443 Assign (
const TMVB& A, TMVB& mv)
446 using Teuchos::Range1D;
449 const int numColsA = A.domain()->dim();
450 const int numColsMv = mv.domain()->dim();
451 if (numColsA > numColsMv) {
452 const std::string prefix (
"Anasazi::MultiVecTraits<Scalar, "
453 "Thyra::MultiVectorBase<Scalar>"
454 " >::Assign(A, mv): ");
455 TEUCHOS_TEST_FOR_EXCEPTION(numColsA > numColsMv, std::invalid_argument,
456 prefix <<
"Input multivector 'A' has "
457 << numColsA <<
" columns, but output multivector "
458 "'mv' has only " << numColsMv <<
" columns.");
459 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Should never get here!");
462 if (numColsA == numColsMv) {
463 Thyra::assign (outArg (mv), A);
467 Thyra::assign (outArg (*mv_view), A);
477 Thyra::randomize(-Teuchos::ScalarTraits<ScalarType>::one(),
478 Teuchos::ScalarTraits<ScalarType>::one(),
479 Teuchos::outArg (mv));
486 ScalarType alpha = Teuchos::ScalarTraits<ScalarType>::zero())
488 Thyra::assign (Teuchos::outArg (mv), alpha);
498 static void MvPrint(
const TMVB & mv, std::ostream& os )
500 Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::getFancyOStream(Teuchos::rcp(&os,
false));
501 out->setf(std::ios_base::scientific);
503 mv.describe(*out,Teuchos::VERB_EXTREME);
526 template <
class ScalarType>
527 class OperatorTraits < ScalarType, Thyra::MultiVectorBase<ScalarType>, Thyra::LinearOpBase<ScalarType> >
534 static void Apply (
const Thyra::LinearOpBase< ScalarType >& Op,
const Thyra::MultiVectorBase< ScalarType > & x, Thyra::MultiVectorBase< ScalarType > & y )
536 Op.apply(Thyra::NOTRANS,x,Teuchos::outArg (y), Teuchos::ScalarTraits<ScalarType>::one(),Teuchos::ScalarTraits<ScalarType>::zero());