Stratimikos Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
BelosThyraAdapter.hpp
Go to the documentation of this file.
1// @HEADER
2// ***********************************************************************
3//
4// Stratimikos: Thyra-based strategies for linear solvers
5// Copyright (2006) Sandia Corporation
6//
7// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8// license for use of this work by or on behalf of the U.S. Government.
9//
10// Redistribution and use in source and binary forms, with or without
11// modification, are permitted provided that the following conditions are
12// met:
13//
14// 1. Redistributions of source code must retain the above copyright
15// notice, this list of conditions and the following disclaimer.
16//
17// 2. Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution.
20//
21// 3. Neither the name of the Corporation nor the names of the
22// contributors may be used to endorse or promote products derived from
23// this software without specific prior written permission.
24//
25// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36//
37// Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov)
38//
39// ***********************************************************************
40// @HEADER
41
52#ifndef BELOS_THYRA_ADAPTER_HPP
53#define BELOS_THYRA_ADAPTER_HPP
54
55#include "BelosConfigDefs.hpp"
56#include "BelosMultiVecTraits.hpp"
57#include "BelosOperatorTraits.hpp"
58
59#include <Thyra_DetachedMultiVectorView.hpp>
60#include <Thyra_MultiVectorBase.hpp>
61#include <Thyra_MultiVectorStdOps.hpp>
62#ifdef HAVE_BELOS_TSQR
63# include <Thyra_TsqrAdaptor.hpp>
64#endif // HAVE_BELOS_TSQR
65
66#include <Teuchos_TimeMonitor.hpp>
67
68namespace Belos {
69
71 //
72 // Implementation of the Belos::MultiVecTraits for Thyra::MultiVectorBase
73 //
75
82 template<class ScalarType>
83 class MultiVecTraits< ScalarType, Thyra::MultiVectorBase<ScalarType> >
84 {
85 private:
86 typedef Thyra::MultiVectorBase<ScalarType> TMVB;
87 typedef Teuchos::ScalarTraits<ScalarType> ST;
88 typedef typename ST::magnitudeType magType;
89
90 public:
91
94
99 static Teuchos::RCP<TMVB> Clone( const TMVB& mv, const int numvecs )
100 {
101 Teuchos::RCP<TMVB> c = Thyra::createMembers( mv.range(), numvecs );
102 return c;
103 }
104
109 static Teuchos::RCP<TMVB> CloneCopy( const TMVB& mv )
110 {
111 int numvecs = mv.domain()->dim();
112 // create the new multivector
113 Teuchos::RCP< TMVB > cc = Thyra::createMembers( mv.range(), numvecs );
114 // copy the data from the source multivector to the new multivector
115 Thyra::assign(cc.ptr(), mv);
116 return cc;
117 }
118
124 static Teuchos::RCP<TMVB> CloneCopy( const TMVB& mv, const std::vector<int>& index )
125 {
126 int numvecs = index.size();
127 // create the new multivector
128 Teuchos::RCP<TMVB> cc = Thyra::createMembers( mv.range(), numvecs );
129 // create a view to the relevant part of the source multivector
130 Teuchos::RCP<const TMVB> view = mv.subView(index);
131 // copy the data from the relevant view to the new multivector
132 Thyra::assign(cc.ptr(), *view);
133 return cc;
134 }
135
136 static Teuchos::RCP<TMVB>
137 CloneCopy (const TMVB& mv, const Teuchos::Range1D& index)
138 {
139 const int numVecs = index.size();
140 // Create the new multivector
141 Teuchos::RCP<TMVB> cc = Thyra::createMembers (mv.range(), numVecs);
142 // Create a view to the relevant part of the source multivector
143 Teuchos::RCP<const TMVB> view = mv.subView (index);
144 // Copy the data from the view to the new multivector.
145 Thyra::assign (cc.ptr(), *view);
146 return cc;
147 }
148
154 static Teuchos::RCP<TMVB> CloneViewNonConst( TMVB& mv, const std::vector<int>& index )
155 {
156 int numvecs = index.size();
157
158 // We do not assume that the indices are sorted, nor do we check that
159 // index.size() > 0. This code is fail-safe, in the sense that a zero
160 // length index std::vector will pass the error on the Thyra.
161
162 // Thyra has two ways to create an indexed View:
163 // * contiguous (via a range of columns)
164 // * indexed (via a std::vector of column indices)
165 // The former is significantly more efficient than the latter, in terms of
166 // computations performed with/against the created view.
167 // We will therefore check to see if the given indices are contiguous, and
168 // if so, we will use the contiguous view creation method.
169
170 int lb = index[0];
171 bool contig = true;
172 for (int i=0; i<numvecs; i++) {
173 if (lb+i != index[i]) contig = false;
174 }
175
176 Teuchos::RCP< TMVB > cc;
177 if (contig) {
178 const Thyra::Range1D rng(lb,lb+numvecs-1);
179 // create a contiguous view to the relevant part of the source multivector
180 cc = mv.subView(rng);
181 }
182 else {
183 // create an indexed view to the relevant part of the source multivector
184 cc = mv.subView(index);
185 }
186 return cc;
187 }
188
189 static Teuchos::RCP<TMVB>
190 CloneViewNonConst (TMVB& mv, const Teuchos::Range1D& index)
191 {
192 // We let Thyra be responsible for checking that the index range
193 // is nonempty.
194 //
195 // Create and return a contiguous view to the relevant part of
196 // the source multivector.
197 return mv.subView (index);
198 }
199
200
206 static Teuchos::RCP<const TMVB> CloneView( const TMVB& mv, const std::vector<int>& index )
207 {
208 int numvecs = index.size();
209
210 // We do not assume that the indices are sorted, nor do we check that
211 // index.size() > 0. This code is fail-safe, in the sense that a zero
212 // length index std::vector will pass the error on the Thyra.
213
214 // Thyra has two ways to create an indexed View:
215 // * contiguous (via a range of columns)
216 // * indexed (via a std::vector of column indices)
217 // The former is significantly more efficient than the latter, in terms of
218 // computations performed with/against the created view.
219 // We will therefore check to see if the given indices are contiguous, and
220 // if so, we will use the contiguous view creation method.
221
222 int lb = index[0];
223 bool contig = true;
224 for (int i=0; i<numvecs; i++) {
225 if (lb+i != index[i]) contig = false;
226 }
227
228 Teuchos::RCP< const TMVB > cc;
229 if (contig) {
230 const Thyra::Range1D rng(lb,lb+numvecs-1);
231 // create a contiguous view to the relevant part of the source multivector
232 cc = mv.subView(rng);
233 }
234 else {
235 // create an indexed view to the relevant part of the source multivector
236 cc = mv.subView(index);
237 }
238 return cc;
239 }
240
241 static Teuchos::RCP<const TMVB>
242 CloneView (const TMVB& mv, const Teuchos::Range1D& index)
243 {
244 // We let Thyra be responsible for checking that the index range
245 // is nonempty.
246 //
247 // Create and return a contiguous view to the relevant part of
248 // the source multivector.
249 return mv.subView (index);
250 }
251
253
256
258 static ptrdiff_t GetGlobalLength( const TMVB& mv ) {
259 return Teuchos::as<ptrdiff_t>(mv.range()->dim());
260 }
261
263 static int GetNumberVecs( const TMVB& mv )
264 { return mv.domain()->dim(); }
265
267
270
273 static void MvTimesMatAddMv( const ScalarType alpha, const TMVB& A,
274 const Teuchos::SerialDenseMatrix<int,ScalarType>& B,
275 const ScalarType beta, TMVB& mv )
276 {
277 using Teuchos::arrayView; using Teuchos::arcpFromArrayView;
278
279 Teuchos::TimeMonitor tM(*Teuchos::TimeMonitor::getNewTimer(std::string("Belos::MVT::MvTimesMatAddMv")));
280
281 const int m = B.numRows();
282 const int n = B.numCols();
283 auto vs = A.domain();
284 // Create a view of the B object!
285 Teuchos::RCP< const TMVB >
286 B_thyra = vs->createCachedMembersView(
288 0, m, 0, n,
289 arcpFromArrayView(arrayView(&B(0,0), B.stride()*B.numCols())), B.stride()
290 )
291 );
292 // perform the operation via A: mv <- alpha*A*B_thyra + beta*mv
293 Thyra::apply<ScalarType>(A, Thyra::NOTRANS, *B_thyra, Teuchos::outArg(mv), alpha, beta);
294 }
295
298 static void MvAddMv( const ScalarType alpha, const TMVB& A,
299 const ScalarType beta, const TMVB& B, TMVB& mv )
300 {
301 using Teuchos::tuple; using Teuchos::ptrInArg; using Teuchos::inoutArg;
302
303 Teuchos::TimeMonitor tM(*Teuchos::TimeMonitor::getNewTimer(std::string("Belos::MVT::MvAddMv")));
304
305 Thyra::linear_combination<ScalarType>(
306 tuple(alpha, beta)(), tuple(ptrInArg(A), ptrInArg(B))(), Teuchos::ScalarTraits<ScalarType>::zero(), inoutArg(mv));
307 }
308
311 static void MvScale ( TMVB& mv, const ScalarType alpha )
312 {
313 Teuchos::TimeMonitor tM(*Teuchos::TimeMonitor::getNewTimer(std::string("Belos::MVT::MvScale")));
314
315 Thyra::scale(alpha, Teuchos::inoutArg(mv));
316 }
317
320 static void MvScale (TMVB& mv, const std::vector<ScalarType>& alpha)
321 {
322 Teuchos::TimeMonitor tM(*Teuchos::TimeMonitor::getNewTimer(std::string("Belos::MVT::MvScale")));
323
324 for (unsigned int i=0; i<alpha.size(); i++) {
325 Thyra::scale<ScalarType> (alpha[i], mv.col(i).ptr());
326 }
327 }
328
331 static void MvTransMv( const ScalarType alpha, const TMVB& A, const TMVB& mv,
332 Teuchos::SerialDenseMatrix<int,ScalarType>& B )
333 {
334 using Teuchos::arrayView; using Teuchos::arcpFromArrayView;
335
336 Teuchos::TimeMonitor tM(*Teuchos::TimeMonitor::getNewTimer(std::string("Belos::MVT::MvTransMv")));
337
338 // Create a multivector to hold the result (m by n)
339 int m = A.domain()->dim();
340 int n = mv.domain()->dim();
341 auto vs = A.domain();
342 // Create a view of the B object!
343 Teuchos::RCP< TMVB >
344 B_thyra = vs->createCachedMembersView(
346 0, m, 0, n,
347 arcpFromArrayView(arrayView(&B(0,0), B.stride()*B.numCols())), B.stride()
348 )
349 );
350 Thyra::apply<ScalarType>(A, Thyra::CONJTRANS, mv, B_thyra.ptr(), alpha);
351 }
352
356 static void MvDot( const TMVB& mv, const TMVB& A, std::vector<ScalarType>& b )
357 {
358 Teuchos::TimeMonitor tM(*Teuchos::TimeMonitor::getNewTimer(std::string("Belos::MVT::MvDot")));
359
360 Thyra::dots(mv, A, Teuchos::arrayViewFromVector(b));
361 }
362
364
367
371 static void MvNorm( const TMVB& mv, std::vector<magType>& normvec,
372 NormType type = TwoNorm ) {
373 Teuchos::TimeMonitor tM(*Teuchos::TimeMonitor::getNewTimer(std::string("Belos::MVT::MvNorm")));
374
375 if(type == TwoNorm)
376 Thyra::norms_2(mv, Teuchos::arrayViewFromVector(normvec));
377 else if(type == OneNorm)
378 Thyra::norms_1(mv, Teuchos::arrayViewFromVector(normvec));
379 else if(type == InfNorm)
380 Thyra::norms_inf(mv, Teuchos::arrayViewFromVector(normvec));
381 else
382 TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument,
383 "Belos::MultiVecTraits::MvNorm (Thyra specialization): "
384 "invalid norm type. Must be either TwoNorm, OneNorm or InfNorm");
385 }
386
388
391
394 static void SetBlock( const TMVB& A, const std::vector<int>& index, TMVB& mv )
395 {
396 // Extract the "numvecs" columns of mv indicated by the index std::vector.
397 int numvecs = index.size();
398 std::vector<int> indexA(numvecs);
399 int numAcols = A.domain()->dim();
400 for (int i=0; i<numvecs; i++) {
401 indexA[i] = i;
402 }
403 // Thyra::assign requires that both arguments have the same number of
404 // vectors. Enforce this, by shrinking one to match the other.
405 if ( numAcols < numvecs ) {
406 // A does not have enough columns to satisfy index_plus. Shrink
407 // index_plus.
408 numvecs = numAcols;
409 }
410 else if ( numAcols > numvecs ) {
411 numAcols = numvecs;
412 indexA.resize( numAcols );
413 }
414 // create a view to the relevant part of the source multivector
415 Teuchos::RCP< const TMVB > relsource = A.subView(indexA);
416 // create a view to the relevant part of the destination multivector
417 Teuchos::RCP< TMVB > reldest = mv.subView(index);
418 // copy the data to the destination multivector subview
419 Thyra::assign(reldest.ptr(), *relsource);
420 }
421
422 static void
423 SetBlock (const TMVB& A, const Teuchos::Range1D& index, TMVB& mv)
424 {
425 const int numColsA = A.domain()->dim();
426 const int numColsMv = mv.domain()->dim();
427 // 'index' indexes into mv; it's the index set of the target.
428 const bool validIndex = index.lbound() >= 0 && index.ubound() < numColsMv;
429 // We can't take more columns out of A than A has.
430 const bool validSource = index.size() <= numColsA;
431
432 if (! validIndex || ! validSource)
433 {
434 std::ostringstream os;
435 os << "Belos::MultiVecTraits<Scalar, Thyra::MultiVectorBase<Scalar> "
436 ">::SetBlock(A, [" << index.lbound() << ", " << index.ubound()
437 << "], mv): ";
438 TEUCHOS_TEST_FOR_EXCEPTION(index.lbound() < 0, std::invalid_argument,
439 os.str() << "Range lower bound must be nonnegative.");
440 TEUCHOS_TEST_FOR_EXCEPTION(index.ubound() >= numColsMv, std::invalid_argument,
441 os.str() << "Range upper bound must be less than "
442 "the number of columns " << numColsA << " in the "
443 "'mv' output argument.");
444 TEUCHOS_TEST_FOR_EXCEPTION(index.size() > numColsA, std::invalid_argument,
445 os.str() << "Range must have no more elements than"
446 " the number of columns " << numColsA << " in the "
447 "'A' input argument.");
448 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Should never get here!");
449 }
450
451 // View of the relevant column(s) of the target multivector mv.
452 // We avoid view creation overhead by only creating a view if
453 // the index range is different than [0, (# columns in mv) - 1].
454 Teuchos::RCP<TMVB> mv_view;
455 if (index.lbound() == 0 && index.ubound()+1 == numColsMv)
456 mv_view = Teuchos::rcpFromRef (mv); // Non-const, non-owning RCP
457 else
458 mv_view = mv.subView (index);
459
460 // View of the relevant column(s) of the source multivector A.
461 // If A has fewer columns than mv_view, then create a view of
462 // the first index.size() columns of A.
463 Teuchos::RCP<const TMVB> A_view;
464 if (index.size() == numColsA)
465 A_view = Teuchos::rcpFromRef (A); // Const, non-owning RCP
466 else
467 A_view = A.subView (Teuchos::Range1D(0, index.size()-1));
468
469 // Copy the data to the destination multivector.
470 Thyra::assign(mv_view.ptr(), *A_view);
471 }
472
473 static void
474 Assign (const TMVB& A, TMVB& mv)
475 {
476 Teuchos::TimeMonitor tM(*Teuchos::TimeMonitor::getNewTimer(std::string("Belos::MVT::Assign")));
477
478 const int numColsA = A.domain()->dim();
479 const int numColsMv = mv.domain()->dim();
480 if (numColsA > numColsMv)
481 {
482 std::ostringstream os;
483 os << "Belos::MultiVecTraits<Scalar, Thyra::MultiVectorBase<Scalar>"
484 " >::Assign(A, mv): ";
485 TEUCHOS_TEST_FOR_EXCEPTION(numColsA > numColsMv, std::invalid_argument,
486 os.str() << "Input multivector 'A' has "
487 << numColsA << " columns, but output multivector "
488 "'mv' has only " << numColsMv << " columns.");
489 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Should never get here!");
490 }
491 // Copy the data to the destination multivector.
492 if (numColsA == numColsMv) {
493 Thyra::assign (Teuchos::outArg (mv), A);
494 } else {
495 Teuchos::RCP<TMVB> mv_view =
496 CloneViewNonConst (mv, Teuchos::Range1D(0, numColsA-1));
497 Thyra::assign (mv_view.ptr(), A);
498 }
499 }
500
503 static void MvRandom( TMVB& mv )
504 {
505 // Thyra::randomize generates via a uniform distribution on [l,u]
506 // We will use this to generate on [-1,1]
507 Thyra::randomize<ScalarType>(
508 -Teuchos::ScalarTraits<ScalarType>::one(),
509 Teuchos::ScalarTraits<ScalarType>::one(),
510 Teuchos::outArg(mv));
511 }
512
514 static void
515 MvInit (TMVB& mv, ScalarType alpha = Teuchos::ScalarTraits<ScalarType>::zero())
516 {
517 Thyra::assign (Teuchos::outArg (mv), alpha);
518 }
519
521
524
527 static void MvPrint( const TMVB& mv, std::ostream& os )
528 { os << describe(mv,Teuchos::VERB_EXTREME); }
529
531
532#ifdef HAVE_BELOS_TSQR
538 typedef Thyra::TsqrAdaptor< ScalarType > tsqr_adaptor_type;
539#endif // HAVE_BELOS_TSQR
540 };
541
543 //
544 // Implementation of the Belos::OperatorTraits for Thyra::LinearOpBase
545 //
547
555 template<class ScalarType>
556 class OperatorTraits <ScalarType,
557 Thyra::MultiVectorBase<ScalarType>,
558 Thyra::LinearOpBase<ScalarType> >
559 {
560 private:
561 typedef Thyra::MultiVectorBase<ScalarType> TMVB;
562 typedef Thyra::LinearOpBase<ScalarType> TLOB;
563
564 public:
580 static void
581 Apply (const TLOB& Op,
582 const TMVB& x,
583 TMVB& y,
584 ETrans trans = NOTRANS)
585 {
586 Thyra::EOpTransp whichOp;
587
588 // We don't check here whether the operator implements the
589 // requested operation. Call HasApplyTranspose() to check.
590 // Thyra::LinearOpBase implementations are not required to
591 // implement NOTRANS. However, Belos needs NOTRANS
592 // (obviously!), so we assume that Op implements NOTRANS.
593 if (trans == NOTRANS)
594 whichOp = Thyra::NOTRANS;
595 else if (trans == TRANS)
596 whichOp = Thyra::TRANS;
597 else if (trans == CONJTRANS)
598 whichOp = Thyra::CONJTRANS;
599 else
600 TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument,
601 "Belos::OperatorTraits::Apply (Thyra specialization): "
602 "'trans' argument must be neither NOTRANS=" << NOTRANS
603 << ", TRANS=" << TRANS << ", or CONJTRANS=" << CONJTRANS
604 << ", but instead has an invalid value of " << trans << ".");
605 Thyra::apply<ScalarType>(Op, whichOp, x, Teuchos::outArg(y));
606 }
607
609 static bool HasApplyTranspose (const TLOB& Op)
610 {
611 typedef Teuchos::ScalarTraits<ScalarType> STS;
612
613 // Thyra::LinearOpBase's interface lets you check whether the
614 // operator implements any of all four possible combinations of
615 // conjugation and transpose. Belos only needs transpose
616 // (TRANS) if the operator is real; in that case, Apply() does
617 // the same thing with trans = CONJTRANS or TRANS. If the
618 // operator is complex, Belos needs both transpose and conjugate
619 // transpose (CONJTRANS) if the operator is complex.
620 return Op.opSupported (Thyra::TRANS) &&
621 (! STS::isComplex || Op.opSupported (Thyra::CONJTRANS));
622 }
623 };
624
625} // end of Belos namespace
626
627#endif
628// end of file BELOS_THYRA_ADAPTER_HPP
static void MvPrint(const TMVB &mv, std::ostream &os)
Print the mv multi-std::vector to the os output stream.
static void SetBlock(const TMVB &A, const std::vector< int > &index, TMVB &mv)
Copy the vectors in A to a set of vectors in mv indicated by the indices given in index.
static void MvAddMv(const ScalarType alpha, const TMVB &A, const ScalarType beta, const TMVB &B, TMVB &mv)
Replace mv with .
static int GetNumberVecs(const TMVB &mv)
Obtain the number of vectors in mv.
static Teuchos::RCP< TMVB > CloneCopy(const TMVB &mv)
Creates a new MultiVectorBase and copies contents of mv into the new std::vector (deep copy).
static Teuchos::RCP< const TMVB > CloneView(const TMVB &mv, const Teuchos::Range1D &index)
static void SetBlock(const TMVB &A, const Teuchos::Range1D &index, TMVB &mv)
static ptrdiff_t GetGlobalLength(const TMVB &mv)
Obtain the std::vector length of mv.
static void MvDot(const TMVB &mv, const TMVB &A, std::vector< ScalarType > &b)
Compute a std::vector b where the components are the individual dot-products of the i-th columns of A...
static Teuchos::RCP< TMVB > CloneCopy(const TMVB &mv, const std::vector< int > &index)
Creates a new MultiVectorBase and copies the selected contents of mv into the new std::vector (deep c...
static Teuchos::RCP< TMVB > CloneCopy(const TMVB &mv, const Teuchos::Range1D &index)
static Teuchos::RCP< TMVB > CloneViewNonConst(TMVB &mv, const std::vector< int > &index)
Creates a new MultiVectorBase that shares the selected contents of mv (shallow copy).
static Teuchos::RCP< TMVB > CloneViewNonConst(TMVB &mv, const Teuchos::Range1D &index)
static Teuchos::RCP< TMVB > Clone(const TMVB &mv, const int numvecs)
Creates a new empty MultiVectorBase containing numvecs columns.
static Teuchos::RCP< const TMVB > CloneView(const TMVB &mv, const std::vector< int > &index)
Creates a new const MultiVectorBase that shares the selected contents of mv (shallow copy).
static void MvScale(TMVB &mv, const ScalarType alpha)
Scale each element of the vectors in *this with alpha.
static void MvTransMv(const ScalarType alpha, const TMVB &A, const TMVB &mv, Teuchos::SerialDenseMatrix< int, ScalarType > &B)
Compute a dense matrix B through the matrix-matrix multiply .
static void MvScale(TMVB &mv, const std::vector< ScalarType > &alpha)
Scale each element of the i-th vector in *this with alpha[i].
static void MvTimesMatAddMv(const ScalarType alpha, const TMVB &A, const Teuchos::SerialDenseMatrix< int, ScalarType > &B, const ScalarType beta, TMVB &mv)
Update mv with .
static void MvRandom(TMVB &mv)
Replace the vectors in mv with random vectors.
static void MvNorm(const TMVB &mv, std::vector< magType > &normvec, NormType type=TwoNorm)
Compute the 2-norm of each individual std::vector of mv. Upon return, normvec[i] holds the value of ,...
static void MvInit(TMVB &mv, ScalarType alpha=Teuchos::ScalarTraits< ScalarType >::zero())
Replace each element of the vectors in mv with alpha.
static bool HasApplyTranspose(const TLOB &Op)
Whether the operator implements applying the transpose.
static void Apply(const TLOB &Op, const TMVB &x, TMVB &y, ETrans trans=NOTRANS)
Apply Op to x, storing the result in y.