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 "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 
68 namespace 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;
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 
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>
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 
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 
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,
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!
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,
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!
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.
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>(
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
533  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  {
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 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 RCP< Time > getNewTimer(const std::string &name)
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