|
AbstractLinAlgPack: C++ Interfaces For Vectors, Matrices And Related Linear Algebra Objects
Version of the Day
|
00001 // @HEADER 00002 // *********************************************************************** 00003 // 00004 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization 00005 // Copyright (2003) Sandia Corporation 00006 // 00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00008 // license for use of this work by or on behalf of the U.S. Government. 00009 // 00010 // Redistribution and use in source and binary forms, with or without 00011 // modification, are permitted provided that the following conditions are 00012 // met: 00013 // 00014 // 1. Redistributions of source code must retain the above copyright 00015 // notice, this list of conditions and the following disclaimer. 00016 // 00017 // 2. Redistributions in binary form must reproduce the above copyright 00018 // notice, this list of conditions and the following disclaimer in the 00019 // documentation and/or other materials provided with the distribution. 00020 // 00021 // 3. Neither the name of the Corporation nor the names of the 00022 // contributors may be used to endorse or promote products derived from 00023 // this software without specific prior written permission. 00024 // 00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00036 // 00037 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 00038 // 00039 // *********************************************************************** 00040 // @HEADER 00041 00042 #include <stdexcept> 00043 #include <string> 00044 #include <typeinfo> 00045 00046 #include "AbstractLinAlgPack_AssertOp.hpp" 00047 #include "AbstractLinAlgPack_VectorSpace.hpp" 00048 #include "AbstractLinAlgPack_VectorMutable.hpp" 00049 #include "AbstractLinAlgPack_MatrixOp.hpp" 00050 #include "Teuchos_Assert.hpp" 00051 00052 // boilerplate code 00053 00054 namespace { 00055 00056 struct dump_vec_spaces { 00057 public: 00058 dump_vec_spaces( 00059 const AbstractLinAlgPack::VectorSpace& _vec_space1, const char _vec_space1_name[] 00060 ,const AbstractLinAlgPack::VectorSpace& _vec_space2, const char _vec_space2_name[] 00061 ) 00062 :vec_space1(_vec_space1),vec_space1_name(_vec_space1_name) 00063 ,vec_space2(_vec_space2),vec_space2_name(_vec_space2_name) 00064 {} 00065 const AbstractLinAlgPack::VectorSpace &vec_space1; 00066 const char *vec_space1_name; 00067 const AbstractLinAlgPack::VectorSpace &vec_space2; 00068 const char *vec_space2_name; 00069 }; // end dum_vec_spaces 00070 00071 // Notice!!!!!!! Place a breakpoint in following function in order to halt the 00072 // program just before an exception is thrown! 00073 00074 std::ostream& operator<<( std::ostream& o, const dump_vec_spaces& d ) 00075 { 00076 o << "Error, " << d.vec_space1_name << " at address " << &d.vec_space1 00077 << " of type \'" << typeName(d.vec_space1) 00078 << "\' with dimension " << d.vec_space1_name << ".dim() = " << d.vec_space1.dim() 00079 << " is not compatible with " 00080 << d.vec_space2_name << " at address " << &d.vec_space2 00081 << " of type \'" << typeName(d.vec_space2) 00082 << "\' with dimension " << d.vec_space2_name << ".dim() = " << d.vec_space2.dim(); 00083 return o; 00084 } 00085 00086 enum EM_VS { SPACE_COLS, SPACE_ROWS }; 00087 00088 const AbstractLinAlgPack::VectorSpace& op( 00089 const AbstractLinAlgPack::MatrixOp& M 00090 ,BLAS_Cpp::Transp M_trans 00091 ,EM_VS M_VS 00092 ) 00093 { 00094 using BLAS_Cpp::no_trans; 00095 using BLAS_Cpp::trans; 00096 if(M_trans == no_trans && M_VS == SPACE_COLS) 00097 return M.space_cols(); 00098 if(M_trans == trans && M_VS == SPACE_COLS) 00099 return M.space_rows(); 00100 if(M_trans == no_trans && M_VS == SPACE_ROWS) 00101 return M.space_rows(); 00102 // M_trans == trans && M_VS == SPACE_ROWS 00103 return M.space_cols(); 00104 } 00105 00106 } // end namespace 00107 00108 #define ASSERT_LHS_ARG(FUNC_NAME,LHS_ARG) \ 00109 TEUCHOS_TEST_FOR_EXCEPTION( \ 00110 (LHS_ARG) == NULL, std::invalid_argument \ 00111 ,FUNC_NAME << " : Error!" \ 00112 ); 00113 00114 // Notice!!!!!!! Setting a breakpoint a the line number that is printed by this macro 00115 // and then trying to set the condition !is_compatible does not work (at least not 00116 // in gdb). 00117 00118 #define ASSERT_VEC_SPACES_NAMES(FUNC_NAME,VS1,VS1_NAME,VS2,VS2_NAME) \ 00119 { \ 00120 const bool is_compatible = (VS1).is_compatible(VS2); \ 00121 TEUCHOS_TEST_FOR_EXCEPTION( \ 00122 !is_compatible, VectorSpace::IncompatibleVectorSpaces \ 00123 ,FUNC_NAME << " : " << dump_vec_spaces(VS1,VS1_NAME,VS2,VS2_NAME) \ 00124 ) \ 00125 } 00126 00127 #define ASSERT_VEC_SPACES(FUNC_NAME,VS1,VS2) \ 00128 ASSERT_VEC_SPACES_NAMES(FUNC_NAME,VS1,#VS1,VS2,#VS2) 00129 00130 #define ASSERT_MAT_VEC_SPACES(FUNC_NAME,M,M_T,M_VS,VS) \ 00131 { \ 00132 std::ostringstream M_VS_name; \ 00133 M_VS_name << "(" #M << ( M_T == BLAS_Cpp::no_trans ? "" : "'" ) << ")" \ 00134 << "." << ( M_VS == SPACE_COLS ? "space_cols()" : "space_rows()" ); \ 00135 ASSERT_VEC_SPACES_NAMES( \ 00136 FUNC_NAME \ 00137 ,op(M,M_T,M_VS),M_VS_name.str().c_str() \ 00138 ,VS,#VS \ 00139 ) \ 00140 } 00141 00142 #define ASSERT_MAT_MAT_SPACES(FUNC_NAME,M1,M1_T,M1_VS,M2,M2_T,M2_VS) \ 00143 { \ 00144 std::ostringstream M1_VS_name, M2_VS_name; \ 00145 M1_VS_name << "(" #M1 << ( M1_T == BLAS_Cpp::no_trans ? "" : "'" ) << ")" \ 00146 << "." << ( M1_VS == SPACE_COLS ? "space_cols()" : "space_rows()" ); \ 00147 M2_VS_name << "(" #M2 << ( M2_T == BLAS_Cpp::no_trans ? "" : "'" ) << ")" \ 00148 << "." << ( M2_VS == SPACE_COLS ? "space_cols()" : "space_rows()" ); \ 00149 ASSERT_VEC_SPACES_NAMES( \ 00150 FUNC_NAME \ 00151 ,op(M1,M1_T,M1_VS),M1_VS_name.str().c_str() \ 00152 ,op(M2,M2_T,M2_VS),M2_VS_name.str().c_str() \ 00153 ) \ 00154 } 00155 00156 // function definitions 00157 00158 #ifdef ABSTRACTLINALGPACK_ASSERT_COMPATIBILITY 00159 00160 void AbstractLinAlgPack::Vp_V_assert_compatibility(VectorMutable* v_lhs, const Vector& v_rhs) 00161 { 00162 const char func_name[] = "Vp_V_assert_compatibility(v_lhs,v_rhs)"; 00163 ASSERT_LHS_ARG(func_name,v_lhs) 00164 ASSERT_VEC_SPACES("Vp_V_assert_compatibility(v_lhs,v_rhs)",v_lhs->space(),v_rhs.space()); 00165 } 00166 00167 void AbstractLinAlgPack::Vp_V_assert_compatibility(VectorMutable* v_lhs, const SpVectorSlice& sv_rhs) 00168 { 00169 // ToDo: Check compatibility! 00170 } 00171 00172 void AbstractLinAlgPack::VopV_assert_compatibility(const Vector& v_rhs1, const Vector& v_rhs2) 00173 { 00174 const char func_name[] = "VopV_assert_compatibility(v_rhs1,v_rhs2)"; 00175 ASSERT_VEC_SPACES(func_name,v_rhs1.space(),v_rhs2.space()); 00176 } 00177 00178 00179 void AbstractLinAlgPack::VopV_assert_compatibility(const Vector& v_rhs1, const SpVectorSlice& sv_rhs2) 00180 { 00181 // ToDo: Check compatibility! 00182 } 00183 00184 void AbstractLinAlgPack::VopV_assert_compatibility(const SpVectorSlice& sv_rhs1, const Vector& v_rhs2) 00185 { 00186 // ToDo: Check compatibility! 00187 } 00188 00189 void AbstractLinAlgPack::Mp_M_assert_compatibility( 00190 MatrixOp* m_lhs, BLAS_Cpp::Transp trans_lhs 00191 ,const MatrixOp& m_rhs, BLAS_Cpp::Transp trans_rhs ) 00192 { 00193 const char func_name[] = "Mp_M_assert_compatibility(m_lhs,trans_lhs,m_rhs,trans_rhs)"; 00194 ASSERT_LHS_ARG(func_name,m_lhs) 00195 ASSERT_MAT_MAT_SPACES(func_name,(*m_lhs),trans_lhs,SPACE_COLS,m_rhs,trans_rhs,SPACE_COLS) 00196 ASSERT_MAT_MAT_SPACES(func_name,(*m_lhs),trans_lhs,SPACE_ROWS,m_rhs,trans_rhs,SPACE_ROWS) 00197 } 00198 00199 void AbstractLinAlgPack::MopM_assert_compatibility( 00200 const MatrixOp& m_rhs1, BLAS_Cpp::Transp trans_rhs1 00201 ,const MatrixOp& m_rhs2, BLAS_Cpp::Transp trans_rhs2 ) 00202 { 00203 const char func_name[] = "MopM_assert_compatibility(m_rhs1,trans_rhs1,m_rhs2,trans_rhs2)"; 00204 ASSERT_MAT_MAT_SPACES(func_name,m_rhs1,trans_rhs1,SPACE_COLS,m_rhs2,trans_rhs2,SPACE_COLS) 00205 ASSERT_MAT_MAT_SPACES(func_name,m_rhs1,trans_rhs1,SPACE_ROWS,m_rhs2,trans_rhs2,SPACE_ROWS) 00206 } 00207 00208 void AbstractLinAlgPack::MtV_assert_compatibility( 00209 const MatrixOp& m_rhs1, BLAS_Cpp::Transp trans_rhs1, const Vector& v_rhs2 ) 00210 { 00211 const char func_name[] = "MtV_assert_compatibility(m_rhs1,trans_rhs1,v_rhs2)"; 00212 ASSERT_MAT_VEC_SPACES(func_name,m_rhs1,trans_rhs1,SPACE_ROWS,v_rhs2.space()) 00213 } 00214 00215 void AbstractLinAlgPack::MtV_assert_compatibility( 00216 const MatrixOp& m_rhs1, BLAS_Cpp::Transp trans_rhs1, const SpVectorSlice& sv_rhs2 ) 00217 { 00218 // ToDo: Check compatibility! 00219 } 00220 00221 void AbstractLinAlgPack::Vp_MtV_assert_compatibility( 00222 VectorMutable* v_lhs 00223 ,const MatrixOp& m_rhs1, BLAS_Cpp::Transp trans_rhs1, const Vector& v_rhs2 ) 00224 { 00225 const char func_name[] = "Vp_MtV_assert_compatibility(v_lhs,m_rhs1,trans_rhs1,v_rhs2)"; 00226 ASSERT_LHS_ARG(func_name,v_lhs) 00227 ASSERT_MAT_VEC_SPACES(func_name,m_rhs1,trans_rhs1,SPACE_COLS,v_lhs->space()) 00228 ASSERT_MAT_VEC_SPACES(func_name,m_rhs1,trans_rhs1,SPACE_ROWS,v_rhs2.space()) 00229 } 00230 00231 void AbstractLinAlgPack::Vp_MtV_assert_compatibility( 00232 VectorMutable* v_lhs 00233 ,const MatrixOp& m_rhs1, BLAS_Cpp::Transp trans_rhs1, const SpVectorSlice& sv_rhs2 ) 00234 { 00235 // ToDo: Check compatibility! 00236 } 00237 00238 void AbstractLinAlgPack::MtM_assert_compatibility( 00239 const MatrixOp& m_rhs1, BLAS_Cpp::Transp trans_rhs1 00240 ,const MatrixOp& m_rhs2, BLAS_Cpp::Transp trans_rhs2 ) 00241 { 00242 const char func_name[] = "MtM_assert_compatibility(m_rhs1,trans_rhs1,m_rhs2,trans_rhs2)"; 00243 ASSERT_MAT_MAT_SPACES(func_name,m_rhs1,trans_rhs1,SPACE_COLS,m_rhs2,trans_rhs2,SPACE_ROWS) 00244 ASSERT_MAT_MAT_SPACES(func_name,m_rhs1,trans_rhs1,SPACE_ROWS,m_rhs2,trans_rhs2,SPACE_COLS) 00245 } 00246 00247 void AbstractLinAlgPack::Mp_MtM_assert_compatibility( 00248 MatrixOp* m_lhs, BLAS_Cpp::Transp trans_lhs 00249 ,const MatrixOp& m_rhs1, BLAS_Cpp::Transp trans_rhs1 00250 ,const MatrixOp& m_rhs2, BLAS_Cpp::Transp trans_rhs2 ) 00251 { 00252 const char func_name[] = "Mp_MtM_assert_compatibility(m_lhs,trans_lhsm_rhs1,trans_rhs1,m_rhs2,trans_rhs2)"; 00253 ASSERT_LHS_ARG(func_name,m_lhs) 00254 ASSERT_MAT_MAT_SPACES(func_name,(*m_lhs),trans_lhs,SPACE_COLS,m_rhs1,trans_rhs1,SPACE_COLS) 00255 ASSERT_MAT_MAT_SPACES(func_name,(*m_lhs),trans_lhs,SPACE_ROWS,m_rhs2,trans_rhs2,SPACE_ROWS) 00256 ASSERT_MAT_MAT_SPACES(func_name,m_rhs1,trans_rhs1,SPACE_ROWS,m_rhs2,trans_rhs2,SPACE_COLS) 00257 } 00258 00259 #endif // ABSTRACTLINALGPACK_ASSERT_COMPATIBILITY
1.7.6.1