DenseLinAlgPack: Concreate C++ Classes for Dense Blas-Compatible Linear Algebra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
DenseLinAlgPack_LinAlgOpPackDef.hpp
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization
5 // Copyright (2003) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #ifndef LIN_ALG_OP_PACK_DEF_H
43 #define LIN_ALG_OP_PACK_DEF_H
44 
45 #include "DenseLinAlgPack_LinAlgOpPackDecl.hpp" // also includes some inline function definitions
46 #include "DenseLinAlgPack_AssertOp.hpp"
47 #include "DenseLinAlgPack_DMatrixClass.hpp"
48 
49 namespace LinAlgOpPack {
50 
51 using BLAS_Cpp::rows;
52 using BLAS_Cpp::cols;
53 
54 // Inject assert functions
55 using DenseLinAlgPack::assert_gms_lhs;
56 using DenseLinAlgPack::Vp_V_assert_sizes;
57 using DenseLinAlgPack::VopV_assert_sizes;
58 using DenseLinAlgPack::Mp_M_assert_sizes;
59 using DenseLinAlgPack::MopM_assert_sizes;
60 using DenseLinAlgPack::Vp_MtV_assert_sizes;
61 using DenseLinAlgPack::MtV_assert_sizes;
62 using DenseLinAlgPack::MtM_assert_sizes;
63 
64 // Inject names of base linear algebra functions for DenseLinAlgPack.
65 // Note that this is neccesary in MS VC++ 5.0 because
66 // it does not perform name lookups properly but it
67 // is not adverse to the standard so it is a portable
68 // fix.
69 using DenseLinAlgPack::assign;
70 using DenseLinAlgPack::Vt_S;
71 using DenseLinAlgPack::Vp_StV;
72 using DenseLinAlgPack::Vp_StMtV;
73 using DenseLinAlgPack::Mt_S;
74 using DenseLinAlgPack::Mp_StM;
75 using DenseLinAlgPack::Mp_StMtM;
76 
77 // ///////////////////////////////////////////////////////////////////////////////
78 // ///////////////////////////////////////////////////////////////////////////////
79 // Level 1 BLAS for Vectors
80 
81 // //////////////////////////////////////////////////////////////////////////////
82 // += operations
83 
84 // //////////////////////////////////////////////////////////////////////////////
85 // operations with DVector as lhs
86 
87 // v_lhs = V_rhs.
88 template <class V>
89 void assign(DVector* v_lhs, const V& V_rhs) {
90  v_lhs->resize(V_rhs.dim());
91  (*v_lhs) = 0.0;
92  Vp_V(&(*v_lhs)(),V_rhs);
93 }
94 
95 // v_lhs = alpha * V_rhs.
96 template <class V>
97 void V_StV(DVector* v_lhs, value_type alpha, const V& V_rhs) {
98  v_lhs->resize(V_rhs.dim());
99  (*v_lhs) = 0.0;
100  Vp_StV(&(*v_lhs)(),alpha,V_rhs);
101 }
102 
103 // v_lhs = V1_rhs1 + V2_rhs2.
104 template <class V1, class V2>
105 void V_VpV(DVector* v_lhs, const V1& V1_rhs1, const V2& V2_rhs2) {
106  VopV_assert_sizes(V1_rhs1.dim(),V2_rhs2.dim());
107  v_lhs->resize(V1_rhs1.dim());
108  (*v_lhs) = 0.0;
109  DVectorSlice vs_lhs(*v_lhs);
110  Vp_V(&vs_lhs,V1_rhs1);
111  Vp_V(&vs_lhs,V2_rhs2);
112 }
113 
114 
115 // v_lhs = V_rhs1 - V_rhs2.
116 template <class V1, class V2>
117 void V_VmV(DVector* v_lhs, const V1& V1_rhs1, const V2& V2_rhs2) {
118  VopV_assert_sizes(V1_rhs1.dim(),V2_rhs2.dim());
119  v_lhs->resize(V1_rhs1.dim());
120  (*v_lhs) = 0.0;
121  DVectorSlice vs_lhs(*v_lhs);
122  Vp_V(&vs_lhs,V1_rhs1);
123  Vp_StV(&vs_lhs,-1.0,V2_rhs2);
124 }
125 
126 
127 // v_lhs = alpha * V_rhs1 + vs_rhs2.
128 template <class V>
129 void V_StVpV(DVector* v_lhs, value_type alpha, const V& V_rhs1
130  , const DVectorSlice& vs_rhs2)
131 {
132  VopV_assert_sizes(V_rhs1.dim(),vs_rhs2.dim());
133  (*v_lhs) = vs_rhs2;
134  Vp_StV(&(*v_lhs)(),alpha,V_rhs1);
135 }
136 
137 // ///////////////////////////////////////////////////////////////////////////
138 // operations with DVectorSlice as lhs
139 
140 // vs_lhs = V_rhs.
141 template <class V>
142 void assign(DVectorSlice* vs_lhs, const V& V_rhs) {
143  Vp_V_assert_sizes( vs_lhs->dim(), V_rhs.dim() );
144  (*vs_lhs) = 0.0;
145  Vp_V(vs_lhs,V_rhs);
146 }
147 
148 // vs_lhs = alpha * V_rhs.
149 template <class V>
150 void V_StV(DVectorSlice* vs_lhs, value_type alpha, const V& V_rhs) {
151  Vp_V_assert_sizes( vs_lhs->dim(), V_rhs.dim() );
152  (*vs_lhs) = 0.0;
153  Vp_StV(vs_lhs,alpha,V_rhs);
154 }
155 
156 // vs_lhs = V1_rhs1 + V2_rhs2.
157 template <class V1, class V2>
158 void V_VpV(DVectorSlice* vs_lhs, const V1& V1_rhs1, const V2& V2_rhs2) {
159  VopV_assert_sizes(V1_rhs1.dim(),V2_rhs2.dim());
160  Vp_V_assert_sizes( vs_lhs->dim(), V1_rhs1.dim() );
161  (*vs_lhs) = 0.0;
162  Vp_V(vs_lhs,V1_rhs1);
163  Vp_V(vs_lhs,V2_rhs2);
164 }
165 
166 // vs_lhs = V_rhs1 - V_rhs2.
167 template <class V1, class V2>
168 void V_VmV(DVectorSlice* vs_lhs, const V1& V1_rhs1, const V2& V2_rhs2) {
169  VopV_assert_sizes(V1_rhs1.dim(),V2_rhs2.dim());
170  Vp_V_assert_sizes( vs_lhs->dim(), V1_rhs1.dim() );
171  (*vs_lhs) = 0.0;
172  Vp_V(vs_lhs,V1_rhs1);
173  Vp_StV(vs_lhs,-1.0,V2_rhs2);
174 }
175 
176 // vs_lhs = alpha * V_rhs1 + vs_rhs2.
177 template <class V>
178 void V_StVpV(DVectorSlice* vs_lhs, value_type alpha, const V& V_rhs1
179  , const DVectorSlice& vs_rhs2)
180 {
181  VopV_assert_sizes(V_rhs1.dim(),vs_rhs2.dim());
182  (*vs_lhs) = vs_rhs2;
183  Vp_StV(vs_lhs,alpha,V_rhs1);
184 }
185 
186 // //////////////////////////////////////////////////////////////////////////////
187 // ///////////////////////////////////////////////////////////////////////////////
188 // Level 1 BLAS for Matrices
189 
190 // //////////////////////////////////////////////////////////////////////////////
191 // += operations
192 
193 
194 // //////////////////////////////////////////////////////////////////////////////
195 // operations with DMatrix as lhs
196 
197 // gm_lhs = op(M_rhs).
198 template <class M>
199 void assign(DMatrix* gm_lhs, const M& M_rhs, BLAS_Cpp::Transp trans_rhs) {
200  gm_lhs->resize( rows(M_rhs.rows(),M_rhs.cols(),trans_rhs)
201  ,cols(M_rhs.rows(),M_rhs.cols(),trans_rhs) );
202  (*gm_lhs) = 0.0;
203  Mp_StM(&(*gm_lhs)(),1.0,M_rhs,trans_rhs);
204 }
205 
206 // gm_lhs = alpha * op(M_rhs).
207 template <class M>
208 void M_StM(DMatrix* gm_lhs, value_type alpha, const M& M_rhs, BLAS_Cpp::Transp trans_rhs) {
209  gm_lhs->resize( rows(M_rhs.rows(),M_rhs.cols(),trans_rhs)
210  ,cols(M_rhs.rows(),M_rhs.cols(),trans_rhs) );
211  (*gm_lhs) = 0.0;
212  Mp_StM(&(*gm_lhs)(),alpha,M_rhs,trans_rhs);
213 }
214 
215 // gm_lhs = op(M1_rhs1) + op(M2_rhs2).
216 template <class M1, class M2>
217 void M_MpM(DMatrix* gm_lhs, const M1& M1_rhs1, BLAS_Cpp::Transp trans_rhs1
218  , const M2& M2_rhs2, BLAS_Cpp::Transp trans_rhs2)
219 {
220  MopM_assert_sizes( M1_rhs1.rows(),M1_rhs1.cols(),trans_rhs1
221  ,M2_rhs2.rows(),M2_rhs2.cols(),trans_rhs2 );
222  gm_lhs->resize( rows(M1_rhs1.rows(),M1_rhs1.cols(),trans_rhs1)
223  ,cols(M1_rhs1.rows(),M1_rhs1.cols(),trans_rhs2) );
224  (*gm_lhs) = 0.0;
225  DMatrixSlice gms_lhs(*gm_lhs);
226  Mp_M(&gms_lhs,M1_rhs1,trans_rhs1);
227  Mp_M(&gms_lhs,M2_rhs2,trans_rhs2);
228 }
229 
230 // gm_lhs = op(M_rhs1) - op(M_rhs2).
231 template <class M1, class M2>
232 void M_MmM(DMatrix* gm_lhs, const M1& M1_rhs1, BLAS_Cpp::Transp trans_rhs1
233  , const M2& M2_rhs2, BLAS_Cpp::Transp trans_rhs2)
234 {
235  MopM_assert_sizes( M1_rhs1.rows(),M1_rhs1.cols(),trans_rhs1
236  ,M2_rhs2.rows(),M2_rhs2.cols(),trans_rhs2 );
237  gm_lhs->resize( rows(M1_rhs1.rows(),M1_rhs1.cols(),trans_rhs1)
238  ,cols(M1_rhs1.rows(),M1_rhs1.cols(),trans_rhs1) );
239  (*gm_lhs) = 0.0;
240  DMatrixSlice gms_lhs(*gm_lhs);
241  Mp_M(&gms_lhs,M1_rhs1,trans_rhs1);
242  Mp_StM(&gms_lhs,-1.0,M2_rhs2,trans_rhs2);
243 }
244 
245 // gm_lhs = alpha * op(M_rhs1) + op(gms_rhs2).
246 template <class M>
247 void M_StMpM(DMatrix* gm_lhs, value_type alpha, const M& M_rhs1, BLAS_Cpp::Transp trans_rhs1
248  , const DMatrixSlice& gms_rhs2, BLAS_Cpp::Transp trans_rhs2)
249 {
250  MopM_assert_sizes( M_rhs1.rows(),M_rhs1.cols(),trans_rhs1
251  ,gms_rhs2.rows(),gms_rhs2.cols(),trans_rhs2);
252  assign(gm_lhs,gms_rhs2,trans_rhs2);
253  Mp_StM(&(*gm_lhs)(),alpha,M_rhs1,trans_rhs1);
254 }
255 
256 // //////////////////////////////////////////////////////////////////////////////
257 // operations with DMatrixSlice as lhs
258 
259 // gms_lhs = op(M_rhs).
260 template <class M>
261 void assign(DMatrixSlice* gms_lhs, const M& M_rhs, BLAS_Cpp::Transp trans_rhs) {
262  Mp_M_assert_sizes(gms_lhs->rows(), gms_lhs->cols(), BLAS_Cpp::no_trans
263  , M_rhs.rows(), M_rhs.cols(), trans_rhs );
264  (*gms_lhs) = 0.0;
265  Mp_StM(gms_lhs,1.0,M_rhs,trans_rhs);
266 }
267 
268 // gms_lhs = alpha * op(M_rhs).
269 template <class M>
270 void M_StM(DMatrixSlice* gms_lhs, value_type alpha, const M& M_rhs, BLAS_Cpp::Transp trans_rhs) {
271  Mp_M_assert_sizes(gms_lhs->rows(), gms_lhs->cols(), BLAS_Cpp::no_trans
272  , M_rhs.rows(), M_rhs.cols(), trans_rhs );
273  (*gms_lhs) = 0.0;
274  Mp_StM(gms_lhs,alpha,M_rhs,trans_rhs);
275 }
276 
277 // gms_lhs = op(M1_rhs1) + op(M2_rhs2).
278 template <class M1, class M2>
279 void M_MpM(DMatrixSlice* gms_lhs, const M1& M1_rhs1, BLAS_Cpp::Transp trans_rhs1
280  , const M2& M2_rhs2, BLAS_Cpp::Transp trans_rhs2)
281 {
282  MopM_assert_sizes( M1_rhs1.rows(),M1_rhs1.cols(),trans_rhs1
283  ,M2_rhs2.rows(),M2_rhs2.cols(),trans_rhs2 );
284  assert_gms_lhs(*gms_lhs, rows(M1_rhs1.rows(),M1_rhs1.cols(),trans_rhs1)
285  , cols(M1_rhs1.rows(),M1_rhs1.cols(),trans_rhs1) );
286  (*gms_lhs) = 0.0;
287  Mp_M(gms_lhs,M1_rhs1,trans_rhs1);
288  Mp_M(gms_lhs,M2_rhs2,trans_rhs2);
289 }
290 
291 // gms_lhs = op(M_rhs1) - op(M_rhs2).
292 template <class M1, class M2>
293 void M_MmM(DMatrixSlice* gms_lhs, const M1& M1_rhs1, BLAS_Cpp::Transp trans_rhs1
294  , const M2& M2_rhs2, BLAS_Cpp::Transp trans_rhs2)
295 {
296  MopM_assert_sizes( M1_rhs1.rows(),M1_rhs1.cols(),trans_rhs1
297  ,M2_rhs2.rows(),M2_rhs2.cols(),trans_rhs2 );
298  assert_gms_lhs(*gms_lhs, rows(M1_rhs1.rows(),M1_rhs1.cols(),trans_rhs1)
299  , cols(M1_rhs1.rows(),M1_rhs1.cols(),trans_rhs1) );
300  (*gms_lhs) = 0.0;
301  Mp_M(gms_lhs,M1_rhs1,trans_rhs1);
302  Mp_StM(gms_lhs,-1.0,M2_rhs2,trans_rhs2);
303 }
304 
305 // gms_lhs = alpha * op(M_rhs1) + op(gms_rhs2).
306 template <class M>
307 void M_StMpM(DMatrixSlice* gms_lhs, value_type alpha, const M& M_rhs1, BLAS_Cpp::Transp trans_rhs1
308  , const DMatrixSlice& gms_rhs2, BLAS_Cpp::Transp trans_rhs2)
309 {
310  MopM_assert_sizes( M_rhs1.rows(),M_rhs1.cols(),trans_rhs1
311  ,gms_rhs2.rows(),gms_rhs2.cols(),trans_rhs2);
312  assign(gms_lhs,gms_rhs2,trans_rhs2);
313  Mp_StM(gms_lhs,alpha,M_rhs1,trans_rhs1);
314 }
315 
316 // //////////////////////////////////////////////////////////////////////////////
317 // /////////////////////////////////////////////////////////////////////// /////
318 // Level 2 BLAS
319 
320 // //////////////////////////////////////////////////////////////////////////////
321 // += operations
322 
323 // //////////////////////////////////////////////////////////////////////////////
324 // operations with DVector as lhs
325 
326 // v_lhs = alpha * op(M_rhs1) * V_rhs2.
327 template <class M, class V>
328 void V_StMtV(DVector* v_lhs, value_type alpha, const M& M_rhs1
329  , BLAS_Cpp::Transp trans_rhs1, const V& V_rhs2)
330 {
331  MtV_assert_sizes(M_rhs1.rows(),M_rhs1.cols(),trans_rhs1,V_rhs2.dim());
332  v_lhs->resize(rows(M_rhs1.rows(),M_rhs1.cols(),trans_rhs1));
333  Vp_StMtV(&(*v_lhs)(),alpha,M_rhs1,trans_rhs1,V_rhs2,0.0);
334 }
335 
336 // v_lhs = op(M_rhs1) * V_rhs2.
337 template <class M, class V>
338 void V_MtV(DVector* v_lhs, const M& M_rhs1, BLAS_Cpp::Transp trans_rhs1
339  , const V& V_rhs2)
340 {
341  MtV_assert_sizes(M_rhs1.rows(),M_rhs1.cols(),trans_rhs1,V_rhs2.dim());
342  v_lhs->resize(rows(M_rhs1.rows(),M_rhs1.cols(),trans_rhs1));
343  Vp_StMtV(&(*v_lhs)(),1.0,M_rhs1,trans_rhs1,V_rhs2,0.0);
344 }
345 
346 // //////////////////////////////////////////////////////////////////////////////
347 // operations with DVectorSlice as lhs
348 
349 // vs_lhs = alpha * op(M_rhs1) * V_rhs2.
350 template <class M, class V>
351 void V_StMtV(DVectorSlice* vs_lhs, value_type alpha, const M& M_rhs1
352  , BLAS_Cpp::Transp trans_rhs1, const V& V_rhs2)
353 {
354  MtV_assert_sizes(M_rhs1.rows(),M_rhs1.cols(),trans_rhs1,V_rhs2.dim());
355  Vp_V_assert_sizes( vs_lhs->dim(), rows(M_rhs1.rows(),M_rhs1.cols(),trans_rhs1) );
356  Vp_StMtV(vs_lhs,alpha,M_rhs1,trans_rhs1,V_rhs2,0.0);
357 }
358 
359 // vs_lhs = op(M_rhs1) * V_rhs2.
360 template <class M, class V>
361 void V_MtV(DVectorSlice* vs_lhs, const M& M_rhs1, BLAS_Cpp::Transp trans_rhs1
362  , const V& V_rhs2)
363 {
364  MtV_assert_sizes(M_rhs1.rows(),M_rhs1.cols(),trans_rhs1,V_rhs2.dim());
365  Vp_V_assert_sizes( vs_lhs->dim(), rows(M_rhs1.rows(),M_rhs1.cols(),trans_rhs1) );
366  Vp_StMtV(vs_lhs,1.0,M_rhs1,trans_rhs1,V_rhs2,0.0);
367 }
368 
369 // //////////////////////////////////////////////////////////////////////////////
370 // //////////////////////////////////////////////////////////////////////////////
371 // Level 3 BLAS
372 
373 // //////////////////////////////////////////////////////////////////////////////
374 // += operations
375 
376 // //////////////////////////////////////////////////////////////////////////////
377 // = operations with DMatrix as lhs
378 
379 // gm_lhs = alpha * op(M1_rhs1) * op(M2_rhs2).
380 template <class M1, class M2>
381 void M_StMtM(DMatrix* gm_lhs, value_type alpha, const M1& M1_rhs1
382  , BLAS_Cpp::Transp trans_rhs1, const M2& M2_rhs2, BLAS_Cpp::Transp trans_rhs2)
383 {
384  MtM_assert_sizes( M1_rhs1.rows(), M1_rhs1.cols(), trans_rhs1
385  , M2_rhs2.rows(), M2_rhs2.cols(), trans_rhs2 );
386  gm_lhs->resize( rows(M1_rhs1.rows(), M1_rhs1.cols(), trans_rhs1)
387  , cols(M2_rhs2.rows(), M2_rhs2.cols(), trans_rhs2) );
388  Mp_StMtM(&(*gm_lhs)(),alpha,M1_rhs1,trans_rhs1,M2_rhs2,trans_rhs2,0.0);
389 }
390 
391 // gm_lhs = op(M1_rhs1) * op(M2_rhs2).
392 template <class M1, class M2>
393 void M_MtM(DMatrix* gm_lhs, const M1& M1_rhs1
394  , BLAS_Cpp::Transp trans_rhs1, const M2& M2_rhs2, BLAS_Cpp::Transp trans_rhs2)
395 {
396  MtM_assert_sizes( M1_rhs1.rows(), M1_rhs1.cols(), trans_rhs1
397  , M2_rhs2.rows(), M2_rhs2.cols(), trans_rhs2 );
398  gm_lhs->resize( rows(M1_rhs1.rows(), M1_rhs1.cols(), trans_rhs1)
399  , cols(M2_rhs2.rows(), M2_rhs2.cols(), trans_rhs2) );
400  Mp_StMtM(&(*gm_lhs)(),1.0,M1_rhs1,trans_rhs1,M2_rhs2,trans_rhs2,0.0);
401 }
402 
403 // //////////////////////////////////////////////////////////////////////////////
404 // = operations with DMatrixSlice as lhs
405 
406 // gms_lhs = alpha * op(M1_rhs1) * op(M2_rhs2).
407 template <class M1, class M2>
408 void M_StMtM(DMatrixSlice* gms_lhs, value_type alpha, const M1& M1_rhs1
409  , BLAS_Cpp::Transp trans_rhs1, const M2& M2_rhs2, BLAS_Cpp::Transp trans_rhs2)
410 {
411  MtM_assert_sizes( M1_rhs1.rows(), M1_rhs1.cols(), trans_rhs1
412  , M2_rhs2.rows(), M2_rhs2.cols(), trans_rhs2 );
413  assert_gms_lhs( *gms_lhs
414  , rows(M1_rhs1.rows(), M1_rhs1.cols(), trans_rhs1)
415  , cols(M2_rhs2.rows(), M2_rhs2.cols(), trans_rhs2) );
416  Mp_StMtM(gms_lhs,alpha,M1_rhs1,trans_rhs1,M2_rhs2,trans_rhs2,0.0);
417 }
418 
419 // gms_lhs = op(M1_rhs1) * op(M2_rhs2).
420 template <class M1, class M2>
421 void M_MtM(DMatrixSlice* gms_lhs, const M1& M1_rhs1
422  , BLAS_Cpp::Transp trans_rhs1, const M2& M2_rhs2, BLAS_Cpp::Transp trans_rhs2)
423 {
424  MtM_assert_sizes( M1_rhs1.rows(), M1_rhs1.cols(), trans_rhs1
425  , M2_rhs2.rows(), M2_rhs2.cols(), trans_rhs2 );
426  assert_gms_lhs( gms_lhs
427  , rows(M1_rhs1.rows(), M1_rhs1.cols(), trans_rhs1)
428  , cols(M2_rhs2.rows(), M2_rhs2.cols(), trans_rhs2) );
429  Mp_StMtM(gms_lhs,1.0,M1_rhs1,trans_rhs1,M2_rhs2,trans_rhs2,0,0);
430 }
431 
432 } // end namespace LinAlgOpPack
433 
434 
435 #endif // LIN_ALG_OP_PACK_DEF_H
size_type rows(size_type rows, size_type cols, BLAS_Cpp::Transp _trans)
Transp
size_type cols(size_type rows, size_type cols, BLAS_Cpp::Transp _trans)