MOOCHO (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AbstractLinAlgPack_MatrixSymDiagStd.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 <iostream> // Debuggin only
43 
50 #include "Teuchos_Assert.hpp"
51 
52 namespace AbstractLinAlgPack {
53 
55  const VectorSpace::vec_mut_ptr_t& diag
56  ,bool unique
57  )
58 {
59  this->initialize(diag,unique);
60 // std::cerr << "MatrixSymDiagStd::rows() = " << this->rows() << std::endl; // Debugging
61 // std::cerr << "MatrixSymDiagStd::nz() = " << this->nz() << std::endl; // Debugging
62 // std::cerr << "MatrixSymDiagStd::cols() = " << this->cols() << std::endl; // Debugging
63 // std::cerr << "MatrixSymDiagStd::nz() = " << this->nz() << std::endl; // Debugging
64 }
65 
67  const VectorSpace::vec_mut_ptr_t& diag
68  ,bool unique
69  )
70 {
71  diag_ = diag; // lazy copy!
72  unique_ = unique;
73 }
74 
76 {
77  copy_unique();
80  !diag, std::logic_error
81  ,"MatrixSymDiagStd::diag(): Error, the diagonal vector has not been set! " );
82  return *diag;;
83 }
84 
87 {
88  return diag_;
89 }
90 
91 // Overridden from MatrixBase
92 
94 {
95  return diag_.get() ? diag_->dim() : 0;
96 }
97 
99 {
100  return diag_.get() ? diag_->nz() : 0;
101 }
102 
103 // Overridden from MatrixOp
104 
106  return diag_->space();
107 }
108 
110  return diag_->space();
111 }
112 
113 MatrixOp&
115 {
116  const MatrixSymDiagStd
117  *p_M = dynamic_cast<const MatrixSymDiagStd*>(&M);
118 
120  p_M == NULL, std::logic_error
121  ,"MatrixSymDiagStd::operator=(M): Error, the matrix M with concrete type "
122  "\'" << typeName(M) << "\' does not support the MatrixSymDiagStd type! " );
123 
124  if( p_M == this ) return *this; // Assignment to self
125 
126  diag_ = p_M->diag_; // lazy copy!
127  unique_ = p_M->unique_;
128 
129  return *this;
130 }
131 
133  MatrixOp* M_lhs, value_type alpha, BLAS_Cpp::Transp trans_rhs) const
134 {
135  // ToDo: validate the vector spaces for the matrices!
137  *M_mv_lhs = dynamic_cast<MultiVectorMutable*>(M_lhs);
138  if(!M_mv_lhs)
139  return false;
141  M_diag = M_mv_lhs->diag(0);
142  if(!M_diag.get())
143  return false; // Access to the diagonal is not supported!
144  Vp_StV( M_diag.get(), alpha, *diag_ );
145  return true;
146 }
147 
149  VectorMutable* v_lhs, value_type alpha, BLAS_Cpp::Transp trans_rhs1
150  , const Vector& v_rhs2, value_type beta) const
151 {
152  // ToDo: Validate input!
153  if(beta == 0.0)
154  *v_lhs = 0.0;
155  else if(beta != 1.0)
156  Vt_S( v_lhs, beta );
157  ele_wise_prod( alpha, v_rhs2, *diag_, v_lhs );
158 }
159 
161  VectorMutable* v_lhs, value_type alpha, BLAS_Cpp::Transp trans_rhs1
162  , const SpVectorSlice& sv_rhs2, value_type beta) const
163 {
164  MatrixOp::Vp_StMtV(v_lhs,alpha,trans_rhs1,sv_rhs2,beta); // ToDo: Implement specialized!
165 }
166 
167 // Overridden from MatrixNonsing
168 
170  VectorMutable* v_lhs, BLAS_Cpp::Transp trans_rhs1
171  , const Vector& v_rhs2) const
172 {
173  ele_wise_divide( 1.0, v_rhs2, *diag_, v_lhs );
174 }
175 
177  VectorMutable* v_lhs, BLAS_Cpp::Transp trans_rhs1
178  , const SpVectorSlice& sv_rhs2) const
179 {
180  MatrixNonsing::V_InvMtV(v_lhs,trans_rhs1,sv_rhs2 ); // ToDo: Implement specialized!
181 }
182 
184  BLAS_Cpp::Transp A_trans
185  ,value_type a
186  ,value_type b
187  ,MatrixSymOp *B
188  ) const
189 {
190  MatrixSymDiagStd *B_sd = dynamic_cast<MatrixSymDiagStd*>(B);
191  if(!B_sd) return false;
192  VectorMutable &B_diag = B_sd->diag();
193  const Vector &A_diag = this->diag();
194  // B = b*B + a*A*A
195  Vt_S( &B_diag, b );
196  ele_wise_prod( 1.0, A_diag, A_diag, &B_diag ); // B.diag(i) += a * (A.diag)(i) * (A.diag)(i)
197  return true;
198 }
199 
200 // Overridden from MatrixSymInitDiag
201 
203 {
204  diag_ = space_diag.create_member();
205  if( diag_->dim() )
206  *diag_ = alpha;
207 }
208 
210 {
211  diag_ = diag.space().create_member();
212  *diag_ = diag;
213 }
214 
215 // Overridden from MatrixSymDiag
216 
218 {
219  return const_cast<MatrixSymDiagStd*>(this)->diag();
220 }
221 
222 // private
223 
225 {
226  if( diag_.get() && diag_.total_count() > 1 && unique_ )
227  diag_ = diag_->clone();
228 }
229 
230 } // end namespace AbstractLinAlgPack
virtual const VectorSpace & space() const =0
Return the vector space that this vector belongs to.
std::string typeName(const T &t)
Abstract interface for immutable, finite dimensional, coordinate vectors {abstract}.
void Vt_S(VectorMutable *v_lhs, const value_type &alpha)
v_lhs *= alpha
friend void V_InvMtV(VectorMutable *v_lhs, const MatrixNonsing &M_rhs1, BLAS_Cpp::Transp trans_rhs1, const Vector &v_rhs2)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void Vp_StV(VectorMutable *v_lhs, const value_type &alpha, const Vector &v_rhs)
v_lhs = alpha * v_rhs + v_lhs
MatrixSymDiagStd(const VectorSpace::vec_mut_ptr_t &diag=Teuchos::null, bool unique=true)
Calls this->initialize().
T * get() const
void Vp_StMtV(VectorMutable *v_lhs, value_type alpha, BLAS_Cpp::Transp trans_rhs1, const Vector &v_rhs2, value_type beta) const
bool Mp_StM(MatrixOp *g_lhs, value_type alpha, BLAS_Cpp::Transp trans_rhs) const
Add to a mutable matrix lhs.
void ele_wise_divide(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.
Interface adding operations specific for a symmetric matrix {abstract}.
bool syrk(BLAS_Cpp::Transp M_trans, value_type alpha, value_type beta, MatrixSymOp *sym_lhs) const
Implements the symmetric rank-k update for all diagonal matrix lhs.
Abstract interface for objects that represent a space for mutable coordinate vectors.
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_int LAPACK_C_Decl::f_dbl_prec B[]
const LAPACK_C_Decl::f_int & M
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.
void initialize(const VectorSpace::vec_mut_ptr_t &diag, bool unique=true)
Initialize given the diagonal vector (or no vector at all).
virtual vec_mut_ptr_t diag(int k)=0
Get a mutable diagonal vector.
Base class for all matrices that support basic matrix operations.
const VectorSpace::vec_mut_ptr_t & diag_ptr() const
Interface for a collection of mutable vectors (multi-vector, matrix).
void V_InvMtV(VectorMutable *v_lhs, BLAS_Cpp::Transp trans_rhs1, const Vector &v_rhs2) const
void init_identity(const VectorSpace &space_diag, value_type alpha)
Abstract interface for mutable coordinate vectors {abstract}.
virtual vec_mut_ptr_t create_member() const =0
Create a vector member from the vector space.
size_type rows() const
Returns 0 if not initalized (this->diag() == NULL).
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.
VectorMutable & diag()
Give non-const access to the diagonal vector.
int total_count() const