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