|
DenseLinAlgPack: Concreate C++ Classes for Dense Blas-Compatible Linear Algebra
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 #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
1.7.6.1