Thyra Version of the Day
Loading...
Searching...
No Matches
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
24namespace Thyra {
25
26
27// Constructors/Initializers
28
29
30template<class Scalar>
33
34
35template<class Scalar>
37 const RCP<VectorBase<Scalar> > &col_vec
38 )
39{
40 this->initialize(col_vec);
41}
42
43
44template<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
55template<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
73template<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
105template<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
117template<class Scalar>
120{
121 return range_;
122}
123
124
125template<class Scalar>
128{
129 return domain_;
130}
131
132
133// Overridden protected functions from MultiVectorBase
134
135
136template<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
146template<class Scalar>
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
161template<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
170template<class Scalar>
172 Scalar alpha,
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
186template<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
212template<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
229template<class Scalar>
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
243template<class Scalar>
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
257template<class Scalar>
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
275template<class Scalar>
277{
279 return ( ST::isComplex ? ( M_trans==NOTRANS || M_trans==CONJTRANS ) : true );
280}
281
282
283template<class Scalar>
285 const EOpTransp M_trans,
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
340template<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
354template<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
size_type size() const
Ptr< T > ptr() const
Ordinal size() const
Ordinal lbound() const
Ordinal ubound() const
Default subclass for MultiVectorBase implemented using columns of separate abstract vectors.
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 assignMultiVecImpl(const MultiVectorBase< Scalar > &mv)
RCP< MultiVectorBase< Scalar > > nonconstContigSubViewImpl(const Range1D &col_rng)
virtual void linearCombinationImpl(const ArrayView< const Scalar > &alpha, const ArrayView< const Ptr< const MultiVectorBase< Scalar > > > &mv, const Scalar &beta)
virtual void updateImpl(Scalar alpha, const MultiVectorBase< Scalar > &mv)
virtual void dotsImpl(const MultiVectorBase< Scalar > &mv, const ArrayView< Scalar > &prods) const
virtual void norms2Impl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
virtual void normsInfImpl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
virtual void norms1Impl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
RCP< const VectorSpaceBase< Scalar > > domain() const
void initialize(const RCP< VectorBase< Scalar > > &col_vec)
Initialize given a single vector object.
RCP< const VectorSpaceBase< Scalar > > range() const
bool opSupportedImpl(EOpTransp M_trans) const
For complex Scalar types returns true for NOTRANS and CONJTRANS and for real types returns true for a...
virtual RCP< const VectorSpaceBase< Scalar > > range() const =0
Return a smart pointer for the range space for this operator.
virtual RCP< const VectorSpaceBase< Scalar > > domain() const =0
Return a smart pointer for the domain space for this operator.
Interface for a collection of column vectors called a multi-vector.
RCP< const VectorBase< Scalar > > col(Ordinal j) const
Calls colImpl().
Abstract interface for finite-dimensional dense vectors.
Abstract interface for objects that represent a space for vectors.
#define TEUCHOS_ASSERT(assertion_test)
#define TEUCHOS_TEST_FOR_EXCEPT_MSG(throw_exception_test, msg)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
#define TEUCHOS_ASSERT_EQUALITY(val1, val2)
#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...
EOpTransp
Enumeration for determining how a linear operator is applied. `*.
Teuchos::Ordinal Ordinal
Type for the dimension of a vector space. `*.
Teuchos::Range1D Range1D
@ NOTRANS
Use the non-transposed operator.
@ CONJTRANS
Use the transposed operator with complex-conjugate clements (same as TRANS for real scalar types).
TypeTo as(const TypeFrom &t)
T_To & dyn_cast(T_From &from)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)