MOOCHO (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AbstractLinAlgPack_MultiVector.cpp
Go to the documentation of this file.
1 /*
2 // @HEADER
3 // ***********************************************************************
4 //
5 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization
6 // Copyright (2003) Sandia Corporation
7 //
8 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
9 // license for use of this work by or on behalf of the U.S. Government.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov)
39 //
40 // ***********************************************************************
41 // @HEADER
42 */
43 
44 // /////////////////////////////////////////////////////////////////////////
45 // MultiVector.cpp
46 
47 #include <assert.h>
48 
54 #include "Teuchos_Workspace.hpp"
55 #include "Teuchos_Assert.hpp"
56 
57 namespace {
58 
59 // Map from EApplyBy to Transp
60 inline
62 to_trans(AbstractLinAlgPack::EApplyBy apply_by)
63 {
64  return ( apply_by == AbstractLinAlgPack::APPLY_BY_ROW
67  );
68 }
69 
70 // Return a row or a column vector from a multi-vector
71 
72 inline
74 vec(
75  const AbstractLinAlgPack::MultiVector& multi_vec
78  )
79 {
80  return ( apply_by == AbstractLinAlgPack::APPLY_BY_ROW
81  ? multi_vec.row(k)
82  : multi_vec.col(k)
83  );
84 }
85 
86 inline
88 vec(
92  )
93 {
94  return ( apply_by == AbstractLinAlgPack::APPLY_BY_ROW
95  ? multi_vec->row(k)
96  : multi_vec->col(k)
97  );
98 }
99 
100 // Implement a matrix-matrix multiplication with a diagonal matrix.
101 //
102 // op(C) = b*op(C) + a*D*op(B)
103 //
104 bool mat_vec(
106  ,const AbstractLinAlgPack::MatrixOp &D_mwo // Diagonal matrix?
107  ,BLAS_Cpp::Transp D_trans
109  ,BLAS_Cpp::Transp B_trans
111  ,BLAS_Cpp::Transp C_trans
113  )
114 {
115  using BLAS_Cpp::no_trans;
116  using BLAS_Cpp::trans;
117 
126  using LinAlgOpPack::Vt_S;
127 
128  AbstractLinAlgPack::Mp_MtM_assert_compatibility(C,C_trans,D_mwo,D_trans,B,B_trans);
129 
130  MultiVectorMutable
131  *Cmv = dynamic_cast<MultiVectorMutable*>(C);
132  const MatrixSymDiag
133  *D = dynamic_cast<const MatrixSymDiag*>(&D_mwo);
134  if( !Cmv || !D || !(Cmv->access_by() & ( C_trans == no_trans ? MV::COL_ACCESS : MV::ROW_ACCESS ))
135  || !(B.access_by() & ( B_trans == no_trans ? MV::COL_ACCESS : MV::ROW_ACCESS ))
136  )
137  {
138  return false;
139  }
140  //
141  // op(C).col(j) = b*op(C).col(j) + a*ele_wise_prod(D_diag,op(B).col(j)), for j = 1...op(C).cols()
142  //
143  const Vector &D_diag = D->diag();
144  const size_type
145  opC_cols = BLAS_Cpp::cols( Cmv->rows(), Cmv->cols(), C_trans );
146  for( size_type j = 1; j <= opC_cols; ++j ) {
147  MV::vec_ptr_t
148  opB_col_j = ( B_trans == no_trans ? B.col(j) : B.row(j) );
149  MVM::vec_mut_ptr_t
150  opC_col_j = ( C_trans == no_trans ? Cmv->col(j) : Cmv->row(j) );
151  Vt_S( opC_col_j.get(), b );
152  ele_wise_prod( a, D_diag, *opB_col_j, opC_col_j.get() );
153  }
154  return true;
155 }
156 
157 } // end namespace
158 
159 namespace AbstractLinAlgPack {
160 
163 {
164  return Teuchos::null;
165 }
166 
168 MultiVector::mv_sub_view(const Range1D& row_rng, const Range1D& col_rng) const
169 {
170  TEUCHOS_TEST_FOR_EXCEPT(true); // ToDo: return a MultiVectorSubView object.
171  // Note that the MultiVectorSubView class should derive from MatrixOpSubView
172  // so that a client can rely on the MatrixOpSubView interface.
173  return Teuchos::null;
174 }
175 
177  EApplyBy apply_by, const RTOpPack::RTOp& prim_op
178  ,const size_t num_multi_vecs, const MultiVector* multi_vecs[]
179  ,const size_t num_targ_multi_vecs, MultiVectorMutable* targ_multi_vecs[]
180  ,RTOpPack::ReductTarget* reduct_objs[]
181  ,const index_type prim_first_ele_in, const index_type prim_sub_dim_in, const index_type prim_global_offset_in
182  ,const index_type sec_first_ele_in, const index_type sec_sub_dim_in
183  ) const
184 {
185  using Teuchos::Workspace;
187 
188  // ToDo: Validate the input!
189 
190  // Get the primary and secondary dimmensions.
191  const index_type
192  prim_dim = ( apply_by == APPLY_BY_ROW ? rows() : cols() ),
193  sec_dim = ( apply_by == APPLY_BY_ROW ? cols() : rows() ),
194  prim_sub_dim = ( prim_sub_dim_in != 0 ? prim_sub_dim_in : prim_dim ),
195  sec_sub_dim = ( sec_sub_dim_in != 0 ? sec_sub_dim_in : sec_dim );
196  TEUCHOS_TEST_FOR_EXCEPT( !( 0 < prim_sub_dim && prim_sub_dim <= prim_dim ) );
197  TEUCHOS_TEST_FOR_EXCEPT( !( 0 < sec_sub_dim && sec_sub_dim <= sec_dim ) );
198 
199  //
200  // Apply the reduction/transformation operator and trnasform the target
201  // vectors and reduce each of the reduction objects.
202  //
203 
204  Workspace<MultiVector::vec_ptr_t> vecs_s(wss,num_multi_vecs);
205  Workspace<const Vector*> vecs(wss,num_multi_vecs);
206  Workspace<MultiVectorMutable::vec_mut_ptr_t> targ_vecs_s(wss,num_targ_multi_vecs);
207  Workspace<VectorMutable*> targ_vecs(wss,num_targ_multi_vecs);
208 
209  {for(size_type j = sec_first_ele_in; j <= sec_first_ele_in - 1 + sec_sub_dim; ++j) {
210  // Fill the arrays of vector arguments
211  {for(size_type k = 0; k < num_multi_vecs; ++k) {
212  vecs_s[k] = vec( *multi_vecs[k], j, apply_by );
213  vecs[k] = vecs_s[k].get();
214  }}
215  {for(size_type k = 0; k < num_targ_multi_vecs; ++k) {
216  targ_vecs_s[k] = vec( targ_multi_vecs[k], j, apply_by );
217  targ_vecs[k] = targ_vecs_s[k].get();
218  }}
219  // Apply the reduction/transformation operator
221  prim_op
222  ,num_multi_vecs, num_multi_vecs ? &vecs[0] : NULL
223  ,num_targ_multi_vecs, num_targ_multi_vecs ? &targ_vecs[0] : NULL
224  ,reduct_objs ? reduct_objs[j-1] : NULL
225  ,prim_first_ele_in, prim_sub_dim_in, prim_global_offset_in
226  );
227  }}
228 
229  // At this point all of the designated targ vectors in the target multi-vectors have
230  // been transformed and all the reduction objects in reduct_obj[] have accumulated
231  // the reductions.
232 
233 }
234 
236  EApplyBy apply_by, const RTOpPack::RTOp& prim_op, const RTOpPack::RTOp& sec_op
237  ,const size_t num_multi_vecs, const MultiVector* multi_vecs[]
238  ,const size_t num_targ_multi_vecs, MultiVectorMutable* targ_multi_vecs[]
239  ,RTOpPack::ReductTarget *reduct_obj
240  ,const index_type prim_first_ele_in, const index_type prim_sub_dim_in, const index_type prim_global_offset_in
241  ,const index_type sec_first_ele_in, const index_type sec_sub_dim_in
242  ) const
243 {
244  using Teuchos::Workspace;
246 
247  // ToDo: Validate the input!
248 
249  // Get the primary and secondary dimmensions.
250  const index_type
251  prim_dim = ( apply_by == APPLY_BY_ROW ? rows() : cols() ),
252  sec_dim = ( apply_by == APPLY_BY_ROW ? cols() : rows() ),
253  sec_sub_dim = ( sec_sub_dim_in != 0 ? sec_sub_dim_in : sec_dim );
254  TEUCHOS_TEST_FOR_EXCEPT( !( 0 < sec_sub_dim && sec_sub_dim <= sec_dim ) );
255 
256  // Create a temporary buffer for the reduction objects of the primary reduction
257  // so that we can call the companion version of this method.
258  Workspace<Teuchos::RCP<RTOpPack::ReductTarget> > rcp_reduct_objs(wss,sec_sub_dim);
259  Workspace<RTOpPack::ReductTarget*> reduct_objs(wss,sec_sub_dim);
260  for(index_type k = 0; k < sec_sub_dim; ++k) {
261  rcp_reduct_objs[k] = prim_op.reduct_obj_create();
262  reduct_objs[k] = &*rcp_reduct_objs[k];
263  }
264 
265  // Call the campanion version that accepts an array of reduction objects
266  this->apply_op(
267  apply_by, prim_op
268  ,num_multi_vecs, multi_vecs
269  ,num_targ_multi_vecs, targ_multi_vecs
270  ,&reduct_objs[0]
271  ,prim_first_ele_in, prim_sub_dim_in, prim_global_offset_in
272  ,sec_first_ele_in, sec_sub_dim_in
273  );
274 
275  // Reduce all the reduction objects using the secondary reduction operator
276  // into one reduction object and free the intermedate reduction objects.
277  for(index_type k = 0; k < sec_sub_dim; ++k) {
278  sec_op.reduce_reduct_objs( *reduct_objs[k], Teuchos::ptr(reduct_obj) );
279  }
280 }
281 
282 // Overridden form MatrixOp
283 
284 MatrixOp::mat_ptr_t
286 {
287  return this->mv_clone();
288 }
289 
290 MatrixOp::mat_ptr_t
291 MultiVector::sub_view(const Range1D& row_rng, const Range1D& col_rng) const
292 {
293  return mv_sub_view(row_rng,col_rng);
294 }
295 
297  MatrixOp* mwo_lhs, value_type alpha
298  ,const MatrixOp& mwo_rhs1, BLAS_Cpp::Transp trans_rhs1
299  ,BLAS_Cpp::Transp trans_rhs2
300  ,value_type beta
301  ) const
302 {
303  return mat_vec(
304  alpha
305  ,mwo_rhs1,trans_rhs1
306  ,*this,trans_rhs2
307  ,beta,BLAS_Cpp::no_trans,mwo_lhs
308  );
309 }
310 
312  MatrixOp* mwo_lhs, value_type alpha
313  ,BLAS_Cpp::Transp trans_rhs1
314  ,const MatrixOp& mwo_rhs2, BLAS_Cpp::Transp trans_rhs2
315  ,value_type beta
316  ) const
317 {
318  return mat_vec(
319  alpha
320  ,mwo_rhs2,BLAS_Cpp::trans_not(trans_rhs2)
321  ,*this,BLAS_Cpp::trans_not(trans_rhs1)
322  ,beta,BLAS_Cpp::trans,mwo_lhs
323  );
324 }
325 
326 } // end namespace AbstractLinAlgPack
327 
328 // nonmembers
329 
331  EApplyBy apply_by
332  ,const RTOpPack::RTOp &primary_op
333  ,const size_t num_multi_vecs
334  ,const MultiVector* multi_vecs[]
335  ,const size_t num_targ_multi_vecs
336  ,MultiVectorMutable* targ_multi_vecs[]
337  ,RTOpPack::ReductTarget* reduct_objs[]
338  ,const index_type primary_first_ele
339  ,const index_type primary_sub_dim
340  ,const index_type primary_global_offset
341  ,const index_type secondary_first_ele
342  ,const index_type secondary_sub_dim
343  )
344 {
345  if(num_multi_vecs)
346  multi_vecs[0]->apply_op(
347  apply_by,primary_op
348  ,num_multi_vecs,multi_vecs,num_targ_multi_vecs,targ_multi_vecs
349  ,reduct_objs,primary_first_ele,primary_sub_dim,primary_global_offset
350  ,secondary_first_ele,secondary_sub_dim
351  );
352  else if(num_targ_multi_vecs)
353  targ_multi_vecs[0]->apply_op(
354  apply_by,primary_op
355  ,num_multi_vecs,multi_vecs,num_targ_multi_vecs,targ_multi_vecs
356  ,reduct_objs,primary_first_ele,primary_sub_dim,primary_global_offset
357  ,secondary_first_ele,secondary_sub_dim
358  );
359 }
360 
362  EApplyBy apply_by
363  ,const RTOpPack::RTOp &primary_op
364  ,const RTOpPack::RTOp &secondary_op
365  ,const size_t num_multi_vecs
366  ,const MultiVector* multi_vecs[]
367  ,const size_t num_targ_multi_vecs
368  ,MultiVectorMutable* targ_multi_vecs[]
369  ,RTOpPack::ReductTarget *reduct_obj
370  ,const index_type primary_first_ele
371  ,const index_type primary_sub_dim
372  ,const index_type primary_global_offset
373  ,const index_type secondary_first_ele
374  ,const index_type secondary_sub_dim
375  )
376 {
377  if(num_multi_vecs)
378  multi_vecs[0]->apply_op(
379  apply_by,primary_op,secondary_op
380  ,num_multi_vecs,multi_vecs,num_targ_multi_vecs,targ_multi_vecs
381  ,reduct_obj,primary_first_ele,primary_sub_dim,primary_global_offset
382  ,secondary_first_ele,secondary_sub_dim
383  );
384  else if(num_targ_multi_vecs)
385  targ_multi_vecs[0]->apply_op(
386  apply_by,primary_op,secondary_op
387  ,num_multi_vecs,multi_vecs,num_targ_multi_vecs,targ_multi_vecs
388  ,reduct_obj,primary_first_ele,primary_sub_dim,primary_global_offset
389  ,secondary_first_ele,secondary_sub_dim
390  );
391 }
AbstractLinAlgPack::size_type size_type
mat_ptr_t clone() const
Returns this->mv_clone().
Abstract interface for immutable, finite dimensional, coordinate vectors {abstract}.
void Vt_S(VectorMutable *v_lhs, const value_type &alpha)
v_lhs *= alpha
virtual access_by_t access_by() const =0
Return a bit field for the types of access that are the most convenient.
mat_ptr_t sub_view(const Range1D &row_rng, const Range1D &col_rng) const
Returns this->mv_sub_view(row_rng,col_rng) casted to a MatrixOp.
Transposed.
bool Mp_StMtM(MatrixOp *mwo_lhs, value_type alpha, const MatrixOp &mwo_rhs1, BLAS_Cpp::Transp trans_rhs1, BLAS_Cpp::Transp trans_rhs2, value_type beta) const
Provides a specialized implementation for mwo_rhs1 of type MatrixSymDiag.
Not transposed.
virtual size_type cols() const
Return the number of columns in the matrix.
. One-based subregion index range class.
RTOpT< RTOp_value_type > RTOp
Teuchos::RCP< const MultiVector > multi_vec_ptr_t
void Mp_MtM_assert_compatibility(MatrixOp *m_lhs, BLAS_Cpp::Transp trans_lhs, const MatrixOp &m_rhs1, BLAS_Cpp::Transp trans_rhs1, const MatrixOp &m_rhs2, BLAS_Cpp::Transp trans_rhs2)
op(m_lhs) += op(m_rhs1) * op(m_rhs2)
void ele_wise_prod(const value_type &alpha, const Vector &v_rhs1, const Vector &v_rhs2, VectorMutable *v_lhs)
v_lhs(i) += alpha * v_rhs1(i) * v_rhs2(i), i = 1,,,dim.
const LAPACK_C_Decl::f_int const LAPACK_C_Decl::f_int const LAPACK_C_Decl::f_int const LAPACK_C_Decl::f_dbl_prec const LAPACK_C_Decl::f_int const LAPACK_C_Decl::f_dbl_prec LAPACK_C_Decl::f_dbl_prec * C
Base class for all matrices that support basic matrix operations.
Interface for a collection of non-mutable vectors (multi-vector, matrix).
virtual vec_mut_ptr_t row(index_type i)=0
Get a mutable row vector.
Interface to all diagonal matrices {abstract}.
virtual multi_vec_ptr_t mv_sub_view(const Range1D &row_rng, const Range1D &col_rng) const
Returns a sub-view of the multi vector.
Transp trans_not(Transp _trans)
Return the opposite of the transpose argument.
Interface for a collection of mutable vectors (multi-vector, matrix).
void apply_op(EApplyBy apply_by, const RTOpPack::RTOp &primary_op, const size_t num_multi_vecs, const MultiVector *multi_vecs[], const size_t num_targ_multi_vecs, MultiVectorMutable *targ_multi_vecs[], RTOpPack::ReductTarget *reduct_objs[]=NULL, const index_type primary_first_ele=1, const index_type primary_sub_dim=0, const index_type primary_global_offset=0, const index_type secondary_first_ele=1, const index_type secondary_sub_dim=0)
Apply a reduction/transformation operator column by column and return an array of the reduction objec...
friend void apply_op(EApplyBy apply_by, const RTOpPack::RTOp &primary_op, const size_t num_multi_vecs, const MultiVector *multi_vecs[], const size_t num_targ_multi_vecs, MultiVectorMutable *targ_multi_vecs[], RTOpPack::ReductTarget *reduct_objs[], const index_type primary_first_ele, const index_type primary_sub_dim, const index_type primary_global_offset, const index_type secondary_first_ele, const index_type secondary_sub_dim)
virtual void apply_op(EApplyBy apply_by, const RTOpPack::RTOp &primary_op, const size_t num_multi_vecs, const MultiVector *multi_vecs[], const size_t num_targ_multi_vecs, MultiVectorMutable *targ_multi_vecs[], RTOpPack::ReductTarget *reduct_objs[], const index_type primary_first_ele, const index_type primary_sub_dim, const index_type primary_global_offset, const index_type secondary_first_ele, const index_type secondary_sub_dim) const
Apply a reduction/transformation operator row by row, or column by column and return an array of the ...
virtual size_type rows() const
Return the number of rows in the matrix.
virtual multi_vec_ptr_t mv_clone() const
Clone the non-const multi-vector object.
virtual vec_ptr_t col(index_type j) const =0
Get a non-mutable column vector.
virtual vec_mut_ptr_t col(index_type j)=0
Get a mutable column vector.
virtual vec_ptr_t row(index_type i) const =0
Get a non-mutable row vector.
Transp
TRANS.
size_type cols(size_type rows, size_type cols, BLAS_Cpp::Transp _trans)
Return columns of a possible transposed matrix.
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
TEUCHOSCORE_LIB_DLL_EXPORT Teuchos::RCP< WorkspaceStore > get_default_workspace_store()