MOOCHO (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AbstractLinAlgPack_MatrixOpSubView.cpp
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 #include <assert.h>
43 
44 #include <typeinfo>
45 #include <stdexcept>
46 
55 #include "Teuchos_RCP.hpp"
56 #include "Teuchos_Assert.hpp"
57 
58 namespace AbstractLinAlgPack {
59 
61  const mat_ptr_t& M_full
62  ,const Range1D& rng_rows
63  ,const Range1D& rng_cols
64  ,BLAS_Cpp::Transp M_trans
65  )
66 {
67  this->initialize(M_full,rng_rows,rng_cols,M_trans);
68 }
69 
71  const mat_ptr_t& M_full
72  ,const Range1D& rng_rows_in
73  ,const Range1D& rng_cols_in
74  ,BLAS_Cpp::Transp M_trans
75  )
76 {
77  namespace rcp = MemMngPack;
78 
79  if( M_full.get() ) {
80  const index_type
81  M_rows = M_full->rows(),
82  M_cols = M_full->cols();
83  const Range1D
84  rng_rows = RangePack::full_range(rng_rows_in,1,M_rows),
85  rng_cols = RangePack::full_range(rng_cols_in,1,M_cols);
87  rng_rows.ubound() > M_rows, std::invalid_argument
88  ,"MatrixOpSubView::initialize(...): Error, "
89  "rng_rows = ["<<rng_rows.lbound()<<","<<rng_rows.ubound()<<"] is of range of "
90  "[1,M_full->rows()] = [1,"<<M_rows<<"]" );
92  rng_cols.ubound() > M_cols, std::invalid_argument
93  ,"MatrixOpSubView::initialize(...): Error, "
94  "rng_cols = ["<<rng_cols.lbound()<<","<<rng_cols.ubound()<<"] is of range of "
95  "[1,M_full->cols()] = [1,"<<M_cols<<"]" );
96  M_full_ = M_full;
97  rng_rows_ = rng_rows;
98  rng_cols_ = rng_cols;
99  M_trans_ = M_trans;
100  space_cols_ = ( M_trans == BLAS_Cpp::no_trans
101  ? M_full->space_cols().sub_space(rng_rows)->clone()
102  : M_full->space_rows().sub_space(rng_cols)->clone() );
103  space_rows_ = ( M_trans == BLAS_Cpp::no_trans
104  ? M_full->space_rows().sub_space(rng_cols)->clone()
105  : M_full->space_cols().sub_space(rng_rows)->clone() );
106  }
107  else {
108  M_full_ = Teuchos::null;
109  rng_rows_ = Range1D::Invalid;
110  rng_cols_ = Range1D::Invalid;
111  M_trans_ = BLAS_Cpp::no_trans;
112  space_cols_ = Teuchos::null;
113  space_rows_ = Teuchos::null;
114  }
115 }
116 
117 // overridden from MatrixBase
118 
120 {
121  return ( M_full_.get()
122  ? BLAS_Cpp::rows( rng_rows_.size(), rng_cols_.size(), M_trans_ )
123  : 0 );
124 }
125 
127 {
128  return ( M_full_.get()
129  ? BLAS_Cpp::cols( rng_rows_.size(), rng_cols_.size(), M_trans_ )
130  : 0 );
131 }
132 
134 {
135  return ( M_full_.get()
136  ? ( rng_rows_.full_range() && rng_cols_.full_range()
137  ? M_full_->nz()
138  : MatrixBase::nz() )
139  : 0 );
140 }
141 
142 // Overridden form MatrixOp
143 
145 {
147  return *space_cols_;
148 }
149 
151 {
153  return *space_rows_;
154 }
155 
156 MatrixOp::mat_ptr_t
157 MatrixOpSubView::sub_view(const Range1D& row_rng, const Range1D& col_rng) const
158 {
160  TEUCHOS_TEST_FOR_EXCEPT(true); // ToDo: Implement!
161  return Teuchos::null;
162 }
163 
165 {
167  if( rng_rows_.full_range() && rng_cols_.full_range() ) {
168  M_full_->zero_out();
169  return;
170  }
172  true, std::logic_error, "MatrixOpSubView::zero_out(): "
173  "Error, this method can not be implemented with a sub-view" );
174 }
175 
177 {
179  if( rng_rows_.full_range() && rng_cols_.full_range() ) {
180  M_full_->Mt_S(alpha);
181  return;
182  }
184  true, std::logic_error, "MatrixOpSubView::Mt_S(alpha): "
185  "Error, this method can not be implemented with a sub-view" );
186 }
187 
189 {
191  TEUCHOS_TEST_FOR_EXCEPT(true); // ToDo: Implement!
192  return *this;
193 }
194 
195 std::ostream& MatrixOpSubView::output(std::ostream& out) const
196 {
198  return MatrixOp::output(out); // ToDo: Specialize if needed?
199 }
200 
201 // Level-1 BLAS
202 
203 // rhs matrix argument
204 
206  MatrixOp* m_lhs, value_type alpha
207  , BLAS_Cpp::Transp trans_rhs) const
208 {
210  return MatrixOp::Mp_StM(m_lhs,alpha,trans_rhs); // ToDo: Specialize?
211 }
212 
214  MatrixOp* m_lhs, value_type alpha
215  , BLAS_Cpp::Transp M_trans
216  , const GenPermMatrixSlice& P_rhs, BLAS_Cpp::Transp P_rhs_trans
217  ) const
218 {
220  return MatrixOp::Mp_StMtP(m_lhs,alpha,M_trans,P_rhs,P_rhs_trans); // ToDo: Specialize?
221 }
222 
224  MatrixOp* m_lhs, value_type alpha
225  , const GenPermMatrixSlice& P_rhs, BLAS_Cpp::Transp P_rhs_trans
226  , BLAS_Cpp::Transp M_trans
227  ) const
228 {
230  return MatrixOp::Mp_StPtM(m_lhs,alpha,P_rhs,P_rhs_trans,M_trans); // ToDo: Specialize?
231 }
232 
234  MatrixOp* m_lhs, value_type alpha
235  , const GenPermMatrixSlice& P_rhs1, BLAS_Cpp::Transp P_rhs1_trans
236  , BLAS_Cpp::Transp M_trans
237  , const GenPermMatrixSlice& P_rhs2, BLAS_Cpp::Transp P_rhs2_trans
238  ) const
239 {
241  return MatrixOp::Mp_StPtMtP(
242  m_lhs,alpha,P_rhs1,P_rhs1_trans,M_trans,P_rhs2,P_rhs2_trans); // ToDo: Specialize?
243 }
244 
245 // lhs matrix argument
246 
248  value_type alpha,const MatrixOp& M_rhs, BLAS_Cpp::Transp trans_rhs)
249 {
251  return MatrixOp::Mp_StM(alpha,M_rhs,trans_rhs); // ToDo: Specialize?
252 }
253 
255  value_type alpha
256  ,const MatrixOp& M_rhs, BLAS_Cpp::Transp M_trans
257  ,const GenPermMatrixSlice& P_rhs, BLAS_Cpp::Transp P_rhs_trans
258  )
259 {
261  return MatrixOp::Mp_StMtP(alpha,M_rhs,M_trans,P_rhs,P_rhs_trans); // ToDo: Specialize?
262 }
263 
265  value_type alpha
266  ,const GenPermMatrixSlice& P_rhs, BLAS_Cpp::Transp P_rhs_trans
267  ,const MatrixOp& M_rhs, BLAS_Cpp::Transp M_trans
268  )
269 {
271  return MatrixOp::Mp_StPtM(
272  alpha,P_rhs,P_rhs_trans,M_rhs,M_trans); // ToDo: Specialize?
273 }
274 
276  value_type alpha
277  ,const GenPermMatrixSlice& P_rhs1, BLAS_Cpp::Transp P_rhs1_trans
278  ,const MatrixOp& M_rhs, BLAS_Cpp::Transp M_trans
279  ,const GenPermMatrixSlice& P_rhs2, BLAS_Cpp::Transp P_rhs2_trans
280  )
281 {
283  return MatrixOp::Mp_StPtMtP(
284  alpha,P_rhs1,P_rhs1_trans,M_rhs,M_trans,P_rhs2,P_rhs2_trans); // ToDo: Specialize?
285 }
286 
287 // Level-2 BLAS
288 
291  , const Vector& x, value_type b
292  ) const
293 {
294  using BLAS_Cpp::no_trans;
295  using BLAS_Cpp::trans;
296 
298 
300  M_trans_trans = ( M_trans_==no_trans ? M_trans_in : BLAS_Cpp::trans_not(M_trans_in) );
301 
302  // ToDo: Assert compatibility!
303 
304  if( rng_rows_.full_range() && rng_cols_.full_range() ) {
305  AbstractLinAlgPack::Vp_StMtV( // The matrix is just transposed
306  y, a
307  ,*M_full_, M_trans_trans
308  ,x, b );
309  return;
310  }
311  // y = b*y
312  Vt_S( y, b );
313  //
314  // xt1 = 0.0
315  // xt3 = xt(op_op_rng_cols) = x
316  // xt3 = 0.0
317  //
318  // [ yt1 ] [ xt1 ]
319  // [ yt2 ] = a * op(op(M_full)) * [ xt3 ]
320  // [ yt3 ] [ xt3 ]
321  //
322  // =>
323  //
324  // y += yt2 = yt(op_op_rng_rows)
325  //
326  const Range1D
327  op_op_rng_rows = ( M_trans_trans == no_trans ? rng_rows_ : rng_cols_ ),
328  op_op_rng_cols = ( M_trans_trans == no_trans ? rng_cols_ : rng_rows_ );
330  xt = ( M_trans_trans == no_trans ? M_full_->space_rows() : M_full_->space_cols() ).create_member(),
331  yt = ( M_trans_trans == no_trans ? M_full_->space_cols() : M_full_->space_rows() ).create_member();
332  *xt = 0.0;
333  *xt->sub_view(op_op_rng_cols) = x;
334  LinAlgOpPack::V_StMtV( yt.get(), a, *M_full_, M_trans_trans, *xt );
335  LinAlgOpPack::Vp_V( y, *yt->sub_view(op_op_rng_rows) );
336 }
337 
339  VectorMutable* v_lhs, value_type alpha, BLAS_Cpp::Transp trans_rhs1
340  , const SpVectorSlice& sv_rhs2, value_type beta) const
341 {
343  MatrixOp::Vp_StMtV(v_lhs,alpha,trans_rhs1,sv_rhs2,beta); // ToDo: Specialize?
344 }
345 
347  VectorMutable* v_lhs, value_type alpha
348  , const GenPermMatrixSlice& P_rhs1, BLAS_Cpp::Transp P_rhs1_trans
349  , BLAS_Cpp::Transp M_rhs2_trans
350  , const Vector& v_rhs3, value_type beta) const
351 {
354  v_lhs,alpha,P_rhs1,P_rhs1_trans,M_rhs2_trans,v_rhs3,beta); // ToDo: Specialize?
355 }
356 
358  VectorMutable* v_lhs, value_type alpha
359  , const GenPermMatrixSlice& P_rhs1, BLAS_Cpp::Transp P_rhs1_trans
360  , BLAS_Cpp::Transp M_rhs2_trans
361  , const SpVectorSlice& sv_rhs3, value_type beta) const
362 {
365  v_lhs,alpha,P_rhs1,P_rhs1_trans,M_rhs2_trans,sv_rhs3,beta); // ToDo: Specialize?
366 }
367 
369  const Vector& v_rhs1, BLAS_Cpp::Transp trans_rhs2
370  , const Vector& v_rhs3) const
371 {
373  return MatrixOp::transVtMtV(v_rhs1,trans_rhs2,v_rhs3); // ToDo: Specialize?
374 }
375 
377  const SpVectorSlice& sv_rhs1, BLAS_Cpp::Transp trans_rhs2
378  , const SpVectorSlice& sv_rhs3) const
379 {
381  return MatrixOp::transVtMtV(sv_rhs1,trans_rhs2,sv_rhs3); // ToDo: Specialize?
382 }
383 
385  BLAS_Cpp::Transp M_trans, value_type alpha
386  , const GenPermMatrixSlice& P1, BLAS_Cpp::Transp P1_trans
387  , const GenPermMatrixSlice& P2, BLAS_Cpp::Transp P2_trans
388  , value_type beta, MatrixSymOp* sym_lhs ) const
389 {
392  M_trans,alpha,P1,P1_trans,P2,P2_trans,beta,sym_lhs); // ToDo: Specialize?
393 }
394 
395 // Level-3 BLAS
396 
398  MatrixOp* m_lhs, value_type alpha
399  , BLAS_Cpp::Transp trans_rhs1, const MatrixOp& mwo_rhs2
400  , BLAS_Cpp::Transp trans_rhs2, value_type beta) const
401 {
403  return MatrixOp::Mp_StMtM(
404  m_lhs,alpha,trans_rhs1,mwo_rhs2,trans_rhs2,beta); // ToDo: Specialize?
405 }
406 
408  MatrixOp* m_lhs, value_type alpha
409  , const MatrixOp& mwo_rhs1, BLAS_Cpp::Transp trans_rhs1
410  , BLAS_Cpp::Transp trans_rhs2, value_type beta ) const
411 {
412  return MatrixOp::Mp_StMtM(
413  m_lhs,alpha,mwo_rhs1,trans_rhs1,trans_rhs2,beta); // ToDo: Specialize?
414 }
415 
417  value_type alpha
418  ,const MatrixOp& mvw_rhs1, BLAS_Cpp::Transp trans_rhs1
419  ,const MatrixOp& mwo_rhs2,BLAS_Cpp::Transp trans_rhs2
420  ,value_type beta )
421 {
423  return MatrixOp::Mp_StMtM(
424  alpha,mvw_rhs1,trans_rhs1,mwo_rhs2,trans_rhs2,beta); // ToDo: Specialize?
425 }
426 
428  BLAS_Cpp::Transp M_trans, value_type alpha
429  , value_type beta, MatrixSymOp* sym_lhs ) const
430 {
432  return MatrixOp::syrk(M_trans,alpha,beta,sym_lhs); // ToDo: Specialize?
433 }
434 
435 // private
436 
439  M_full_.get() == NULL, std::logic_error
440  ,"Error, the MatrixOpSubView object has not been initialize!" );
441 }
442 
443 } // end namespace AbstractLinAlgPack
virtual size_type nz() const
Return the number of nonzero elements in the matrix.
virtual vec_mut_ptr_t sub_view(const Range1D &rng)
Create a mutable abstract view of a vector object.
bool syrk(BLAS_Cpp::Transp M_trans, value_type alpha, value_type beta, MatrixSymOp *sym_lhs) const
friend void syr2k(const MatrixOp &M, BLAS_Cpp::Transp M_trans, value_type alpha, const GenPermMatrixSlice &P1, BLAS_Cpp::Transp P1_trans, const GenPermMatrixSlice &P2, BLAS_Cpp::Transp P2_trans, value_type beta, MatrixSymOp *symwo_lhs)
Abstract interface for immutable, finite dimensional, coordinate vectors {abstract}.
MatrixOpSubView(const mat_ptr_t &M_full=Teuchos::null, const Range1D &rng_rows=Range1D(), const Range1D &rng_cols=Range1D(), BLAS_Cpp::Transp M_trans=BLAS_Cpp::no_trans)
Calls this->initialize(...)
void Vp_StPtMtV(VectorMutable *vs_lhs, value_type alpha, const GenPermMatrixSlice &P_rhs1, BLAS_Cpp::Transp P_rhs1_trans, BLAS_Cpp::Transp M_rhs2_trans, const Vector &v_rhs3, value_type beta) const
void Vt_S(VectorMutable *v_lhs, const value_type &alpha)
v_lhs *= alpha
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Index ubound() const
Return upper bound of the range.
size_type rows(size_type rows, size_type cols, BLAS_Cpp::Transp _trans)
Return rows of a possible transposed matrix.
MatrixOp::mat_ptr_t sub_view(const Range1D &row_rng, const Range1D &col_rng) const
T * get() const
bool Mp_StM(MatrixOp *mwo_lhs, value_type alpha, BLAS_Cpp::Transp trans_rhs) const
void V_StMtV(VectorMutable *v_lhs, value_type alpha, const MatrixOp &M_rhs1, BLAS_Cpp::Transp trans_rhs1, const V &V_rhs2)
v_lhs = alpha * op(M_rhs1) * V_rhs2.
friend value_type transVtMtV(const Vector &v_rhs1, const MatrixOp &M_rhs2, BLAS_Cpp::Transp trans_rhs2, const Vector &v_rhs3)
Transposed.
friend void Mp_StPtMtP(MatrixOp *mwo_lhs, value_type alpha, const GenPermMatrixSlice &P_rhs1, BLAS_Cpp::Transp P_rhs1_trans, const MatrixOp &M_rhs, BLAS_Cpp::Transp trans_rhs, const GenPermMatrixSlice &P_rhs2, BLAS_Cpp::Transp P_rhs2_trans)
void syr2k(BLAS_Cpp::Transp M_trans, value_type alpha, const GenPermMatrixSlice &P1, BLAS_Cpp::Transp P1_trans, const GenPermMatrixSlice &P2, BLAS_Cpp::Transp P2_trans, value_type beta, MatrixSymOp *symwo_lhs) const
Interface adding operations specific for a symmetric matrix {abstract}.
virtual std::ostream & output(std::ostream &out) const
Virtual output function.
std::ostream & output(std::ostream &out) const
Not transposed.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
. One-based subregion index range class.
value_type transVtMtV(const Vector &v_rhs1, BLAS_Cpp::Transp trans_rhs2, const Vector &v_rhs3) const
Abstract interface for objects that represent a space for mutable coordinate vectors.
void initialize(const mat_ptr_t &M_full, const Range1D &rng_rows=Range1D(), const Range1D &rng_cols=Range1D(), BLAS_Cpp::Transp M_trans=BLAS_Cpp::no_trans)
Initialize the view of a matrix.
friend void Mp_StMtM(MatrixOp *mwo_lhs, value_type alpha, const MatrixOp &mwo_rhs1, BLAS_Cpp::Transp trans_rhs1, const MatrixOp &mwo_rhs2, BLAS_Cpp::Transp trans_rhs2, value_type beta)
std::ostream * out
const LAPACK_C_Decl::f_int & M
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)
friend void Mp_StM(MatrixOp *mwo_lhs, value_type alpha, const MatrixOp &M_rhs, BLAS_Cpp::Transp trans_rhs)
Base class for all matrices that support basic matrix operations.
bool Mp_StMtP(MatrixOp *mwo_lhs, value_type alpha, BLAS_Cpp::Transp M_trans, const GenPermMatrixSlice &P_rhs, BLAS_Cpp::Transp P_rhs_trans) const
bool Mp_StPtMtP(MatrixOp *mwo_lhs, value_type alpha, const GenPermMatrixSlice &P_rhs1, BLAS_Cpp::Transp P_rhs1_trans, BLAS_Cpp::Transp M_trans, const GenPermMatrixSlice &P_rhs2, BLAS_Cpp::Transp P_rhs2_trans) const
static const Range1D Invalid
Range1D(INVALID)
Transp trans_not(Transp _trans)
Return the opposite of the transpose argument.
Index lbound() const
Return lower bound of the range.
bool Mp_StPtM(MatrixOp *mwo_lhs, value_type alpha, const GenPermMatrixSlice &P_rhs, BLAS_Cpp::Transp P_rhs_trans, BLAS_Cpp::Transp M_trans) const
friend void Mp_StMtP(MatrixOp *mwo_lhs, value_type alpha, const MatrixOp &M_rhs, BLAS_Cpp::Transp M_trans, const GenPermMatrixSlice &P_rhs, BLAS_Cpp::Transp P_rhs_trans)
Abstract interface for mutable coordinate vectors {abstract}.
bool Mp_StMtM(MatrixOp *mwo_lhs, value_type alpha, BLAS_Cpp::Transp trans_rhs1, const MatrixOp &mwo_rhs2, BLAS_Cpp::Transp trans_rhs2, value_type beta) const
friend void syrk(const MatrixOp &mwo_rhs, BLAS_Cpp::Transp M_trans, value_type alpha, value_type beta, MatrixSymOp *sym_lhs)
friend 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)
Transp
TRANS.
void Vp_StMtV(VectorMutable *vs_lhs, value_type alpha, BLAS_Cpp::Transp trans_rhs1, const Vector &v_rhs2, value_type beta) const
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)
Concrete matrix type to represent general permutation (mapping) matrices.
friend void Mp_StPtM(MatrixOp *mwo_lhs, value_type alpha, const GenPermMatrixSlice &P_rhs, BLAS_Cpp::Transp P_rhs_trans, const MatrixOp &M_rhs, BLAS_Cpp::Transp M_trans)
friend void Vp_StPtMtV(VectorMutable *v_lhs, value_type alpha, const GenPermMatrixSlice &P_rhs1, BLAS_Cpp::Transp P_rhs1_trans, const MatrixOp &M_rhs2, BLAS_Cpp::Transp M_rhs2_trans, const Vector &v_rhs3, value_type beta)
void Vp_V(VectorMutable *v_lhs, const V &V_rhs)
v_lhs += V_rhs.