MOOCHO (Single Doxygen Collection) Version of the Day
DenseLinAlgPack_LinAlgOpPackDef.hpp
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 #ifndef LIN_ALG_OP_PACK_DEF_H
00043 #define LIN_ALG_OP_PACK_DEF_H
00044 
00045 #include "DenseLinAlgPack_LinAlgOpPackDecl.hpp" // also includes some inline function definitions
00046 #include "DenseLinAlgPack_AssertOp.hpp"
00047 #include "DenseLinAlgPack_DMatrixClass.hpp"
00048 
00049 namespace LinAlgOpPack {
00050 
00051 using BLAS_Cpp::rows;
00052 using BLAS_Cpp::cols;
00053 
00054 // Inject assert functions
00055 using DenseLinAlgPack::assert_gms_lhs;
00056 using DenseLinAlgPack::Vp_V_assert_sizes;
00057 using DenseLinAlgPack::VopV_assert_sizes;
00058 using DenseLinAlgPack::Mp_M_assert_sizes;
00059 using DenseLinAlgPack::MopM_assert_sizes;
00060 using DenseLinAlgPack::Vp_MtV_assert_sizes;
00061 using DenseLinAlgPack::MtV_assert_sizes;
00062 using DenseLinAlgPack::MtM_assert_sizes;
00063 
00064 // Inject names of base linear algebra functions for DenseLinAlgPack.
00065 // Note that this is neccesary in MS VC++ 5.0 because
00066 // it does not perform name lookups properly but it
00067 // is not adverse to the standard so it is a portable
00068 // fix.
00069 using DenseLinAlgPack::assign;
00070 using DenseLinAlgPack::Vt_S;
00071 using DenseLinAlgPack::Vp_StV;
00072 using DenseLinAlgPack::Vp_StMtV;
00073 using DenseLinAlgPack::Mt_S;
00074 using DenseLinAlgPack::Mp_StM;
00075 using DenseLinAlgPack::Mp_StMtM;
00076 
00077 // ///////////////////////////////////////////////////////////////////////////////
00078 // ///////////////////////////////////////////////////////////////////////////////
00079 // Level 1 BLAS for Vectors
00080 
00081 // //////////////////////////////////////////////////////////////////////////////
00082 // += operations 
00083 
00084 // //////////////////////////////////////////////////////////////////////////////
00085 // operations with DVector as lhs
00086 
00087 // v_lhs = V_rhs.
00088 template <class V>
00089 void assign(DVector* v_lhs, const V& V_rhs) {
00090   v_lhs->resize(V_rhs.dim());
00091   (*v_lhs) = 0.0;
00092   Vp_V(&(*v_lhs)(),V_rhs);
00093 }
00094 
00095 // v_lhs = alpha * V_rhs.
00096 template <class V>
00097 void V_StV(DVector* v_lhs, value_type alpha, const V& V_rhs) {
00098   v_lhs->resize(V_rhs.dim());
00099   (*v_lhs) = 0.0;
00100   Vp_StV(&(*v_lhs)(),alpha,V_rhs);
00101 }
00102 
00103 // v_lhs = V1_rhs1 + V2_rhs2.
00104 template <class V1, class V2>
00105 void V_VpV(DVector* v_lhs, const V1& V1_rhs1, const V2& V2_rhs2) {
00106   VopV_assert_sizes(V1_rhs1.dim(),V2_rhs2.dim());
00107   v_lhs->resize(V1_rhs1.dim());
00108   (*v_lhs) = 0.0;
00109   DVectorSlice vs_lhs(*v_lhs);
00110   Vp_V(&vs_lhs,V1_rhs1);
00111   Vp_V(&vs_lhs,V2_rhs2);
00112 }
00113 
00114 
00115 // v_lhs = V_rhs1 - V_rhs2.
00116 template <class V1, class V2>
00117 void V_VmV(DVector* v_lhs, const V1& V1_rhs1, const V2& V2_rhs2) {
00118   VopV_assert_sizes(V1_rhs1.dim(),V2_rhs2.dim());
00119   v_lhs->resize(V1_rhs1.dim());
00120   (*v_lhs) = 0.0;
00121   DVectorSlice vs_lhs(*v_lhs);
00122   Vp_V(&vs_lhs,V1_rhs1);
00123   Vp_StV(&vs_lhs,-1.0,V2_rhs2);
00124 }
00125 
00126 
00127 // v_lhs = alpha * V_rhs1 + vs_rhs2.
00128 template <class V>
00129 void V_StVpV(DVector* v_lhs, value_type alpha, const V& V_rhs1
00130   , const DVectorSlice& vs_rhs2)
00131 {
00132   VopV_assert_sizes(V_rhs1.dim(),vs_rhs2.dim());
00133   (*v_lhs) = vs_rhs2;
00134   Vp_StV(&(*v_lhs)(),alpha,V_rhs1);
00135 }
00136 
00137 // ///////////////////////////////////////////////////////////////////////////
00138 // operations with DVectorSlice as lhs
00139 
00140 // vs_lhs = V_rhs.
00141 template <class V>
00142 void assign(DVectorSlice* vs_lhs, const V& V_rhs) {
00143   Vp_V_assert_sizes( vs_lhs->dim(), V_rhs.dim() );
00144   (*vs_lhs) = 0.0;
00145   Vp_V(vs_lhs,V_rhs);
00146 }
00147 
00148 // vs_lhs = alpha * V_rhs.
00149 template <class V>
00150 void V_StV(DVectorSlice* vs_lhs, value_type alpha, const V& V_rhs) {
00151   Vp_V_assert_sizes( vs_lhs->dim(), V_rhs.dim() );
00152   (*vs_lhs) = 0.0;
00153   Vp_StV(vs_lhs,alpha,V_rhs);
00154 }
00155 
00156 // vs_lhs = V1_rhs1 + V2_rhs2.
00157 template <class V1, class V2>
00158 void V_VpV(DVectorSlice* vs_lhs, const V1& V1_rhs1, const V2& V2_rhs2) {
00159   VopV_assert_sizes(V1_rhs1.dim(),V2_rhs2.dim());
00160   Vp_V_assert_sizes( vs_lhs->dim(), V1_rhs1.dim() );
00161   (*vs_lhs) = 0.0;
00162   Vp_V(vs_lhs,V1_rhs1);
00163   Vp_V(vs_lhs,V2_rhs2);
00164 }
00165 
00166 // vs_lhs = V_rhs1 - V_rhs2.
00167 template <class V1, class V2>
00168 void V_VmV(DVectorSlice* vs_lhs, const V1& V1_rhs1, const V2& V2_rhs2) {
00169   VopV_assert_sizes(V1_rhs1.dim(),V2_rhs2.dim());
00170   Vp_V_assert_sizes( vs_lhs->dim(), V1_rhs1.dim() );
00171   (*vs_lhs) = 0.0;
00172   Vp_V(vs_lhs,V1_rhs1);
00173   Vp_StV(vs_lhs,-1.0,V2_rhs2);
00174 }
00175 
00176 // vs_lhs = alpha * V_rhs1 + vs_rhs2.
00177 template <class V>
00178 void V_StVpV(DVectorSlice* vs_lhs, value_type alpha, const V& V_rhs1
00179   , const DVectorSlice& vs_rhs2)
00180 {
00181   VopV_assert_sizes(V_rhs1.dim(),vs_rhs2.dim());
00182   (*vs_lhs) = vs_rhs2;
00183   Vp_StV(vs_lhs,alpha,V_rhs1);
00184 }
00185 
00186 // //////////////////////////////////////////////////////////////////////////////
00187 // ///////////////////////////////////////////////////////////////////////////////
00188 // Level 1 BLAS for Matrices
00189 
00190 // //////////////////////////////////////////////////////////////////////////////
00191 // += operations 
00192 
00193 
00194 // //////////////////////////////////////////////////////////////////////////////
00195 // operations with DMatrix as lhs
00196 
00197 // gm_lhs = op(M_rhs).
00198 template <class M>
00199 void assign(DMatrix* gm_lhs, const M& M_rhs, BLAS_Cpp::Transp trans_rhs) {
00200   gm_lhs->resize(  rows(M_rhs.rows(),M_rhs.cols(),trans_rhs)
00201           ,cols(M_rhs.rows(),M_rhs.cols(),trans_rhs) );
00202   (*gm_lhs) = 0.0;
00203   Mp_StM(&(*gm_lhs)(),1.0,M_rhs,trans_rhs);
00204 }
00205 
00206 // gm_lhs = alpha * op(M_rhs).
00207 template <class M>
00208 void M_StM(DMatrix* gm_lhs, value_type alpha, const M& M_rhs, BLAS_Cpp::Transp trans_rhs) {
00209   gm_lhs->resize(  rows(M_rhs.rows(),M_rhs.cols(),trans_rhs)
00210           ,cols(M_rhs.rows(),M_rhs.cols(),trans_rhs) );
00211   (*gm_lhs) = 0.0;
00212   Mp_StM(&(*gm_lhs)(),alpha,M_rhs,trans_rhs);
00213 }
00214 
00215 // gm_lhs = op(M1_rhs1) + op(M2_rhs2).
00216 template <class M1, class M2>
00217 void M_MpM(DMatrix* gm_lhs, const M1& M1_rhs1, BLAS_Cpp::Transp trans_rhs1
00218   , const M2& M2_rhs2, BLAS_Cpp::Transp trans_rhs2)
00219 {
00220   MopM_assert_sizes(   M1_rhs1.rows(),M1_rhs1.cols(),trans_rhs1
00221             ,M2_rhs2.rows(),M2_rhs2.cols(),trans_rhs2 );
00222   gm_lhs->resize(  rows(M1_rhs1.rows(),M1_rhs1.cols(),trans_rhs1)
00223           ,cols(M1_rhs1.rows(),M1_rhs1.cols(),trans_rhs2) );
00224   (*gm_lhs) = 0.0;
00225   DMatrixSlice gms_lhs(*gm_lhs);
00226   Mp_M(&gms_lhs,M1_rhs1,trans_rhs1);
00227   Mp_M(&gms_lhs,M2_rhs2,trans_rhs2);
00228 }
00229 
00230 // gm_lhs = op(M_rhs1) - op(M_rhs2).
00231 template <class M1, class M2>
00232 void M_MmM(DMatrix* gm_lhs, const M1& M1_rhs1, BLAS_Cpp::Transp trans_rhs1
00233   , const M2& M2_rhs2, BLAS_Cpp::Transp trans_rhs2)
00234 {
00235   MopM_assert_sizes(   M1_rhs1.rows(),M1_rhs1.cols(),trans_rhs1
00236             ,M2_rhs2.rows(),M2_rhs2.cols(),trans_rhs2 );
00237   gm_lhs->resize(  rows(M1_rhs1.rows(),M1_rhs1.cols(),trans_rhs1)
00238           ,cols(M1_rhs1.rows(),M1_rhs1.cols(),trans_rhs1) );
00239   (*gm_lhs) = 0.0;
00240   DMatrixSlice gms_lhs(*gm_lhs);
00241   Mp_M(&gms_lhs,M1_rhs1,trans_rhs1);
00242   Mp_StM(&gms_lhs,-1.0,M2_rhs2,trans_rhs2);
00243 }
00244 
00245 // gm_lhs = alpha * op(M_rhs1) + op(gms_rhs2).
00246 template <class M>
00247 void M_StMpM(DMatrix* gm_lhs, value_type alpha, const M& M_rhs1, BLAS_Cpp::Transp trans_rhs1
00248   , const DMatrixSlice& gms_rhs2, BLAS_Cpp::Transp trans_rhs2)
00249 {
00250   MopM_assert_sizes(   M_rhs1.rows(),M_rhs1.cols(),trans_rhs1
00251             ,gms_rhs2.rows(),gms_rhs2.cols(),trans_rhs2);
00252   assign(gm_lhs,gms_rhs2,trans_rhs2);
00253   Mp_StM(&(*gm_lhs)(),alpha,M_rhs1,trans_rhs1);
00254 }
00255 
00256 // //////////////////////////////////////////////////////////////////////////////
00257 // operations with DMatrixSlice as lhs
00258 
00259 // gms_lhs = op(M_rhs).
00260 template <class M>
00261 void assign(DMatrixSlice* gms_lhs, const M& M_rhs, BLAS_Cpp::Transp trans_rhs) {
00262   Mp_M_assert_sizes(gms_lhs->rows(), gms_lhs->cols(), BLAS_Cpp::no_trans
00263     , M_rhs.rows(), M_rhs.cols(), trans_rhs );
00264   (*gms_lhs) = 0.0;
00265   Mp_StM(gms_lhs,1.0,M_rhs,trans_rhs);
00266 }
00267 
00268 // gms_lhs = alpha * op(M_rhs).
00269 template <class M>
00270 void M_StM(DMatrixSlice* gms_lhs, value_type alpha, const M& M_rhs, BLAS_Cpp::Transp trans_rhs) {
00271   Mp_M_assert_sizes(gms_lhs->rows(), gms_lhs->cols(), BLAS_Cpp::no_trans
00272     , M_rhs.rows(), M_rhs.cols(), trans_rhs );
00273   (*gms_lhs) = 0.0;
00274   Mp_StM(gms_lhs,alpha,M_rhs,trans_rhs);
00275 }
00276 
00277 // gms_lhs = op(M1_rhs1) + op(M2_rhs2).
00278 template <class M1, class M2>
00279 void M_MpM(DMatrixSlice* gms_lhs, const M1& M1_rhs1, BLAS_Cpp::Transp trans_rhs1
00280   , const M2& M2_rhs2, BLAS_Cpp::Transp trans_rhs2)
00281 {
00282   MopM_assert_sizes(   M1_rhs1.rows(),M1_rhs1.cols(),trans_rhs1
00283             ,M2_rhs2.rows(),M2_rhs2.cols(),trans_rhs2 );
00284   assert_gms_lhs(*gms_lhs, rows(M1_rhs1.rows(),M1_rhs1.cols(),trans_rhs1)
00285                , cols(M1_rhs1.rows(),M1_rhs1.cols(),trans_rhs1) );
00286   (*gms_lhs) = 0.0;
00287   Mp_M(gms_lhs,M1_rhs1,trans_rhs1);
00288   Mp_M(gms_lhs,M2_rhs2,trans_rhs2);
00289 }
00290 
00291 // gms_lhs = op(M_rhs1) - op(M_rhs2).
00292 template <class M1, class M2>
00293 void M_MmM(DMatrixSlice* gms_lhs, const M1& M1_rhs1, BLAS_Cpp::Transp trans_rhs1
00294   , const M2& M2_rhs2, BLAS_Cpp::Transp trans_rhs2)
00295 {
00296   MopM_assert_sizes(   M1_rhs1.rows(),M1_rhs1.cols(),trans_rhs1
00297             ,M2_rhs2.rows(),M2_rhs2.cols(),trans_rhs2 );
00298   assert_gms_lhs(*gms_lhs, rows(M1_rhs1.rows(),M1_rhs1.cols(),trans_rhs1)
00299                , cols(M1_rhs1.rows(),M1_rhs1.cols(),trans_rhs1) );
00300   (*gms_lhs) = 0.0;
00301   Mp_M(gms_lhs,M1_rhs1,trans_rhs1);
00302   Mp_StM(gms_lhs,-1.0,M2_rhs2,trans_rhs2);
00303 }
00304 
00305 // gms_lhs = alpha * op(M_rhs1) + op(gms_rhs2).
00306 template <class M>
00307 void M_StMpM(DMatrixSlice* gms_lhs, value_type alpha, const M& M_rhs1, BLAS_Cpp::Transp trans_rhs1
00308   , const DMatrixSlice& gms_rhs2, BLAS_Cpp::Transp trans_rhs2)
00309 {
00310   MopM_assert_sizes(   M_rhs1.rows(),M_rhs1.cols(),trans_rhs1
00311             ,gms_rhs2.rows(),gms_rhs2.cols(),trans_rhs2);
00312   assign(gms_lhs,gms_rhs2,trans_rhs2);
00313   Mp_StM(gms_lhs,alpha,M_rhs1,trans_rhs1);
00314 }
00315 
00316 // //////////////////////////////////////////////////////////////////////////////
00317 // /////////////////////////////////////////////////////////////////////// /////
00318 // Level 2 BLAS
00319 
00320 // //////////////////////////////////////////////////////////////////////////////
00321 // += operations
00322 
00323 // //////////////////////////////////////////////////////////////////////////////
00324 // operations with DVector as lhs
00325 
00326 // v_lhs = alpha * op(M_rhs1) * V_rhs2.
00327 template <class M, class V>
00328 void V_StMtV(DVector* v_lhs, value_type alpha, const M& M_rhs1
00329   , BLAS_Cpp::Transp trans_rhs1, const V& V_rhs2)
00330 {
00331   MtV_assert_sizes(M_rhs1.rows(),M_rhs1.cols(),trans_rhs1,V_rhs2.dim());
00332   v_lhs->resize(rows(M_rhs1.rows(),M_rhs1.cols(),trans_rhs1));
00333   Vp_StMtV(&(*v_lhs)(),alpha,M_rhs1,trans_rhs1,V_rhs2,0.0);
00334 }
00335 
00336 // v_lhs = op(M_rhs1) * V_rhs2.
00337 template <class M, class V>
00338 void V_MtV(DVector* v_lhs, const M& M_rhs1, BLAS_Cpp::Transp trans_rhs1
00339   , const V& V_rhs2)
00340 {
00341   MtV_assert_sizes(M_rhs1.rows(),M_rhs1.cols(),trans_rhs1,V_rhs2.dim());
00342   v_lhs->resize(rows(M_rhs1.rows(),M_rhs1.cols(),trans_rhs1));
00343   Vp_StMtV(&(*v_lhs)(),1.0,M_rhs1,trans_rhs1,V_rhs2,0.0);
00344 }
00345 
00346 // //////////////////////////////////////////////////////////////////////////////
00347 // operations with DVectorSlice as lhs
00348 
00349 // vs_lhs = alpha * op(M_rhs1) * V_rhs2.
00350 template <class M, class V>
00351 void V_StMtV(DVectorSlice* vs_lhs, value_type alpha, const M& M_rhs1
00352   , BLAS_Cpp::Transp trans_rhs1, const V& V_rhs2)
00353 {
00354   MtV_assert_sizes(M_rhs1.rows(),M_rhs1.cols(),trans_rhs1,V_rhs2.dim());
00355   Vp_V_assert_sizes( vs_lhs->dim(), rows(M_rhs1.rows(),M_rhs1.cols(),trans_rhs1) );
00356   Vp_StMtV(vs_lhs,alpha,M_rhs1,trans_rhs1,V_rhs2,0.0);
00357 }
00358 
00359 // vs_lhs = op(M_rhs1) * V_rhs2.
00360 template <class M, class V>
00361 void V_MtV(DVectorSlice* vs_lhs, const M& M_rhs1, BLAS_Cpp::Transp trans_rhs1
00362   , const V& V_rhs2)
00363 {
00364   MtV_assert_sizes(M_rhs1.rows(),M_rhs1.cols(),trans_rhs1,V_rhs2.dim());
00365   Vp_V_assert_sizes( vs_lhs->dim(), rows(M_rhs1.rows(),M_rhs1.cols(),trans_rhs1) );
00366   Vp_StMtV(vs_lhs,1.0,M_rhs1,trans_rhs1,V_rhs2,0.0);
00367 }
00368 
00369 // //////////////////////////////////////////////////////////////////////////////
00370 // //////////////////////////////////////////////////////////////////////////////
00371 // Level 3 BLAS
00372 
00373 // //////////////////////////////////////////////////////////////////////////////
00374 // += operations 
00375 
00376 // //////////////////////////////////////////////////////////////////////////////
00377 // = operations with DMatrix as lhs
00378 
00379 // gm_lhs = alpha * op(M1_rhs1) * op(M2_rhs2).
00380 template <class M1, class M2>
00381 void M_StMtM(DMatrix* gm_lhs, value_type alpha, const M1& M1_rhs1
00382   , BLAS_Cpp::Transp trans_rhs1, const M2& M2_rhs2, BLAS_Cpp::Transp trans_rhs2)
00383 {
00384   MtM_assert_sizes(   M1_rhs1.rows(), M1_rhs1.cols(), trans_rhs1
00385             , M2_rhs2.rows(), M2_rhs2.cols(), trans_rhs2 );
00386   gm_lhs->resize(   rows(M1_rhs1.rows(), M1_rhs1.cols(), trans_rhs1)
00387           , cols(M2_rhs2.rows(), M2_rhs2.cols(), trans_rhs2) );
00388   Mp_StMtM(&(*gm_lhs)(),alpha,M1_rhs1,trans_rhs1,M2_rhs2,trans_rhs2,0.0);
00389 }
00390 
00391 // gm_lhs = op(M1_rhs1) * op(M2_rhs2).
00392 template <class M1, class M2>
00393 void M_MtM(DMatrix* gm_lhs, const M1& M1_rhs1
00394   , BLAS_Cpp::Transp trans_rhs1, const M2& M2_rhs2, BLAS_Cpp::Transp trans_rhs2)
00395 {
00396   MtM_assert_sizes(   M1_rhs1.rows(), M1_rhs1.cols(), trans_rhs1
00397             , M2_rhs2.rows(), M2_rhs2.cols(), trans_rhs2 );
00398   gm_lhs->resize(   rows(M1_rhs1.rows(), M1_rhs1.cols(), trans_rhs1)
00399           , cols(M2_rhs2.rows(), M2_rhs2.cols(), trans_rhs2) );
00400   Mp_StMtM(&(*gm_lhs)(),1.0,M1_rhs1,trans_rhs1,M2_rhs2,trans_rhs2,0.0);
00401 }
00402 
00403 // //////////////////////////////////////////////////////////////////////////////
00404 // = operations with DMatrixSlice as lhs
00405 
00406 // gms_lhs = alpha * op(M1_rhs1) * op(M2_rhs2).
00407 template <class M1, class M2>
00408 void M_StMtM(DMatrixSlice* gms_lhs, value_type alpha, const M1& M1_rhs1
00409   , BLAS_Cpp::Transp trans_rhs1, const M2& M2_rhs2, BLAS_Cpp::Transp trans_rhs2)
00410 {
00411   MtM_assert_sizes(   M1_rhs1.rows(), M1_rhs1.cols(), trans_rhs1
00412             , M2_rhs2.rows(), M2_rhs2.cols(), trans_rhs2 );
00413   assert_gms_lhs(   *gms_lhs
00414           , rows(M1_rhs1.rows(), M1_rhs1.cols(), trans_rhs1)
00415           , cols(M2_rhs2.rows(), M2_rhs2.cols(), trans_rhs2) );
00416   Mp_StMtM(gms_lhs,alpha,M1_rhs1,trans_rhs1,M2_rhs2,trans_rhs2,0.0);
00417 }
00418 
00419 // gms_lhs = op(M1_rhs1) * op(M2_rhs2).
00420 template <class M1, class M2>
00421 void M_MtM(DMatrixSlice* gms_lhs, const M1& M1_rhs1
00422   , BLAS_Cpp::Transp trans_rhs1, const M2& M2_rhs2, BLAS_Cpp::Transp trans_rhs2)
00423 {
00424   MtM_assert_sizes(   M1_rhs1.rows(), M1_rhs1.cols(), trans_rhs1
00425             , M2_rhs2.rows(), M2_rhs2.cols(), trans_rhs2 );
00426   assert_gms_lhs(   gms_lhs
00427           , rows(M1_rhs1.rows(), M1_rhs1.cols(), trans_rhs1)
00428           , cols(M2_rhs2.rows(), M2_rhs2.cols(), trans_rhs2) );
00429   Mp_StMtM(gms_lhs,1.0,M1_rhs1,trans_rhs1,M2_rhs2,trans_rhs2,0,0);
00430 }
00431 
00432 } // end namespace LinAlgOpPack
00433 
00434 
00435 #endif // LIN_ALG_OP_PACK_DEF_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines