Stratimikos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 "Stratimikos_Config.h"
56 #include "BelosConfigDefs.hpp"
57 #include "BelosMultiVecTraits.hpp"
58 #include "BelosOperatorTraits.hpp"
59 
60 #include <Thyra_DetachedMultiVectorView.hpp>
61 #include <Thyra_MultiVectorBase.hpp>
62 #include <Thyra_MultiVectorStdOps.hpp>
63 #ifdef HAVE_BELOS_TSQR
64 # include <Thyra_TsqrAdaptor.hpp>
65 #endif // HAVE_BELOS_TSQR
66 
67 #ifdef HAVE_STRATIMIKOS_BELOS_TIMERS
68 # include <Teuchos_TimeMonitor.hpp>
69 
70 # define STRATIMIKOS_TIME_MONITOR(NAME) \
71  Teuchos::TimeMonitor tM(*Teuchos::TimeMonitor::getNewTimer(std::string(NAME)))
72 
73 #else
74 
75 # define STRATIMIKOS_TIME_MONITOR(NAME)
76 
77 #endif
78 
79 namespace Belos {
80 
82  //
83  // Implementation of the Belos::MultiVecTraits for Thyra::MultiVectorBase
84  //
86 
93  template<class ScalarType>
94  class MultiVecTraits< ScalarType, Thyra::MultiVectorBase<ScalarType> >
95  {
96  private:
97  typedef Thyra::MultiVectorBase<ScalarType> TMVB;
99  typedef typename ST::magnitudeType magType;
100 
101  public:
102 
105 
110  static Teuchos::RCP<TMVB> Clone( const TMVB& mv, const int numvecs )
111  {
112  Teuchos::RCP<TMVB> c = Thyra::createMembers( mv.range(), numvecs );
113  return c;
114  }
115 
120  static Teuchos::RCP<TMVB> CloneCopy( const TMVB& mv )
121  {
122  int numvecs = mv.domain()->dim();
123  // create the new multivector
124  Teuchos::RCP< TMVB > cc = Thyra::createMembers( mv.range(), numvecs );
125  // copy the data from the source multivector to the new multivector
126  Thyra::assign(cc.ptr(), mv);
127  return cc;
128  }
129 
135  static Teuchos::RCP<TMVB> CloneCopy( const TMVB& mv, const std::vector<int>& index )
136  {
137  int numvecs = index.size();
138  // create the new multivector
139  Teuchos::RCP<TMVB> cc = Thyra::createMembers( mv.range(), numvecs );
140  // create a view to the relevant part of the source multivector
141  Teuchos::RCP<const TMVB> view = mv.subView(index);
142  // copy the data from the relevant view to the new multivector
143  Thyra::assign(cc.ptr(), *view);
144  return cc;
145  }
146 
147  static Teuchos::RCP<TMVB>
148  CloneCopy (const TMVB& mv, const Teuchos::Range1D& index)
149  {
150  const int numVecs = index.size();
151  // Create the new multivector
152  Teuchos::RCP<TMVB> cc = Thyra::createMembers (mv.range(), numVecs);
153  // Create a view to the relevant part of the source multivector
154  Teuchos::RCP<const TMVB> view = mv.subView (index);
155  // Copy the data from the view to the new multivector.
156  Thyra::assign (cc.ptr(), *view);
157  return cc;
158  }
159 
165  static Teuchos::RCP<TMVB> CloneViewNonConst( TMVB& mv, const std::vector<int>& index )
166  {
167  int numvecs = index.size();
168 
169  // We do not assume that the indices are sorted, nor do we check that
170  // index.size() > 0. This code is fail-safe, in the sense that a zero
171  // length index std::vector will pass the error on the Thyra.
172 
173  // Thyra has two ways to create an indexed View:
174  // * contiguous (via a range of columns)
175  // * indexed (via a std::vector of column indices)
176  // The former is significantly more efficient than the latter, in terms of
177  // computations performed with/against the created view.
178  // We will therefore check to see if the given indices are contiguous, and
179  // if so, we will use the contiguous view creation method.
180 
181  int lb = index[0];
182  bool contig = true;
183  for (int i=0; i<numvecs; i++) {
184  if (lb+i != index[i]) contig = false;
185  }
186 
188  if (contig) {
189  const Thyra::Range1D rng(lb,lb+numvecs-1);
190  // create a contiguous view to the relevant part of the source multivector
191  cc = mv.subView(rng);
192  }
193  else {
194  // create an indexed view to the relevant part of the source multivector
195  cc = mv.subView(index);
196  }
197  return cc;
198  }
199 
200  static Teuchos::RCP<TMVB>
202  {
203  // We let Thyra be responsible for checking that the index range
204  // is nonempty.
205  //
206  // Create and return a contiguous view to the relevant part of
207  // the source multivector.
208  return mv.subView (index);
209  }
210 
211 
217  static Teuchos::RCP<const TMVB> CloneView( const TMVB& mv, const std::vector<int>& index )
218  {
219  int numvecs = index.size();
220 
221  // We do not assume that the indices are sorted, nor do we check that
222  // index.size() > 0. This code is fail-safe, in the sense that a zero
223  // length index std::vector will pass the error on the Thyra.
224 
225  // Thyra has two ways to create an indexed View:
226  // * contiguous (via a range of columns)
227  // * indexed (via a std::vector of column indices)
228  // The former is significantly more efficient than the latter, in terms of
229  // computations performed with/against the created view.
230  // We will therefore check to see if the given indices are contiguous, and
231  // if so, we will use the contiguous view creation method.
232 
233  int lb = index[0];
234  bool contig = true;
235  for (int i=0; i<numvecs; i++) {
236  if (lb+i != index[i]) contig = false;
237  }
238 
240  if (contig) {
241  const Thyra::Range1D rng(lb,lb+numvecs-1);
242  // create a contiguous view to the relevant part of the source multivector
243  cc = mv.subView(rng);
244  }
245  else {
246  // create an indexed view to the relevant part of the source multivector
247  cc = mv.subView(index);
248  }
249  return cc;
250  }
251 
253  CloneView (const TMVB& mv, const Teuchos::Range1D& index)
254  {
255  // We let Thyra be responsible for checking that the index range
256  // is nonempty.
257  //
258  // Create and return a contiguous view to the relevant part of
259  // the source multivector.
260  return mv.subView (index);
261  }
262 
264 
267 
269  static ptrdiff_t GetGlobalLength( const TMVB& mv ) {
270  return Teuchos::as<ptrdiff_t>(mv.range()->dim());
271  }
272 
274  static int GetNumberVecs( const TMVB& mv )
275  { return mv.domain()->dim(); }
276 
278 
281 
284  static void MvTimesMatAddMv( const ScalarType alpha, const TMVB& A,
286  const ScalarType beta, TMVB& mv )
287  {
288  using Teuchos::arrayView; using Teuchos::arcpFromArrayView;
289  STRATIMIKOS_TIME_MONITOR("Belos::MVT::MvTimesMatAddMv");
290 
291  const int m = B.numRows();
292  const int n = B.numCols();
293  // Check if B is 1-by-1, in which case we can just call MvAddMv()
294  if ((m == 1) && (n == 1)) {
295  using Teuchos::tuple; using Teuchos::ptrInArg; using Teuchos::inoutArg;
296  const ScalarType alphaNew = alpha * B(0, 0);
297  Thyra::linear_combination<ScalarType>(tuple(alphaNew)(), tuple(ptrInArg(A))(), beta, inoutArg(mv));
298  } else {
299  // perform the operation via A: mv <- alpha*A*B_thyra + beta*mv
300  auto vs = A.domain();
301  // Create a view of the B object!
303  B_thyra = vs->createCachedMembersView(
305  0, m, 0, n,
306  arcpFromArrayView(arrayView(&B(0,0), B.stride()*B.numCols())), B.stride()
307  )
308  );
309  Thyra::apply<ScalarType>(A, Thyra::NOTRANS, *B_thyra, Teuchos::outArg(mv), alpha, beta);
310  }
311  }
312 
315  static void MvAddMv( const ScalarType alpha, const TMVB& A,
316  const ScalarType beta, const TMVB& B, TMVB& mv )
317  {
318  using Teuchos::tuple; using Teuchos::ptrInArg; using Teuchos::inoutArg;
319  STRATIMIKOS_TIME_MONITOR("Belos::MVT::MvAddMv");
320 
321  Thyra::linear_combination<ScalarType>(
322  tuple(alpha, beta)(), tuple(ptrInArg(A), ptrInArg(B))(), Teuchos::ScalarTraits<ScalarType>::zero(), inoutArg(mv));
323  }
324 
327  static void MvScale ( TMVB& mv, const ScalarType alpha )
328  {
329  STRATIMIKOS_TIME_MONITOR("Belos::MVT::MvScale");
330 
331  Thyra::scale(alpha, Teuchos::inoutArg(mv));
332  }
333 
336  static void MvScale (TMVB& mv, const std::vector<ScalarType>& alpha)
337  {
338  STRATIMIKOS_TIME_MONITOR("Belos::MVT::MvScale");
339 
340  for (unsigned int i=0; i<alpha.size(); i++) {
341  Thyra::scale<ScalarType> (alpha[i], mv.col(i).ptr());
342  }
343  }
344 
347  static void MvTransMv( const ScalarType alpha, const TMVB& A, const TMVB& mv,
349  {
350  using Teuchos::arrayView; using Teuchos::arcpFromArrayView;
351  STRATIMIKOS_TIME_MONITOR("Belos::MVT::MvTransMv");
352 
353  // Create a multivector to hold the result (m by n)
354  int m = A.domain()->dim();
355  int n = mv.domain()->dim();
356  auto vs = A.domain();
357  // Create a view of the B object!
359  B_thyra = vs->createCachedMembersView(
361  0, m, 0, n,
362  arcpFromArrayView(arrayView(&B(0,0), B.stride()*B.numCols())), B.stride()
363  ),
364  false
365  );
366  Thyra::apply<ScalarType>(A, Thyra::CONJTRANS, mv, B_thyra.ptr(), alpha);
367  }
368 
372  static void MvDot( const TMVB& mv, const TMVB& A, std::vector<ScalarType>& b )
373  {
374  STRATIMIKOS_TIME_MONITOR("Belos::MVT::MvDot");
375 
376  Thyra::dots(mv, A, Teuchos::arrayViewFromVector(b));
377  }
378 
380 
383 
387  static void MvNorm( const TMVB& mv, std::vector<magType>& normvec,
388  NormType type = TwoNorm ) {
389  STRATIMIKOS_TIME_MONITOR("Belos::MVT::MvNorm");
390 
391  if(type == TwoNorm)
392  Thyra::norms_2(mv, Teuchos::arrayViewFromVector(normvec));
393  else if(type == OneNorm)
394  Thyra::norms_1(mv, Teuchos::arrayViewFromVector(normvec));
395  else if(type == InfNorm)
396  Thyra::norms_inf(mv, Teuchos::arrayViewFromVector(normvec));
397  else
398  TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument,
399  "Belos::MultiVecTraits::MvNorm (Thyra specialization): "
400  "invalid norm type. Must be either TwoNorm, OneNorm or InfNorm");
401  }
402 
404 
407 
410  static void SetBlock( const TMVB& A, const std::vector<int>& index, TMVB& mv )
411  {
412  // Extract the "numvecs" columns of mv indicated by the index std::vector.
413  int numvecs = index.size();
414  std::vector<int> indexA(numvecs);
415  int numAcols = A.domain()->dim();
416  for (int i=0; i<numvecs; i++) {
417  indexA[i] = i;
418  }
419  // Thyra::assign requires that both arguments have the same number of
420  // vectors. Enforce this, by shrinking one to match the other.
421  if ( numAcols < numvecs ) {
422  // A does not have enough columns to satisfy index_plus. Shrink
423  // index_plus.
424  numvecs = numAcols;
425  }
426  else if ( numAcols > numvecs ) {
427  numAcols = numvecs;
428  indexA.resize( numAcols );
429  }
430  // create a view to the relevant part of the source multivector
431  Teuchos::RCP< const TMVB > relsource = A.subView(indexA);
432  // create a view to the relevant part of the destination multivector
433  Teuchos::RCP< TMVB > reldest = mv.subView(index);
434  // copy the data to the destination multivector subview
435  Thyra::assign(reldest.ptr(), *relsource);
436  }
437 
438  static void
439  SetBlock (const TMVB& A, const Teuchos::Range1D& index, TMVB& mv)
440  {
441  const int numColsA = A.domain()->dim();
442  const int numColsMv = mv.domain()->dim();
443  // 'index' indexes into mv; it's the index set of the target.
444  const bool validIndex = index.lbound() >= 0 && index.ubound() < numColsMv;
445  // We can't take more columns out of A than A has.
446  const bool validSource = index.size() <= numColsA;
447 
448  if (! validIndex || ! validSource)
449  {
450  std::ostringstream os;
451  os << "Belos::MultiVecTraits<Scalar, Thyra::MultiVectorBase<Scalar> "
452  ">::SetBlock(A, [" << index.lbound() << ", " << index.ubound()
453  << "], mv): ";
454  TEUCHOS_TEST_FOR_EXCEPTION(index.lbound() < 0, std::invalid_argument,
455  os.str() << "Range lower bound must be nonnegative.");
456  TEUCHOS_TEST_FOR_EXCEPTION(index.ubound() >= numColsMv, std::invalid_argument,
457  os.str() << "Range upper bound must be less than "
458  "the number of columns " << numColsA << " in the "
459  "'mv' output argument.");
460  TEUCHOS_TEST_FOR_EXCEPTION(index.size() > numColsA, std::invalid_argument,
461  os.str() << "Range must have no more elements than"
462  " the number of columns " << numColsA << " in the "
463  "'A' input argument.");
464  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Should never get here!");
465  }
466 
467  // View of the relevant column(s) of the target multivector mv.
468  // We avoid view creation overhead by only creating a view if
469  // the index range is different than [0, (# columns in mv) - 1].
470  Teuchos::RCP<TMVB> mv_view;
471  if (index.lbound() == 0 && index.ubound()+1 == numColsMv)
472  mv_view = Teuchos::rcpFromRef (mv); // Non-const, non-owning RCP
473  else
474  mv_view = mv.subView (index);
475 
476  // View of the relevant column(s) of the source multivector A.
477  // If A has fewer columns than mv_view, then create a view of
478  // the first index.size() columns of A.
480  if (index.size() == numColsA)
481  A_view = Teuchos::rcpFromRef (A); // Const, non-owning RCP
482  else
483  A_view = A.subView (Teuchos::Range1D(0, index.size()-1));
484 
485  // Copy the data to the destination multivector.
486  Thyra::assign(mv_view.ptr(), *A_view);
487  }
488 
489  static void
490  Assign (const TMVB& A, TMVB& mv)
491  {
492  STRATIMIKOS_TIME_MONITOR("Belos::MVT::Assign");
493 
494  const int numColsA = A.domain()->dim();
495  const int numColsMv = mv.domain()->dim();
496  if (numColsA > numColsMv)
497  {
498  std::ostringstream os;
499  os << "Belos::MultiVecTraits<Scalar, Thyra::MultiVectorBase<Scalar>"
500  " >::Assign(A, mv): ";
501  TEUCHOS_TEST_FOR_EXCEPTION(numColsA > numColsMv, std::invalid_argument,
502  os.str() << "Input multivector 'A' has "
503  << numColsA << " columns, but output multivector "
504  "'mv' has only " << numColsMv << " columns.");
505  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Should never get here!");
506  }
507  // Copy the data to the destination multivector.
508  if (numColsA == numColsMv) {
509  Thyra::assign (Teuchos::outArg (mv), A);
510  } else {
511  Teuchos::RCP<TMVB> mv_view =
512  CloneViewNonConst (mv, Teuchos::Range1D(0, numColsA-1));
513  Thyra::assign (mv_view.ptr(), A);
514  }
515  }
516 
519  static void MvRandom( TMVB& mv )
520  {
521  // Thyra::randomize generates via a uniform distribution on [l,u]
522  // We will use this to generate on [-1,1]
523  Thyra::randomize<ScalarType>(
526  Teuchos::outArg(mv));
527  }
528 
530  static void
531  MvInit (TMVB& mv, ScalarType alpha = Teuchos::ScalarTraits<ScalarType>::zero())
532  {
533  Thyra::assign (Teuchos::outArg (mv), alpha);
534  }
535 
537 
540 
543  static void MvPrint( const TMVB& mv, std::ostream& os )
544  { os << describe(mv,Teuchos::VERB_EXTREME); }
545 
547 
548 #ifdef HAVE_BELOS_TSQR
549  typedef Thyra::TsqrAdaptor< ScalarType > tsqr_adaptor_type;
555 #endif // HAVE_BELOS_TSQR
556  };
557 
559  //
560  // Implementation of the Belos::OperatorTraits for Thyra::LinearOpBase
561  //
563 
571  template<class ScalarType>
572  class OperatorTraits <ScalarType,
573  Thyra::MultiVectorBase<ScalarType>,
574  Thyra::LinearOpBase<ScalarType> >
575  {
576  private:
577  typedef Thyra::MultiVectorBase<ScalarType> TMVB;
578  typedef Thyra::LinearOpBase<ScalarType> TLOB;
579 
580  public:
596  static void
597  Apply (const TLOB& Op,
598  const TMVB& x,
599  TMVB& y,
600  ETrans trans = NOTRANS)
601  {
602  Thyra::EOpTransp whichOp;
603 
604  // We don't check here whether the operator implements the
605  // requested operation. Call HasApplyTranspose() to check.
606  // Thyra::LinearOpBase implementations are not required to
607  // implement NOTRANS. However, Belos needs NOTRANS
608  // (obviously!), so we assume that Op implements NOTRANS.
609  if (trans == NOTRANS)
610  whichOp = Thyra::NOTRANS;
611  else if (trans == TRANS)
612  whichOp = Thyra::TRANS;
613  else if (trans == CONJTRANS)
614  whichOp = Thyra::CONJTRANS;
615  else
616  TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument,
617  "Belos::OperatorTraits::Apply (Thyra specialization): "
618  "'trans' argument must be neither NOTRANS=" << NOTRANS
619  << ", TRANS=" << TRANS << ", or CONJTRANS=" << CONJTRANS
620  << ", but instead has an invalid value of " << trans << ".");
621  Thyra::apply<ScalarType>(Op, whichOp, x, Teuchos::outArg(y));
622  }
623 
625  static bool HasApplyTranspose (const TLOB& Op)
626  {
628 
629  // Thyra::LinearOpBase's interface lets you check whether the
630  // operator implements any of all four possible combinations of
631  // conjugation and transpose. Belos only needs transpose
632  // (TRANS) if the operator is real; in that case, Apply() does
633  // the same thing with trans = CONJTRANS or TRANS. If the
634  // operator is complex, Belos needs both transpose and conjugate
635  // transpose (CONJTRANS) if the operator is complex.
636  return Op.opSupported (Thyra::TRANS) &&
637  (! STS::isComplex || Op.opSupported (Thyra::CONJTRANS));
638  }
639  };
640 
641 } // end of Belos namespace
642 
643 #endif
644 // end of file BELOS_THYRA_ADAPTER_HPP
static int GetNumberVecs(const TMVB &mv)
Obtain the number of vectors in mv.
static ptrdiff_t GetGlobalLength(const TMVB &mv)
Obtain the std::vector length of mv.
static void MvPrint(const TMVB &mv, std::ostream &os)
Print the mv multi-std::vector to the os output stream.
Stub adaptor from Thyra::MultiVectorBase to TSQR.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
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 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 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...
Ordinal ubound() const
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 void MvScale(TMVB &mv, const ScalarType alpha)
Scale each element of the vectors in *this with alpha.
static void MvTimesMatAddMv(const ScalarType alpha, const TMVB &A, const Teuchos::SerialDenseMatrix< int, ScalarType > &B, const ScalarType beta, TMVB &mv)
Update mv with .
Ptr< T > ptr() const
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 Teuchos::RCP< TMVB > CloneCopy(const TMVB &mv, const Teuchos::Range1D &index)
static void Apply(const TLOB &Op, const TMVB &x, TMVB &y, ETrans trans=NOTRANS)
Apply Op to x, storing the result in y.
static void MvRandom(TMVB &mv)
Replace the vectors in mv with random vectors.
static Teuchos::RCP< TMVB > CloneViewNonConst(TMVB &mv, const Teuchos::Range1D &index)
Ordinal lbound() const
OrdinalType numCols() const
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 SetBlock(const TMVB &A, const Teuchos::Range1D &index, TMVB &mv)
Ordinal size() const
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 bool HasApplyTranspose(const TLOB &Op)
Whether the operator implements applying the transpose.
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< const TMVB > CloneView(const TMVB &mv, const Teuchos::Range1D &index)
int n
OrdinalType stride() const
static Teuchos::RCP< TMVB > Clone(const TMVB &mv, const int numvecs)
Creates a new empty MultiVectorBase containing numvecs columns.
static void MvAddMv(const ScalarType alpha, const TMVB &A, const ScalarType beta, const TMVB &B, TMVB &mv)
Replace mv with .
OrdinalType numRows() const
#define STRATIMIKOS_TIME_MONITOR(NAME)