MOOCHO (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AbstractLinAlgPack_dense_Vp_StPtMtV.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization
5 // Copyright (2003) 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 
42 #ifndef DENSE_V_P_S_T_P_T_M_T_V_H
43 #define DENSE_V_P_S_T_P_T_M_T_V_H
44 
45 #include "AbstractLinAlgPack/src/AbstractLinAlgPack_SpVectorClass.hpp"
47 #include "AbstractLinAlgPack/src/AbstractLinAlgPack_EtaVector.hpp"
48 #include "AbstractLinAlgPack/src/AbstractLinAlgPack_GenPermMatrixSlice.hpp"
54 #include "MiWorkspacePack.h"
55 
56 namespace AbstractLinAlgPack {
57 
64 template<class M_t, class V_t>
66  DVectorSlice *y
67  ,value_type a
68  ,const GenPermMatrixSlice &P
69  ,BLAS_Cpp::Transp P_trans
70  ,const M_t &M
71  ,BLAS_Cpp::Transp M_trans
72  ,const V_t &x
73  ,value_type b
74  )
75 {
76  using BLAS_Cpp::no_trans;
77  using BLAS_Cpp::trans;
78  using BLAS_Cpp::trans_not;
79  using BLAS_Cpp::rows;
80  using BLAS_Cpp::cols;
88  using Teuchos::Workspace;
90 
91  // Validate the sizes
92  //
93  // y += op(P)*op(M)*x
94  //
96  ny = y->size(),
97  nx = x.size(),
98  opM_rows = rows( M.rows(), M.cols(), M_trans ),
99  opM_cols = cols( M.rows(), M.cols(), M_trans );
100  if( ny != rows( P.rows(), P.cols(), P_trans )
101  || nx != opM_cols
102  || cols( P.rows(), P.cols(), P_trans ) != opM_rows )
103  throw std::length_error( "MatrixOp::Vp_StPtMtV(...) : Error, "
104  "sizes of arguments does not match up" );
105  //
106  // Compute y = b*y + a*op(P)*op(M)*x in a resonably efficient manner. This
107  // implementation will assume that M is stored as a dense matrix. Either
108  // t = op(M)*x is computed first (O(opM_rows*nx) flops) then y = b*y + a*op(P)*t
109  // (O(ny) + O(P_nz) flops) or each row of t' = e(j)' * op(M) (O(nx) flops)
110  // is computed one at a time and then y(i) = b*y(i) + a*t'*x (O(nx) flops)
111  // where op(P)(i,j) = 1.0. In the latter case, there are P_nz rows
112  // of op(M) that have to be generated so the total cost is O(P_nz*nx).
113  // Therefore, we will do the former if opM_rows < P_nz and the latter otherwise.
114  //
115  if( !P.nz() ) {
116  // y = b*y
117  if(b==0.0) *y = 0.0;
118  else if(b!=1.0) Vt_S(y,b);
119  }
120  else if( opM_rows > P.nz() || P.is_identity() ) {
121  // t = op(M)*x
122  Workspace<value_type> t_ws(wss,opM_rows);
123  DVectorSlice t(&t_ws[0],t_ws.size());
124  LinAlgOpPack::V_MtV( &t, M, M_trans, x );
125  // y = b*y + a*op(P)*t
126  Vp_StMtV( y, a, P, P_trans, t(), b );
127  }
128  else {
129  // y = b*y
130  if(b==0.0) *y = 0.0;
131  else if(b!=1.0) Vt_S(y,b);
132  // Compute t' = e(j)' * op(M) then y(i) += a*t'*x where op(P)(i,j) = 1.0
133  Workspace<value_type> t_ws(wss,opM_cols);
134  DVectorSlice t(&t_ws[0],t_ws.size());
135  if( P.is_identity() ) {
136  for( size_type k = 1; k <= P.nz(); ++k ) {
137  const size_type
138  i = k,
139  j = k;
140  // t = op(M') * e(j)
141  LinAlgOpPack::V_MtV( &t, M, trans_not(M_trans), eta(j,opM_rows)() );
142  // y(i) += a*t'*x
143  (*y)(i) += a * dot( t(), x );
144  }
145  }
146  else {
147  for( GenPermMatrixSlice::const_iterator itr = P.begin(); itr != P.end(); ++itr ) {
149  i = P_trans == no_trans ? itr->row_i() : itr->col_j(),
150  j = P_trans == no_trans ? itr->col_j() : itr->row_i();
151  // t = op(M') * e(j)
152  LinAlgOpPack::V_MtV( &t, M, trans_not(M_trans), eta(j,opM_rows)() );
153  // y(i) += a*t'*x
154  (*y)(i) += a * dot( t(), x );
155  }
156  }
157  }
158 }
159 
160 } // end namespace AbstractLinAlgPack
161 
162 #endif // DENSE_V_P_S_T_P_T_M_T_V_H
Teuchos::Ordinal size_type
Typedef for the size type of elements that are used by the library.
void Vt_S(VectorMutable *v_lhs, const value_type &alpha)
v_lhs *= alpha
size_type rows(size_type rows, size_type cols, BLAS_Cpp::Transp _trans)
Return rows of a possible transposed matrix.
const_iterator end() const
Return the end of this->const_iterator_begin().
Transposed.
Not transposed.
This is a full random access iterator for accessing row and colunmn indices.
const_iterator begin() const
Return a random access iterator for accessing which row and column that each nonzero 1...
const LAPACK_C_Decl::f_int & M
Create an eta vector (scaled by alpha = default 1).
void Vp_StMtV(VectorMutable *v_lhs, value_type alpha, const MatrixOp &M_rhs1, BLAS_Cpp::Transp trans_rhs1, const Vector &v_rhs2, value_type beta=1.0)
v_lhs = alpha * op(M_rhs1) * v_rhs2 + beta * v_lhs (BLAS xGEMV)
value_type dot(const Vector &v_rhs1, const Vector &v_rhs2)
result = v_rhs1' * v_rhs2
Transp trans_not(Transp _trans)
Return the opposite of the transpose argument.
void Vt_S(DVectorSlice *vs_lhs, value_type alpha)
vs_lhs *= alpha (BLAS xSCAL) (*** Note that alpha == 0.0 is handeled as vs_lhs = 0.0)
void V_MtV(VectorMutable *v_lhs, const MatrixOp &M_rhs1, BLAS_Cpp::Transp trans_rhs1, const V &V_rhs2)
v_lhs = op(M_rhs1) * V_rhs2.
VectorTmpl< value_type > DVector
void dense_Vp_StPtMtV(DVectorSlice *y, value_type a, const GenPermMatrixSlice &P, BLAS_Cpp::Transp P_trans, const M_t &M, BLAS_Cpp::Transp M_trans, const V_t &x, value_type b)
Implements y = b*y + a*op(P)*op(M)*x where it is assumed that generating rows of op(M) is cheap compa...
Transp
TRANS.
size_type cols(size_type rows, size_type cols, BLAS_Cpp::Transp _trans)
Return columns of a possible transposed matrix.
TEUCHOSCORE_LIB_DLL_EXPORT Teuchos::RCP< WorkspaceStore > get_default_workspace_store()
Concrete matrix type to represent general permutation (mapping) matrices.
value_type dot(const DVectorSlice &vs_rhs1, const DVectorSlice &vs_rhs2)
result = vs_rhs1' * vs_rhs2 (BLAS xDOT)