Thyra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Thyra_DefaultColumnwiseMultiVector_def.hpp
1 // @HEADER
2 // *****************************************************************************
3 // Thyra: Interfaces and Support for Abstract Numerical Algorithms
4 //
5 // Copyright 2004 NTESS and the Thyra contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef THYRA_DEFAULT_COLUMNWISE_MULTI_VECTOR_DEF_HPP
11 #define THYRA_DEFAULT_COLUMNWISE_MULTI_VECTOR_DEF_HPP
12 
13 #include "Thyra_DefaultColumnwiseMultiVector_decl.hpp"
14 #include "Thyra_MultiVectorDefaultBase.hpp"
15 #include "Thyra_VectorSpaceBase.hpp"
16 #include "Thyra_VectorBase.hpp"
17 #include "Thyra_MultiVectorBase.hpp"
18 #include "Thyra_VectorStdOps.hpp"
19 #include "Thyra_VectorSpaceFactoryBase.hpp"
20 #include "Thyra_AssertOp.hpp"
21 #include "Teuchos_Assert.hpp"
22 #include "Teuchos_as.hpp"
23 
24 namespace Thyra {
25 
26 
27 // Constructors/Initializers
28 
29 
30 template<class Scalar>
32 {}
33 
34 
35 template<class Scalar>
37  const RCP<VectorBase<Scalar> > &col_vec
38  )
39 {
40  this->initialize(col_vec);
41 }
42 
43 
44 template<class Scalar>
46  const RCP<const VectorSpaceBase<Scalar> > &range_in,
47  const RCP<const VectorSpaceBase<Scalar> > &domain_in,
48  const ArrayView<const RCP<VectorBase<Scalar> > > &col_vecs_in
49  )
50 {
51  this->initialize(range_in, domain_in, col_vecs_in);
52 }
53 
54 
55 template<class Scalar>
57  const RCP<VectorBase<Scalar> > &col_vec
58  )
59 {
60 #ifdef TEUCHOS_DEBUG
61  const std::string err_msg =
62  "DefaultColumnwiseMultiVector<Scalar>::initialize(...): Error!";
63  TEUCHOS_TEST_FOR_EXCEPT_MSG( is_null(col_vec), err_msg );
64  TEUCHOS_TEST_FOR_EXCEPT_MSG( is_null(col_vec->space()), err_msg );
65 #endif
66  range_ = col_vec->space();
67  domain_ = range_->smallVecSpcFcty()->createVecSpc(1);
68  col_vecs_.resize(1);
69  col_vecs_[0] = col_vec;
70 }
71 
72 
73 template<class Scalar>
75  const RCP<const VectorSpaceBase<Scalar> > &range_in,
76  const RCP<const VectorSpaceBase<Scalar> > &domain_in,
77  const ArrayView<const RCP<VectorBase<Scalar> > > &col_vecs
78  )
79 {
80 #ifdef TEUCHOS_DEBUG
81  const std::string err_msg =
82  "DefaultColumnwiseMultiVector<Scalar>::initialize(...): Error!";
83  TEUCHOS_TEST_FOR_EXCEPT_MSG( is_null(range_in), err_msg );
84  TEUCHOS_TEST_FOR_EXCEPT_MSG( is_null(domain_in), err_msg );
85  TEUCHOS_TEST_FOR_EXCEPT_MSG( range_in->dim() == 0, err_msg );
86  TEUCHOS_TEST_FOR_EXCEPT_MSG( domain_in->dim() == 0, err_msg );
87  // ToDo: Check the compatibility of the vectors in col_vecs!
88 #endif
89  const int domainDim = domain_in->dim();
90  range_ = range_in;
91  domain_ = domain_in;
92  col_vecs_.clear();
93  col_vecs_.reserve(domainDim);
94  if (col_vecs.size()) {
95  for( Ordinal j = 0; j < domainDim; ++j )
96  col_vecs_.push_back(col_vecs[j]);
97  }
98  else {
99  for( Ordinal j = 0; j < domainDim; ++j )
100  col_vecs_.push_back(createMember(range_));
101  }
102 }
103 
104 
105 template<class Scalar>
107 {
108  col_vecs_.resize(0);
109  range_ = Teuchos::null;
110  domain_ = Teuchos::null;
111 }
112 
113 
114 // Overridden from OpBase
115 
116 
117 template<class Scalar>
120 {
121  return range_;
122 }
123 
124 
125 template<class Scalar>
128 {
129  return domain_;
130 }
131 
132 
133 // Overridden protected functions from MultiVectorBase
134 
135 
136 template<class Scalar>
138 {
139  const Ordinal m = col_vecs_.size();
140  for (Ordinal col_j = 0; col_j < m; ++col_j) {
141  col_vecs_[col_j]->assign(alpha);
142  }
143 }
144 
145 
146 template<class Scalar>
148  const MultiVectorBase<Scalar>& mv
149  )
150 {
151 #ifdef TEUCHOS_DEBUG
152  TEUCHOS_ASSERT_EQUALITY(col_vecs_.size(), mv.domain()->dim());
153  TEUCHOS_ASSERT(range_->isCompatible(*mv.range()));
154 #endif
155  for (Ordinal col_j = 0; col_j < col_vecs_.size(); ++col_j) {
156  col_vecs_[col_j]->assign(*mv.col(col_j));
157  }
158 }
159 
160 
161 template<class Scalar>
163 {
164  for (Ordinal col_j = 0; col_j < col_vecs_.size(); ++col_j) {
165  col_vecs_[col_j]->scale(alpha);
166  }
167 }
168 
169 
170 template<class Scalar>
172  Scalar alpha,
173  const MultiVectorBase<Scalar>& mv
174  )
175 {
176 #ifdef TEUCHOS_DEBUG
177  TEUCHOS_ASSERT_EQUALITY(col_vecs_.size(), mv.domain()->dim());
178  TEUCHOS_ASSERT(range_->isCompatible(*mv.range()));
179 #endif
180  for (Ordinal col_j = 0; col_j < col_vecs_.size(); ++col_j) {
181  col_vecs_[col_j]->update(alpha, *mv.col(col_j));
182  }
183 }
184 
185 
186 template<class Scalar>
188  const ArrayView<const Scalar>& alpha,
189  const ArrayView<const Ptr<const MultiVectorBase<Scalar> > >& mv,
190  const Scalar& beta
191  )
192 {
193 #ifdef TEUCHOS_DEBUG
194  TEUCHOS_ASSERT_EQUALITY(alpha.size(), mv.size());
195  for (Ordinal i = 0; i < mv.size(); ++i) {
196  TEUCHOS_ASSERT_EQUALITY(col_vecs_.size(), mv[i]->domain()->dim());
197  TEUCHOS_ASSERT(range_->isCompatible(*mv[i]->range()));
198  }
199 #endif
200  Array<RCP<const VectorBase<Scalar> > > v_rcp(mv.size());
201  Array<Ptr<const VectorBase<Scalar> > > v(mv.size());
202  for (Ordinal col_j = 0; col_j < col_vecs_.size(); ++col_j) {
203  for (Ordinal i = 0; i < mv.size(); ++i) {
204  v_rcp[i] = mv[i]->col(col_j);
205  v[i] = v_rcp[i].ptr();
206  }
207  col_vecs_[col_j]->linear_combination(alpha, v(), beta);
208  }
209 }
210 
211 
212 template<class Scalar>
214  const MultiVectorBase<Scalar>& mv,
215  const ArrayView<Scalar>& prods
216  ) const
217 {
218 #ifdef TEUCHOS_DEBUG
219  TEUCHOS_ASSERT_EQUALITY(col_vecs_.size(), mv.domain()->dim());
220  TEUCHOS_ASSERT_EQUALITY(col_vecs_.size(), prods.size());
221  TEUCHOS_ASSERT(range_->isCompatible(*mv.range()));
222 #endif
223  for (Ordinal col_j = 0; col_j < col_vecs_.size(); ++col_j) {
224  prods[col_j] = col_vecs_[col_j]->dot(*mv.col(col_j));
225  }
226 }
227 
228 
229 template<class Scalar>
231  const ArrayView<typename ScalarTraits<Scalar>::magnitudeType>& norms
232  ) const
233 {
234 #ifdef TEUCHOS_DEBUG
235  TEUCHOS_ASSERT_EQUALITY(col_vecs_.size(), norms.size());
236 #endif
237  for (Ordinal col_j = 0; col_j < col_vecs_.size(); ++col_j) {
238  norms[col_j] = col_vecs_[col_j]->norm_1();
239  }
240 }
241 
242 
243 template<class Scalar>
245  const ArrayView<typename ScalarTraits<Scalar>::magnitudeType>& norms
246  ) const
247 {
248 #ifdef TEUCHOS_DEBUG
249  TEUCHOS_ASSERT_EQUALITY(col_vecs_.size(), norms.size());
250 #endif
251  for (Ordinal col_j = 0; col_j < col_vecs_.size(); ++col_j) {
252  norms[col_j] = col_vecs_[col_j]->norm_2();
253  }
254 }
255 
256 
257 template<class Scalar>
259  const ArrayView<typename ScalarTraits<Scalar>::magnitudeType>& norms
260  ) const
261 {
262 #ifdef TEUCHOS_DEBUG
263  TEUCHOS_ASSERT_EQUALITY(col_vecs_.size(), norms.size());
264 #endif
265  for (Ordinal col_j = 0; col_j < col_vecs_.size(); ++col_j) {
266  norms[col_j] = col_vecs_[col_j]->norm_inf();
267  }
268 }
269 
270 
271 // Overridden protected functions from LinearOpBase
272 
273 
274 
275 template<class Scalar>
277 {
279  return ( ST::isComplex ? ( M_trans==NOTRANS || M_trans==CONJTRANS ) : true );
280 }
281 
282 
283 template<class Scalar>
285  const EOpTransp M_trans,
286  const MultiVectorBase<Scalar> &X,
287  const Ptr<MultiVectorBase<Scalar> > &Y,
288  const Scalar alpha,
289  const Scalar beta
290  ) const
291 {
292 #ifdef TEUCHOS_DEBUG
294  "MultiVectorBase<Scalar>::apply()", *this, M_trans, X, &*Y);
295 #endif
296  const Ordinal nc = this->domain()->dim();
297  const Ordinal m = X.domain()->dim();
298  for (Ordinal col_j = 0; col_j < m; ++col_j) {
299  const RCP<const VectorBase<Scalar> > x_j = X.col(col_j);
300  const RCP<VectorBase<Scalar> > y_j = Y->col(col_j);
301  // y_j *= beta
302  Vt_S(y_j.ptr(), beta);
303  // y_j += alpha*op(M)*x_j
304  if(M_trans == NOTRANS) {
305  //
306  // y_j += alpha*M*x_j = alpha*M.col(0)*x_j(0) + ... + alpha*M.col(nc-1)*x_j(nc-1)
307  //
308  // Extract an explicit view of x_j
310  x_j->acquireDetachedView(Range1D(), &x_sub_vec);
311  // Loop through and add the multiple of each column
312  for (Ordinal j = 0; j < nc; ++j )
313  Vp_StV( y_j.ptr(), Scalar(alpha*x_sub_vec(j)), *this->col(j) );
314  // Release the view of x
315  x_j->releaseDetachedView(&x_sub_vec);
316  }
317  else {
318  //
319  // [ alpha*dot(M.col(0),x_j) ]
320  // y_j += alpha*M^T*x_j = [ alpha*dot(M.col(1),x_j) ]
321  // [ ... ]
322  // [ alpha*dot(M.col(nc-1),x_j) ]
323  //
324  // Extract an explicit view of y_j
326  y_j->acquireDetachedView(Range1D(), &y_sub_vec);
327  // Loop through and add to each element in y_j
328  for (Ordinal j = 0; j < nc; ++j )
329  y_sub_vec(j) += alpha*dot(*this->col(j), *x_j);
330  // Commit explicit view of y
331  y_j->commitDetachedView(&y_sub_vec);
332  }
333  }
334 }
335 
336 
337 // Overridden from MultiVectorBase
338 
339 
340 template<class Scalar>
343 {
344  using Teuchos::as;
345  const int num_cols = col_vecs_.size();
347  !( 0 <= j && j < num_cols ), std::logic_error
348  ,"Error, j = " << j << " does not fall in the range [0,"<<(num_cols-1)<< "]!"
349  );
350  return col_vecs_[j];
351 }
352 
353 
354 template<class Scalar>
357  const Range1D& col_rng_in
358  )
359 {
360  const Ordinal numCols = domain_->dim();
361  const Range1D col_rng = Teuchos::full_range(col_rng_in,0,numCols-1);
362 #ifdef TEUCHOS_DEBUG
364  !( col_rng.ubound() < numCols ), std::logic_error
365  ,"DefaultColumnwiseMultiVector<Scalar>::subView(col_rng):"
366  "Error, the input range col_rng = ["<<col_rng.lbound()
367  <<","<<col_rng.ubound()<<"] "
368  "is not in the range [0,"<<(numCols-1)<<"]!"
369  );
370 #endif
371  return Teuchos::rcp(
373  range_,
374  domain_->smallVecSpcFcty()->createVecSpc(col_rng.size()),
375  col_vecs_(col_rng.lbound(),col_rng.size())
376  )
377  );
378 }
379 
380 
381 } // end namespace Thyra
382 
383 
384 #endif // THYRA_DEFAULT_COLUMNWISE_MULTI_VECTOR_DEF_HPP
void initialize(int *argc, char ***argv)
virtual void assignMultiVecImpl(const MultiVectorBase< Scalar > &mv)
virtual void updateImpl(Scalar alpha, const MultiVectorBase< Scalar > &mv)
RCP< const VectorSpaceBase< Scalar > > range() const
bool is_null(const boost::shared_ptr< T > &p)
virtual RCP< const VectorSpaceBase< Scalar > > range() const =0
Return a smart pointer for the range space for this operator.
EOpTransp
Enumeration for determining how a linear operator is applied. `*.
virtual void norms1Impl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
#define THYRA_ASSERT_LINEAR_OP_MULTIVEC_APPLY_SPACES(FUNC_NAME, M, M_T, X, Y)
This is a very useful macro that should be used to validate that the spaces for the multi-vector vers...
void applyImpl(const EOpTransp M_trans, const MultiVectorBase< Scalar > &X, const Ptr< MultiVectorBase< Scalar > > &Y, const Scalar alpha, const Scalar beta) const
This function is implemented in terms of the multi-vector applyOp() function.
virtual void norms2Impl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Use the non-transposed operator.
size_type size() const
Use the transposed operator with complex-conjugate clements (same as TRANS for real scalar types)...
Abstract interface for objects that represent a space for vectors.
virtual void linearCombinationImpl(const ArrayView< const Scalar > &alpha, const ArrayView< const Ptr< const MultiVectorBase< Scalar > > > &mv, const Scalar &beta)
Ordinal ubound() const
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Teuchos::Ordinal Ordinal
Type for the dimension of a vector space. `*.
#define TEUCHOS_TEST_FOR_EXCEPT_MSG(throw_exception_test, msg)
Interface for a collection of column vectors called a multi-vector.
Ptr< T > ptr() const
RCP< const VectorBase< Scalar > > col(Ordinal j) const
Calls colImpl().
RCP< VectorBase< Scalar > > nonconstColImpl(Ordinal j)
Abstract interface for finite-dimensional dense vectors.
void initialize(const RCP< VectorBase< Scalar > > &col_vec)
Initialize given a single vector object.
Default subclass for MultiVectorBase implemented using columns of separate abstract vectors...
virtual void normsInfImpl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
RCP< MultiVectorBase< Scalar > > nonconstContigSubViewImpl(const Range1D &col_rng)
bool opSupportedImpl(EOpTransp M_trans) const
For complex Scalar types returns true for NOTRANS and CONJTRANS and for real types returns true for a...
Ordinal lbound() const
virtual RCP< const VectorSpaceBase< Scalar > > domain() const =0
Return a smart pointer for the domain space for this operator.
RCP< const VectorSpaceBase< Scalar > > domain() const
Ordinal size() const
TypeTo as(const TypeFrom &t)
#define TEUCHOS_ASSERT(assertion_test)
#define TEUCHOS_ASSERT_EQUALITY(val1, val2)
virtual void dotsImpl(const MultiVectorBase< Scalar > &mv, const ArrayView< Scalar > &prods) const
Teuchos::Range1D Range1D