MOOCHO (Single Doxygen Collection) Version of the Day
AbstractLinAlgPack_AssertOp.cpp
Go to the documentation of this file.
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 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 
00025 // 
00026 // ***********************************************************************
00027 // @HEADER
00028 
00029 #include <stdexcept>
00030 #include <string>
00031 #include <typeinfo>
00032 
00033 #include "AbstractLinAlgPack_AssertOp.hpp"
00034 #include "AbstractLinAlgPack_VectorSpace.hpp"
00035 #include "AbstractLinAlgPack_VectorMutable.hpp"
00036 #include "AbstractLinAlgPack_MatrixOp.hpp"
00037 #include "Teuchos_TestForException.hpp"
00038 
00039 // boilerplate code
00040 
00041 namespace {
00042 
00043 struct dump_vec_spaces {
00044 public:
00045   dump_vec_spaces(
00046     const AbstractLinAlgPack::VectorSpace& _vec_space1, const char _vec_space1_name[]
00047     ,const AbstractLinAlgPack::VectorSpace& _vec_space2, const char _vec_space2_name[]
00048     )
00049     :vec_space1(_vec_space1),vec_space1_name(_vec_space1_name)
00050     ,vec_space2(_vec_space2),vec_space2_name(_vec_space2_name)
00051     {}
00052   const AbstractLinAlgPack::VectorSpace &vec_space1;
00053   const char                            *vec_space1_name;
00054   const AbstractLinAlgPack::VectorSpace &vec_space2;
00055   const char                            *vec_space2_name;
00056 }; // end dum_vec_spaces
00057 
00058 // Notice!!!!!!!  Place a breakpoint in following function in order to halt the
00059 // program just before an exception is thrown!
00060 
00061 std::ostream& operator<<( std::ostream& o, const dump_vec_spaces& d )
00062 {
00063   o << "Error, " << d.vec_space1_name << " at address " << &d.vec_space1
00064     << " of type \'" << typeName(d.vec_space1)
00065     << "\' with dimension " << d.vec_space1_name << ".dim() = " << d.vec_space1.dim()
00066     << " is not compatible with "
00067     << d.vec_space2_name  << " at address " << &d.vec_space2
00068     << " of type \'" << typeName(d.vec_space2)
00069     << "\' with dimension " << d.vec_space2_name << ".dim() = " << d.vec_space2.dim();
00070   return o;
00071 }
00072 
00073 enum EM_VS { SPACE_COLS, SPACE_ROWS };
00074 
00075 const AbstractLinAlgPack::VectorSpace& op(
00076   const AbstractLinAlgPack::MatrixOp&     M
00077   ,BLAS_Cpp::Transp                           M_trans
00078   ,EM_VS                                      M_VS
00079   )
00080 {
00081   using BLAS_Cpp::no_trans;
00082   using BLAS_Cpp::trans;
00083   if(M_trans == no_trans && M_VS == SPACE_COLS)
00084     return M.space_cols();
00085   if(M_trans == trans && M_VS == SPACE_COLS)
00086     return M.space_rows();
00087   if(M_trans == no_trans && M_VS == SPACE_ROWS)
00088     return M.space_rows();
00089   // M_trans == trans && M_VS == SPACE_ROWS
00090   return M.space_cols();
00091 }
00092 
00093 } // end namespace
00094 
00095 #define ASSERT_LHS_ARG(FUNC_NAME,LHS_ARG)                                              \
00096   TEST_FOR_EXCEPTION(                                                                   \
00097     (LHS_ARG) == NULL, std::invalid_argument                                       \
00098     ,FUNC_NAME << " : Error!"                                                      \
00099     );
00100 
00101 // Notice!!!!!!!  Setting a breakpoint a the line number that is printed by this macro
00102 // and then trying to set the condition !is_compatible does not work (at least not
00103 // in gdb).
00104 
00105 #define ASSERT_VEC_SPACES_NAMES(FUNC_NAME,VS1,VS1_NAME,VS2,VS2_NAME)                   \
00106 {                                                                                      \
00107   const bool is_compatible = (VS1).is_compatible(VS2);                               \
00108   TEST_FOR_EXCEPTION(                                                                   \
00109     !is_compatible, VectorSpace::IncompatibleVectorSpaces                          \
00110     ,FUNC_NAME << " : " << dump_vec_spaces(VS1,VS1_NAME,VS2,VS2_NAME)              \
00111     )                                                                              \
00112 }
00113 
00114 #define ASSERT_VEC_SPACES(FUNC_NAME,VS1,VS2)                                              \
00115 ASSERT_VEC_SPACES_NAMES(FUNC_NAME,VS1,#VS1,VS2,#VS2)
00116 
00117 #define ASSERT_MAT_VEC_SPACES(FUNC_NAME,M,M_T,M_VS,VS)                                    \
00118 {                                                                                         \
00119   std::ostringstream M_VS_name;                                                         \
00120   M_VS_name << "(" #M << ( M_T == BLAS_Cpp::no_trans ? "" : "'" ) << ")"                \
00121          << "." << ( M_VS == SPACE_COLS ? "space_cols()" : "space_rows()" );        \
00122   ASSERT_VEC_SPACES_NAMES(                                                              \
00123     FUNC_NAME                                                                         \
00124     ,op(M,M_T,M_VS),M_VS_name.str().c_str()                                           \
00125     ,VS,#VS                                                                           \
00126     )                                                                                 \
00127 }
00128 
00129 #define ASSERT_MAT_MAT_SPACES(FUNC_NAME,M1,M1_T,M1_VS,M2,M2_T,M2_VS)                      \
00130 {                                                                                         \
00131   std::ostringstream M1_VS_name, M2_VS_name;                                            \
00132   M1_VS_name << "(" #M1 << ( M1_T == BLAS_Cpp::no_trans ? "" : "'" ) << ")" \
00133          << "." << ( M1_VS == SPACE_COLS ? "space_cols()" : "space_rows()" );       \
00134   M2_VS_name << "(" #M2 << ( M2_T == BLAS_Cpp::no_trans ? "" : "'" ) << ")" \
00135          << "." << ( M2_VS == SPACE_COLS ? "space_cols()" : "space_rows()" );       \
00136   ASSERT_VEC_SPACES_NAMES(                                                              \
00137     FUNC_NAME                                                                         \
00138     ,op(M1,M1_T,M1_VS),M1_VS_name.str().c_str()                                       \
00139     ,op(M2,M2_T,M2_VS),M2_VS_name.str().c_str()                                       \
00140     )                                                                                 \
00141 }
00142 
00143 // function definitions
00144 
00145 #ifdef ABSTRACTLINALGPACK_ASSERT_COMPATIBILITY
00146 
00147 void AbstractLinAlgPack::Vp_V_assert_compatibility(VectorMutable* v_lhs, const Vector& v_rhs)
00148 {
00149   const char func_name[] = "Vp_V_assert_compatibility(v_lhs,v_rhs)";
00150   ASSERT_LHS_ARG(func_name,v_lhs)
00151   ASSERT_VEC_SPACES("Vp_V_assert_compatibility(v_lhs,v_rhs)",v_lhs->space(),v_rhs.space());
00152 }
00153 
00154 void AbstractLinAlgPack::Vp_V_assert_compatibility(VectorMutable* v_lhs, const SpVectorSlice& sv_rhs)
00155 {
00156   // ToDo: Check compatibility!
00157 } 
00158 
00159 void AbstractLinAlgPack::VopV_assert_compatibility(const Vector& v_rhs1, const Vector&  v_rhs2)
00160 {
00161   const char func_name[] = "VopV_assert_compatibility(v_rhs1,v_rhs2)";
00162   ASSERT_VEC_SPACES(func_name,v_rhs1.space(),v_rhs2.space());
00163 }
00164 
00165 
00166 void AbstractLinAlgPack::VopV_assert_compatibility(const Vector& v_rhs1, const SpVectorSlice& sv_rhs2)
00167 {
00168   // ToDo: Check compatibility!
00169 } 
00170 
00171 void AbstractLinAlgPack::VopV_assert_compatibility(const SpVectorSlice& sv_rhs1, const Vector& v_rhs2)
00172 {
00173   // ToDo: Check compatibility!
00174 } 
00175 
00176 void AbstractLinAlgPack::Mp_M_assert_compatibility(
00177   MatrixOp* m_lhs, BLAS_Cpp::Transp trans_lhs
00178   ,const MatrixOp& m_rhs, BLAS_Cpp::Transp trans_rhs )
00179 {
00180   const char func_name[] = "Mp_M_assert_compatibility(m_lhs,trans_lhs,m_rhs,trans_rhs)";
00181   ASSERT_LHS_ARG(func_name,m_lhs)
00182   ASSERT_MAT_MAT_SPACES(func_name,(*m_lhs),trans_lhs,SPACE_COLS,m_rhs,trans_rhs,SPACE_COLS)
00183   ASSERT_MAT_MAT_SPACES(func_name,(*m_lhs),trans_lhs,SPACE_ROWS,m_rhs,trans_rhs,SPACE_ROWS)
00184 }
00185 
00186 void AbstractLinAlgPack::MopM_assert_compatibility(
00187   const MatrixOp& m_rhs1, BLAS_Cpp::Transp trans_rhs1
00188   ,const MatrixOp& m_rhs2, BLAS_Cpp::Transp trans_rhs2 )
00189 {
00190   const char func_name[] = "MopM_assert_compatibility(m_rhs1,trans_rhs1,m_rhs2,trans_rhs2)";
00191   ASSERT_MAT_MAT_SPACES(func_name,m_rhs1,trans_rhs1,SPACE_COLS,m_rhs2,trans_rhs2,SPACE_COLS)
00192   ASSERT_MAT_MAT_SPACES(func_name,m_rhs1,trans_rhs1,SPACE_ROWS,m_rhs2,trans_rhs2,SPACE_ROWS)
00193 }
00194 
00195 void AbstractLinAlgPack::MtV_assert_compatibility(
00196   const MatrixOp& m_rhs1, BLAS_Cpp::Transp trans_rhs1, const Vector& v_rhs2 )
00197 {
00198   const char func_name[] = "MtV_assert_compatibility(m_rhs1,trans_rhs1,v_rhs2)";
00199   ASSERT_MAT_VEC_SPACES(func_name,m_rhs1,trans_rhs1,SPACE_ROWS,v_rhs2.space())
00200 }
00201 
00202 void AbstractLinAlgPack::MtV_assert_compatibility(
00203   const MatrixOp& m_rhs1, BLAS_Cpp::Transp trans_rhs1, const SpVectorSlice& sv_rhs2 )
00204 {
00205   // ToDo: Check compatibility!
00206 } 
00207 
00208 void AbstractLinAlgPack::Vp_MtV_assert_compatibility(
00209   VectorMutable* v_lhs
00210   ,const MatrixOp& m_rhs1, BLAS_Cpp::Transp trans_rhs1, const Vector& v_rhs2 )
00211 {
00212   const char func_name[] = "Vp_MtV_assert_compatibility(v_lhs,m_rhs1,trans_rhs1,v_rhs2)";
00213   ASSERT_LHS_ARG(func_name,v_lhs)
00214   ASSERT_MAT_VEC_SPACES(func_name,m_rhs1,trans_rhs1,SPACE_COLS,v_lhs->space())
00215   ASSERT_MAT_VEC_SPACES(func_name,m_rhs1,trans_rhs1,SPACE_ROWS,v_rhs2.space())
00216 }
00217 
00218 void AbstractLinAlgPack::Vp_MtV_assert_compatibility(
00219   VectorMutable* v_lhs
00220   ,const MatrixOp& m_rhs1, BLAS_Cpp::Transp trans_rhs1, const SpVectorSlice& sv_rhs2 )
00221 {
00222   // ToDo: Check compatibility!
00223 } 
00224 
00225 void AbstractLinAlgPack::MtM_assert_compatibility(
00226   const MatrixOp& m_rhs1, BLAS_Cpp::Transp trans_rhs1
00227   ,const MatrixOp& m_rhs2, BLAS_Cpp::Transp trans_rhs2 )
00228 {
00229   const char func_name[] = "MtM_assert_compatibility(m_rhs1,trans_rhs1,m_rhs2,trans_rhs2)";
00230   ASSERT_MAT_MAT_SPACES(func_name,m_rhs1,trans_rhs1,SPACE_COLS,m_rhs2,trans_rhs2,SPACE_ROWS)
00231   ASSERT_MAT_MAT_SPACES(func_name,m_rhs1,trans_rhs1,SPACE_ROWS,m_rhs2,trans_rhs2,SPACE_COLS)
00232 }
00233 
00234 void AbstractLinAlgPack::Mp_MtM_assert_compatibility(
00235   MatrixOp* m_lhs, BLAS_Cpp::Transp trans_lhs
00236   ,const MatrixOp& m_rhs1, BLAS_Cpp::Transp trans_rhs1
00237   ,const MatrixOp& m_rhs2, BLAS_Cpp::Transp trans_rhs2 )
00238 {
00239   const char func_name[] = "Mp_MtM_assert_compatibility(m_lhs,trans_lhsm_rhs1,trans_rhs1,m_rhs2,trans_rhs2)";
00240   ASSERT_LHS_ARG(func_name,m_lhs)
00241   ASSERT_MAT_MAT_SPACES(func_name,(*m_lhs),trans_lhs,SPACE_COLS,m_rhs1,trans_rhs1,SPACE_COLS)
00242   ASSERT_MAT_MAT_SPACES(func_name,(*m_lhs),trans_lhs,SPACE_ROWS,m_rhs2,trans_rhs2,SPACE_ROWS)
00243   ASSERT_MAT_MAT_SPACES(func_name,m_rhs1,trans_rhs1,SPACE_ROWS,m_rhs2,trans_rhs2,SPACE_COLS)
00244 }
00245 
00246 #endif // ABSTRACTLINALGPACK_ASSERT_COMPATIBILITY
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines