86 typedef Tpetra::MultiVector<Scalar, LO, GO, Node> MV;
93 static Teuchos::RCP<MV>
Clone (
const MV& X,
const int numVecs) {
94 Teuchos::RCP<MV> Y (
new MV (X.getMap (), numVecs,
false));
95 Y->setCopyOrView (Teuchos::View);
105 Teuchos::RCP<MV> X_copy (
new MV (X, Teuchos::Copy));
112 X_copy->setCopyOrView (Teuchos::View);
127 static Teuchos::RCP<MV>
130#ifdef HAVE_TPETRA_DEBUG
131 const char fnName[] =
"Anasazi::MultiVecTraits::CloneCopy(mv,index)";
132 const size_t inNumVecs = mv.getNumVectors ();
133 TEUCHOS_TEST_FOR_EXCEPTION(
134 index.size () > 0 && *std::min_element (index.begin (), index.end ()) < 0,
135 std::runtime_error, fnName <<
": All indices must be nonnegative.");
136 TEUCHOS_TEST_FOR_EXCEPTION(
138 static_cast<size_t> (*std::max_element (index.begin (), index.end ())) >= inNumVecs,
140 fnName <<
": All indices must be strictly less than the number of "
141 "columns " << inNumVecs <<
" of the input multivector mv.");
145 Teuchos::Array<size_t> columns (index.size ());
146 for (std::vector<int>::size_type j = 0; j < index.size (); ++j) {
147 columns[j] = index[j];
152 Teuchos::RCP<MV> X_copy = mv.subCopy (columns ());
153 X_copy->setCopyOrView (Teuchos::View);
163 static Teuchos::RCP<MV>
166 const bool validRange = index.size() > 0 &&
167 index.lbound() >= 0 &&
170 std::ostringstream os;
171 os <<
"Anasazi::MultiVecTraits::CloneCopy(mv,index=["
172 << index.lbound() <<
"," << index.ubound() <<
"]): ";
173 TEUCHOS_TEST_FOR_EXCEPTION(
174 index.size() == 0, std::invalid_argument,
175 os.str() <<
"Empty index range is not allowed.");
176 TEUCHOS_TEST_FOR_EXCEPTION(
177 index.lbound() < 0, std::invalid_argument,
178 os.str() <<
"Index range includes negative index/ices, which is not "
180 TEUCHOS_TEST_FOR_EXCEPTION(
182 os.str() <<
"Index range exceeds number of vectors "
183 << mv.getNumVectors() <<
" in the input multivector.");
184 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
185 os.str() <<
"Should never get here!");
187 Teuchos::RCP<MV> X_copy = mv.subCopy (index);
188 X_copy->setCopyOrView (Teuchos::View);
192 static Teuchos::RCP<MV>
195#ifdef HAVE_TPETRA_DEBUG
196 const char fnName[] =
"Anasazi::MultiVecTraits::CloneViewNonConst(mv,index)";
197 const size_t numVecs = mv.getNumVectors ();
198 TEUCHOS_TEST_FOR_EXCEPTION(
199 index.size () > 0 && *std::min_element (index.begin (), index.end ()) < 0,
200 std::invalid_argument,
201 fnName <<
": All indices must be nonnegative.");
202 TEUCHOS_TEST_FOR_EXCEPTION(
204 static_cast<size_t> (*std::max_element (index.begin (), index.end ())) >= numVecs,
205 std::invalid_argument,
206 fnName <<
": All indices must be strictly less than the number of "
207 "columns " << numVecs <<
" in the input MultiVector mv.");
211 Teuchos::Array<size_t> columns (index.size ());
212 for (std::vector<int>::size_type j = 0; j < index.size (); ++j) {
213 columns[j] = index[j];
218 Teuchos::RCP<MV> X_view = mv.subViewNonConst (columns ());
219 X_view->setCopyOrView (Teuchos::View);
223 static Teuchos::RCP<MV>
229 const int numCols =
static_cast<int> (mv.getNumVectors());
230 const bool validRange = index.size() > 0 &&
231 index.lbound() >= 0 && index.ubound() < numCols;
233 std::ostringstream os;
234 os <<
"Belos::MultiVecTraits::CloneViewNonConst(mv,index=["
235 << index.lbound() <<
", " << index.ubound() <<
"]): ";
236 TEUCHOS_TEST_FOR_EXCEPTION(
237 index.size() == 0, std::invalid_argument,
238 os.str() <<
"Empty index range is not allowed.");
239 TEUCHOS_TEST_FOR_EXCEPTION(
240 index.lbound() < 0, std::invalid_argument,
241 os.str() <<
"Index range includes negative inde{x,ices}, which is "
243 TEUCHOS_TEST_FOR_EXCEPTION(
244 index.ubound() >= numCols, std::invalid_argument,
245 os.str() <<
"Index range exceeds number of vectors " << numCols
246 <<
" in the input multivector.");
247 TEUCHOS_TEST_FOR_EXCEPTION(
248 true, std::logic_error,
249 os.str() <<
"Should never get here!");
251 Teuchos::RCP<MV> X_view = mv.subViewNonConst (index);
252 X_view->setCopyOrView (Teuchos::View);
256 static Teuchos::RCP<const MV>
257 CloneView (
const MV& mv,
const std::vector<int>& index)
259#ifdef HAVE_TPETRA_DEBUG
260 const char fnName[] =
"Belos::MultiVecTraits<Scalar, "
261 "Tpetra::MultiVector<...> >::CloneView(mv,index)";
262 const size_t numVecs = mv.getNumVectors ();
263 TEUCHOS_TEST_FOR_EXCEPTION(
264 *std::min_element (index.begin (), index.end ()) < 0,
265 std::invalid_argument,
266 fnName <<
": All indices must be nonnegative.");
267 TEUCHOS_TEST_FOR_EXCEPTION(
268 static_cast<size_t> (*std::max_element (index.begin (), index.end ())) >= numVecs,
269 std::invalid_argument,
270 fnName <<
": All indices must be strictly less than the number of "
271 "columns " << numVecs <<
" in the input MultiVector mv.");
275 Teuchos::Array<size_t> columns (index.size ());
276 for (std::vector<int>::size_type j = 0; j < index.size (); ++j) {
277 columns[j] = index[j];
282 Teuchos::RCP<const MV> X_view = mv.subView (columns);
283 Teuchos::rcp_const_cast<MV> (X_view)->setCopyOrView (Teuchos::View);
287 static Teuchos::RCP<const MV>
288 CloneView (
const MV& mv,
const Teuchos::Range1D& index)
293 const int numCols =
static_cast<int> (mv.getNumVectors());
294 const bool validRange = index.size() > 0 &&
295 index.lbound() >= 0 && index.ubound() < numCols;
297 std::ostringstream os;
298 os <<
"Anasazi::MultiVecTraits::CloneView(mv, index=["
299 << index.lbound () <<
", " << index.ubound() <<
"]): ";
300 TEUCHOS_TEST_FOR_EXCEPTION(index.size() == 0, std::invalid_argument,
301 os.str() <<
"Empty index range is not allowed.");
302 TEUCHOS_TEST_FOR_EXCEPTION(index.lbound() < 0, std::invalid_argument,
303 os.str() <<
"Index range includes negative index/ices, which is not "
305 TEUCHOS_TEST_FOR_EXCEPTION(
306 index.ubound() >= numCols, std::invalid_argument,
307 os.str() <<
"Index range exceeds number of vectors " << numCols
308 <<
" in the input multivector.");
309 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
310 os.str() <<
"Should never get here!");
312 Teuchos::RCP<const MV> X_view = mv.subView (index);
313 Teuchos::rcp_const_cast<MV> (X_view)->setCopyOrView (Teuchos::View);
318 return static_cast<ptrdiff_t
> (mv.getGlobalLength ());
322 return static_cast<int> (mv.getNumVectors ());
328 const Teuchos::SerialDenseMatrix<int, Scalar>& B,
332 using Teuchos::ArrayView;
334 using Teuchos::rcpFromRef;
335 typedef Tpetra::Map<LO, GO, Node> map_type;
337#ifdef HAVE_ANASAZI_TPETRA_TIMERS
338 const std::string timerName (
"Anasazi::MVT::MvTimesMatAddMv");
339 Teuchos::RCP<Teuchos::Time> timer =
340 Teuchos::TimeMonitor::lookupCounter (timerName);
341 if (timer.is_null ()) {
342 timer = Teuchos::TimeMonitor::getNewCounter (timerName);
344 TEUCHOS_TEST_FOR_EXCEPTION(
345 timer.is_null (), std::logic_error,
346 "Anasazi::MultiVecTraits::MvTimesMatAddMv: "
347 "Failed to look up timer \"" << timerName <<
"\". "
348 "Please report this bug to the Belos developers.");
351 Teuchos::TimeMonitor timeMon (*timer);
355 if (B.numRows () == 1 && B.numCols () == 1) {
356 mv.update (alpha*B(0,0), A, beta);
361 Teuchos::SerialComm<int> serialComm;
362 map_type LocalMap (B.numRows (), A.getMap ()->getIndexBase (),
363 rcpFromRef<
const Comm<int> > (serialComm),
364 Tpetra::LocallyReplicated);
366 ArrayView<const Scalar> Bvalues (B.values (), B.stride () * B.numCols ());
368 MV B_mv (rcpFromRef (LocalMap), Bvalues, B.stride (), B.numCols ());
369 mv.multiply (Teuchos::NO_TRANS, Teuchos::NO_TRANS, alpha, A, B_mv, beta);
386 mv.update (alpha, A, beta, B, Teuchos::ScalarTraits<Scalar>::zero ());
389 static void MvScale (MV& mv, Scalar alpha) {
393 static void MvScale (MV& mv,
const std::vector<Scalar>& alphas) {
401 Teuchos::SerialDenseMatrix<int,Scalar>& C)
403 using Tpetra::LocallyReplicated;
407 using Teuchos::TimeMonitor;
408 typedef Tpetra::Map<LO,GO,Node> map_type;
410#ifdef HAVE_ANASAZI_TPETRA_TIMERS
411 const std::string timerName (
"Anasazi::MVT::MvTransMv");
412 RCP<Teuchos::Time> timer = TimeMonitor::lookupCounter (timerName);
413 if (timer.is_null ()) {
414 timer = TimeMonitor::getNewCounter (timerName);
416 TEUCHOS_TEST_FOR_EXCEPTION(
417 timer.is_null (), std::logic_error,
"Anasazi::MvTransMv: "
418 "Failed to look up timer \"" << timerName <<
"\". "
419 "Please report this bug to the Belos developers.");
422 TimeMonitor timeMon (*timer);
433 const int numRowsC = C.numRows ();
434 const int numColsC = C.numCols ();
435 const int strideC = C.stride ();
438 if (numRowsC == 1 && numColsC == 1) {
439 if (alpha == Teuchos::ScalarTraits<Scalar>::zero ()) {
444 A.dot (B, Teuchos::ArrayView<Scalar> (C.values (), 1));
445 if (alpha != Teuchos::ScalarTraits<Scalar>::one ()) {
452 RCP<const Comm<int> > pcomm = A.getMap ()->getComm ();
455 RCP<const map_type> LocalMap =
456 rcp (
new map_type (numRowsC, 0, pcomm, LocallyReplicated));
458 const bool INIT_TO_ZERO =
true;
459 MV C_mv (LocalMap, numColsC, INIT_TO_ZERO);
462 C_mv.multiply (Teuchos::CONJ_TRANS, Teuchos::NO_TRANS, alpha, A, B,
463 Teuchos::ScalarTraits<Scalar>::zero ());
466 Teuchos::ArrayView<Scalar> C_view (C.values (), strideC * numColsC);
471 C_mv.get1dCopy (C_view, strideC);
476 MvDot (
const MV& A,
const MV& B, std::vector<Scalar> &dots)
478 const size_t numVecs = A.getNumVectors ();
479 TEUCHOS_TEST_FOR_EXCEPTION(
480 numVecs != B.getNumVectors (), std::invalid_argument,
481 "Anasazi::MultiVecTraits::MvDot(A,B,dots): "
482 "A and B must have the same number of columns. "
483 "A has " << numVecs <<
" column(s), "
484 "but B has " << B.getNumVectors () <<
" column(s).");
485#ifdef HAVE_TPETRA_DEBUG
486 TEUCHOS_TEST_FOR_EXCEPTION(
487 dots.size() < numVecs, std::invalid_argument,
488 "Anasazi::MultiVecTraits::MvDot(A,B,dots): "
489 "The output array 'dots' must have room for all dot products. "
490 "A and B each have " << numVecs <<
" column(s), "
491 "but 'dots' only has " << dots.size() <<
" entry(/ies).");
494 Teuchos::ArrayView<Scalar> av (dots);
495 A.dot (B, av (0, numVecs));
501 std::vector<
typename Teuchos::ScalarTraits<Scalar>::magnitudeType> &normvec)
503 typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType magnitude_type;
504#ifdef HAVE_TPETRA_DEBUG
505 TEUCHOS_TEST_FOR_EXCEPTION(
506 normvec.size () <
static_cast<std::vector<int>::size_type
> (mv.getNumVectors ()),
507 std::invalid_argument,
508 "Anasazi::MultiVecTraits::MvNorm(mv,normvec): The normvec output "
509 "argument must have at least as many entries as the number of vectors "
510 "(columns) in the MultiVector mv. normvec.size() = " << normvec.size ()
511 <<
" < mv.getNumVectors() = " << mv.getNumVectors () <<
".");
513 Teuchos::ArrayView<magnitude_type> av (normvec);
514 mv.norm2 (av (0, mv.getNumVectors ()));
518 SetBlock (
const MV& A,
const std::vector<int>& index, MV& mv)
520 using Teuchos::Range1D;
522 const size_t inNumVecs = A.getNumVectors ();
523#ifdef HAVE_TPETRA_DEBUG
524 TEUCHOS_TEST_FOR_EXCEPTION(
525 inNumVecs <
static_cast<size_t> (index.size ()), std::invalid_argument,
526 "Anasazi::MultiVecTraits::SetBlock(A,index,mv): 'index' argument must "
527 "have no more entries as the number of columns in the input MultiVector"
528 " A. A.getNumVectors() = " << inNumVecs <<
" < index.size () = "
529 << index.size () <<
".");
532 if (inNumVecs >
static_cast<size_t> (index.size ())) {
533 RCP<const MV> Asub = A.subView (Range1D (0, index.size () - 1));
534 Tpetra::deep_copy (*mvsub, *Asub);
536 Tpetra::deep_copy (*mvsub, A);
541 SetBlock (
const MV& A,
const Teuchos::Range1D& index, MV& mv)
550 const size_t maxInt =
551 static_cast<size_t> (Teuchos::OrdinalTraits<int>::max ());
552 const bool overflow =
553 maxInt < A.getNumVectors () && maxInt < mv.getNumVectors ();
555 std::ostringstream os;
556 os <<
"Anasazi::MultiVecTraits::SetBlock(A, index=[" << index.lbound ()
557 <<
", " << index.ubound () <<
"], mv): ";
558 TEUCHOS_TEST_FOR_EXCEPTION(
559 maxInt < A.getNumVectors (), std::range_error, os.str () <<
"Number "
560 "of columns (size_t) in the input MultiVector 'A' overflows int.");
561 TEUCHOS_TEST_FOR_EXCEPTION(
562 maxInt < mv.getNumVectors (), std::range_error, os.str () <<
"Number "
563 "of columns (size_t) in the output MultiVector 'mv' overflows int.");
566 const int numColsA =
static_cast<int> (A.getNumVectors ());
567 const int numColsMv =
static_cast<int> (mv.getNumVectors ());
569 const bool validIndex =
570 index.lbound () >= 0 && index.ubound () < numColsMv;
572 const bool validSource = index.size () <= numColsA;
574 if (! validIndex || ! validSource) {
575 std::ostringstream os;
576 os <<
"Anasazi::MultiVecTraits::SetBlock(A, index=[" << index.lbound ()
577 <<
", " << index.ubound () <<
"], mv): ";
578 TEUCHOS_TEST_FOR_EXCEPTION(
579 index.lbound() < 0, std::invalid_argument,
580 os.str() <<
"Range lower bound must be nonnegative.");
581 TEUCHOS_TEST_FOR_EXCEPTION(
582 index.ubound() >= numColsMv, std::invalid_argument,
583 os.str() <<
"Range upper bound must be less than the number of "
584 "columns " << numColsA <<
" in the 'mv' output argument.");
585 TEUCHOS_TEST_FOR_EXCEPTION(
586 index.size() > numColsA, std::invalid_argument,
587 os.str() <<
"Range must have no more elements than the number of "
588 "columns " << numColsA <<
" in the 'A' input argument.");
589 TEUCHOS_TEST_FOR_EXCEPTION(
590 true, std::logic_error,
"Should never get here!");
596 Teuchos::RCP<MV> mv_view;
597 if (index.lbound () == 0 && index.ubound () + 1 == numColsMv) {
598 mv_view = Teuchos::rcpFromRef (mv);
606 Teuchos::RCP<const MV> A_view;
607 if (index.size () == numColsA) {
608 A_view = Teuchos::rcpFromRef (A);
610 A_view =
CloneView (A, Teuchos::Range1D (0, index.size () - 1));
613 Tpetra::deep_copy (*mv_view, *A_view);
616 static void Assign (
const MV& A, MV& mv)
618 const char errPrefix[] =
"Anasazi::MultiVecTraits::Assign(A, mv): ";
627 const size_t maxInt =
628 static_cast<size_t> (Teuchos::OrdinalTraits<int>::max ());
629 const bool overflow =
630 maxInt < A.getNumVectors () && maxInt < mv.getNumVectors ();
632 TEUCHOS_TEST_FOR_EXCEPTION(
633 maxInt < A.getNumVectors(), std::range_error,
634 errPrefix <<
"Number of columns in the input multivector 'A' "
635 "(a size_t) overflows int.");
636 TEUCHOS_TEST_FOR_EXCEPTION(
637 maxInt < mv.getNumVectors(), std::range_error,
638 errPrefix <<
"Number of columns in the output multivector 'mv' "
639 "(a size_t) overflows int.");
640 TEUCHOS_TEST_FOR_EXCEPTION(
641 true, std::logic_error,
"Should never get here!");
644 const int numColsA =
static_cast<int> (A.getNumVectors ());
645 const int numColsMv =
static_cast<int> (mv.getNumVectors ());
646 if (numColsA > numColsMv) {
647 TEUCHOS_TEST_FOR_EXCEPTION(
648 numColsA > numColsMv, std::invalid_argument,
649 errPrefix <<
"Input multivector 'A' has " << numColsA <<
" columns, "
650 "but output multivector 'mv' has only " << numColsMv <<
" columns.");
651 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Should never get here!");
653 if (numColsA == numColsMv) {
654 Tpetra::deep_copy (mv, A);
656 Teuchos::RCP<MV> mv_view =
658 Tpetra::deep_copy (*mv_view, A);
667 MvInit (MV& mv,
const Scalar alpha = Teuchos::ScalarTraits<Scalar>::zero ())
669 mv.putScalar (alpha);
672 static void MvPrint (
const MV& mv, std::ostream& os) {
673 Teuchos::FancyOStream fos (Teuchos::rcpFromRef (os));
674 mv.describe (fos, Teuchos::VERB_EXTREME);
677#ifdef HAVE_ANASAZI_TSQR
680 typedef Tpetra::TsqrAdaptor<Tpetra::MultiVector<Scalar, LO, GO, Node> > tsqr_adaptor_type;