AbstractLinAlgPack: C++ Interfaces For Vectors, Matrices And Related Linear Algebra Objects  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
AbstractLinAlgPack_AssertOp.cpp
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 <stdexcept>
43 #include <string>
44 #include <typeinfo>
45 
46 #include "AbstractLinAlgPack_AssertOp.hpp"
47 #include "AbstractLinAlgPack_VectorSpace.hpp"
48 #include "AbstractLinAlgPack_VectorMutable.hpp"
49 #include "AbstractLinAlgPack_MatrixOp.hpp"
50 #include "Teuchos_Assert.hpp"
51 
52 // boilerplate code
53 
54 namespace {
55 
56 struct dump_vec_spaces {
57 public:
58  dump_vec_spaces(
59  const AbstractLinAlgPack::VectorSpace& _vec_space1, const char _vec_space1_name[]
60  ,const AbstractLinAlgPack::VectorSpace& _vec_space2, const char _vec_space2_name[]
61  )
62  :vec_space1(_vec_space1),vec_space1_name(_vec_space1_name)
63  ,vec_space2(_vec_space2),vec_space2_name(_vec_space2_name)
64  {}
65  const AbstractLinAlgPack::VectorSpace &vec_space1;
66  const char *vec_space1_name;
67  const AbstractLinAlgPack::VectorSpace &vec_space2;
68  const char *vec_space2_name;
69 }; // end dum_vec_spaces
70 
71 // Notice!!!!!!! Place a breakpoint in following function in order to halt the
72 // program just before an exception is thrown!
73 
74 std::ostream& operator<<( std::ostream& o, const dump_vec_spaces& d )
75 {
76  o << "Error, " << d.vec_space1_name << " at address " << &d.vec_space1
77  << " of type \'" << typeName(d.vec_space1)
78  << "\' with dimension " << d.vec_space1_name << ".dim() = " << d.vec_space1.dim()
79  << " is not compatible with "
80  << d.vec_space2_name << " at address " << &d.vec_space2
81  << " of type \'" << typeName(d.vec_space2)
82  << "\' with dimension " << d.vec_space2_name << ".dim() = " << d.vec_space2.dim();
83  return o;
84 }
85 
86 enum EM_VS { SPACE_COLS, SPACE_ROWS };
87 
90  ,BLAS_Cpp::Transp M_trans
91  ,EM_VS M_VS
92  )
93 {
94  using BLAS_Cpp::no_trans;
95  using BLAS_Cpp::trans;
96  if(M_trans == no_trans && M_VS == SPACE_COLS)
97  return M.space_cols();
98  if(M_trans == trans && M_VS == SPACE_COLS)
99  return M.space_rows();
100  if(M_trans == no_trans && M_VS == SPACE_ROWS)
101  return M.space_rows();
102  // M_trans == trans && M_VS == SPACE_ROWS
103  return M.space_cols();
104 }
105 
106 } // end namespace
107 
108 #define ASSERT_LHS_ARG(FUNC_NAME,LHS_ARG) \
109  TEUCHOS_TEST_FOR_EXCEPTION( \
110  (LHS_ARG) == NULL, std::invalid_argument \
111  ,FUNC_NAME << " : Error!" \
112  );
113 
114 // Notice!!!!!!! Setting a breakpoint a the line number that is printed by this macro
115 // and then trying to set the condition !is_compatible does not work (at least not
116 // in gdb).
117 
118 #define ASSERT_VEC_SPACES_NAMES(FUNC_NAME,VS1,VS1_NAME,VS2,VS2_NAME) \
119 { \
120  const bool is_compatible = (VS1).is_compatible(VS2); \
121  TEUCHOS_TEST_FOR_EXCEPTION( \
122  !is_compatible, VectorSpace::IncompatibleVectorSpaces \
123  ,FUNC_NAME << " : " << dump_vec_spaces(VS1,VS1_NAME,VS2,VS2_NAME) \
124  ) \
125 }
126 
127 #define ASSERT_VEC_SPACES(FUNC_NAME,VS1,VS2) \
128 ASSERT_VEC_SPACES_NAMES(FUNC_NAME,VS1,#VS1,VS2,#VS2)
129 
130 #define ASSERT_MAT_VEC_SPACES(FUNC_NAME,M,M_T,M_VS,VS) \
131 { \
132  std::ostringstream M_VS_name; \
133  M_VS_name << "(" #M << ( M_T == BLAS_Cpp::no_trans ? "" : "'" ) << ")" \
134  << "." << ( M_VS == SPACE_COLS ? "space_cols()" : "space_rows()" ); \
135  ASSERT_VEC_SPACES_NAMES( \
136  FUNC_NAME \
137  ,op(M,M_T,M_VS),M_VS_name.str().c_str() \
138  ,VS,#VS \
139  ) \
140 }
141 
142 #define ASSERT_MAT_MAT_SPACES(FUNC_NAME,M1,M1_T,M1_VS,M2,M2_T,M2_VS) \
143 { \
144  std::ostringstream M1_VS_name, M2_VS_name; \
145  M1_VS_name << "(" #M1 << ( M1_T == BLAS_Cpp::no_trans ? "" : "'" ) << ")" \
146  << "." << ( M1_VS == SPACE_COLS ? "space_cols()" : "space_rows()" ); \
147  M2_VS_name << "(" #M2 << ( M2_T == BLAS_Cpp::no_trans ? "" : "'" ) << ")" \
148  << "." << ( M2_VS == SPACE_COLS ? "space_cols()" : "space_rows()" ); \
149  ASSERT_VEC_SPACES_NAMES( \
150  FUNC_NAME \
151  ,op(M1,M1_T,M1_VS),M1_VS_name.str().c_str() \
152  ,op(M2,M2_T,M2_VS),M2_VS_name.str().c_str() \
153  ) \
154 }
155 
156 // function definitions
157 
158 #ifdef ABSTRACTLINALGPACK_ASSERT_COMPATIBILITY
159 
160 void AbstractLinAlgPack::Vp_V_assert_compatibility(VectorMutable* v_lhs, const Vector& v_rhs)
161 {
162  const char func_name[] = "Vp_V_assert_compatibility(v_lhs,v_rhs)";
163  ASSERT_LHS_ARG(func_name,v_lhs)
164  ASSERT_VEC_SPACES("Vp_V_assert_compatibility(v_lhs,v_rhs)",v_lhs->space(),v_rhs.space());
165 }
166 
167 void AbstractLinAlgPack::Vp_V_assert_compatibility(VectorMutable* v_lhs, const SpVectorSlice& sv_rhs)
168 {
169  // ToDo: Check compatibility!
170 }
171 
172 void AbstractLinAlgPack::VopV_assert_compatibility(const Vector& v_rhs1, const Vector& v_rhs2)
173 {
174  const char func_name[] = "VopV_assert_compatibility(v_rhs1,v_rhs2)";
175  ASSERT_VEC_SPACES(func_name,v_rhs1.space(),v_rhs2.space());
176 }
177 
178 
179 void AbstractLinAlgPack::VopV_assert_compatibility(const Vector& v_rhs1, const SpVectorSlice& sv_rhs2)
180 {
181  // ToDo: Check compatibility!
182 }
183 
184 void AbstractLinAlgPack::VopV_assert_compatibility(const SpVectorSlice& sv_rhs1, const Vector& v_rhs2)
185 {
186  // ToDo: Check compatibility!
187 }
188 
190  MatrixOp* m_lhs, BLAS_Cpp::Transp trans_lhs
191  ,const MatrixOp& m_rhs, BLAS_Cpp::Transp trans_rhs )
192 {
193  const char func_name[] = "Mp_M_assert_compatibility(m_lhs,trans_lhs,m_rhs,trans_rhs)";
194  ASSERT_LHS_ARG(func_name,m_lhs)
195  ASSERT_MAT_MAT_SPACES(func_name,(*m_lhs),trans_lhs,SPACE_COLS,m_rhs,trans_rhs,SPACE_COLS)
196  ASSERT_MAT_MAT_SPACES(func_name,(*m_lhs),trans_lhs,SPACE_ROWS,m_rhs,trans_rhs,SPACE_ROWS)
197 }
198 
199 void AbstractLinAlgPack::MopM_assert_compatibility(
200  const MatrixOp& m_rhs1, BLAS_Cpp::Transp trans_rhs1
201  ,const MatrixOp& m_rhs2, BLAS_Cpp::Transp trans_rhs2 )
202 {
203  const char func_name[] = "MopM_assert_compatibility(m_rhs1,trans_rhs1,m_rhs2,trans_rhs2)";
204  ASSERT_MAT_MAT_SPACES(func_name,m_rhs1,trans_rhs1,SPACE_COLS,m_rhs2,trans_rhs2,SPACE_COLS)
205  ASSERT_MAT_MAT_SPACES(func_name,m_rhs1,trans_rhs1,SPACE_ROWS,m_rhs2,trans_rhs2,SPACE_ROWS)
206 }
207 
208 void AbstractLinAlgPack::MtV_assert_compatibility(
209  const MatrixOp& m_rhs1, BLAS_Cpp::Transp trans_rhs1, const Vector& v_rhs2 )
210 {
211  const char func_name[] = "MtV_assert_compatibility(m_rhs1,trans_rhs1,v_rhs2)";
212  ASSERT_MAT_VEC_SPACES(func_name,m_rhs1,trans_rhs1,SPACE_ROWS,v_rhs2.space())
213 }
214 
216  const MatrixOp& m_rhs1, BLAS_Cpp::Transp trans_rhs1, const SpVectorSlice& sv_rhs2 )
217 {
218  // ToDo: Check compatibility!
219 }
220 
222  VectorMutable* v_lhs
223  ,const MatrixOp& m_rhs1, BLAS_Cpp::Transp trans_rhs1, const Vector& v_rhs2 )
224 {
225  const char func_name[] = "Vp_MtV_assert_compatibility(v_lhs,m_rhs1,trans_rhs1,v_rhs2)";
226  ASSERT_LHS_ARG(func_name,v_lhs)
227  ASSERT_MAT_VEC_SPACES(func_name,m_rhs1,trans_rhs1,SPACE_COLS,v_lhs->space())
228  ASSERT_MAT_VEC_SPACES(func_name,m_rhs1,trans_rhs1,SPACE_ROWS,v_rhs2.space())
229 }
230 
231 void AbstractLinAlgPack::Vp_MtV_assert_compatibility(
232  VectorMutable* v_lhs
233  ,const MatrixOp& m_rhs1, BLAS_Cpp::Transp trans_rhs1, const SpVectorSlice& sv_rhs2 )
234 {
235  // ToDo: Check compatibility!
236 }
237 
239  const MatrixOp& m_rhs1, BLAS_Cpp::Transp trans_rhs1
240  ,const MatrixOp& m_rhs2, BLAS_Cpp::Transp trans_rhs2 )
241 {
242  const char func_name[] = "MtM_assert_compatibility(m_rhs1,trans_rhs1,m_rhs2,trans_rhs2)";
243  ASSERT_MAT_MAT_SPACES(func_name,m_rhs1,trans_rhs1,SPACE_COLS,m_rhs2,trans_rhs2,SPACE_ROWS)
244  ASSERT_MAT_MAT_SPACES(func_name,m_rhs1,trans_rhs1,SPACE_ROWS,m_rhs2,trans_rhs2,SPACE_COLS)
245 }
246 
247 void AbstractLinAlgPack::Mp_MtM_assert_compatibility(
248  MatrixOp* m_lhs, BLAS_Cpp::Transp trans_lhs
249  ,const MatrixOp& m_rhs1, BLAS_Cpp::Transp trans_rhs1
250  ,const MatrixOp& m_rhs2, BLAS_Cpp::Transp trans_rhs2 )
251 {
252  const char func_name[] = "Mp_MtM_assert_compatibility(m_lhs,trans_lhsm_rhs1,trans_rhs1,m_rhs2,trans_rhs2)";
253  ASSERT_LHS_ARG(func_name,m_lhs)
254  ASSERT_MAT_MAT_SPACES(func_name,(*m_lhs),trans_lhs,SPACE_COLS,m_rhs1,trans_rhs1,SPACE_COLS)
255  ASSERT_MAT_MAT_SPACES(func_name,(*m_lhs),trans_lhs,SPACE_ROWS,m_rhs2,trans_rhs2,SPACE_ROWS)
256  ASSERT_MAT_MAT_SPACES(func_name,m_rhs1,trans_rhs1,SPACE_ROWS,m_rhs2,trans_rhs2,SPACE_COLS)
257 }
258 
259 #endif // ABSTRACTLINALGPACK_ASSERT_COMPATIBILITY
virtual const VectorSpace & space_rows() const =0
Vector space for vectors that are compatible with the rows of the matrix.
void MopM_assert_compatibility(const MatrixOp &m_rhs1, BLAS_Cpp::Transp trans_rhs1, const MatrixOp &m_rhs2, BLAS_Cpp::Transp trans_rhs2)
op(m_rhs1) op op(m_rhs2)
void MtV_assert_compatibility(const MatrixOp &m_rhs1, BLAS_Cpp::Transp trans_rhs1, const Vector &v_rhs2)
op(m_rhs1) * v_rhs2
void Vp_V_assert_compatibility(VectorMutable *v_lhs, const Vector &v_rhs)
v_lhs += op v_rhs
void MtM_assert_compatibility(const MatrixOp &m_rhs1, BLAS_Cpp::Transp trans_rhs1, const MatrixOp &m_rhs2, BLAS_Cpp::Transp trans_rhs2)
op(m_lhs) += op(m_rhs1)
Abstract interface for objects that represent a space for mutable coordinate vectors.
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)
Base class for all matrices that support basic matrix operations.
virtual const VectorSpace & space_cols() const =0
Vector space for vectors that are compatible with the columns of the matrix.
void Vp_MtV_assert_compatibility(VectorMutable *v_lhs, const MatrixOp &m_rhs1, BLAS_Cpp::Transp trans_rhs1, const Vector &v_rhs2)
v_lhs += op(m_rhs1) * v_rhs2
Transp
std::string typeName(const T &t)
void Mp_M_assert_compatibility(MatrixOp *m_lhs, BLAS_Cpp::Transp trans_lhs, const MatrixOp &m_rhs, BLAS_Cpp::Transp trans_rhs)
op(m_lhs) += op op(m_rhs)
void VopV_assert_compatibility(const Vector &v_rhs1, const Vector &v_rhs2)
v_rhs1 op v_rhs2