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 // 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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines