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_DMatrixOp.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 // Basic DMatrix / DMatrixSlice operation functions.
43 //
44 // Changes: 6/9/98:
45 // * I simplified the set of functions to only include direct analogs to
46 // BLAS routines. Addition operations are derived from these and some
47 // of the simplifications are given in LinAlgPackOp.h.
48 // * Testing for aliasing was removed since it provides overhead
49 // and is only a problem if the lhs argment apears in the rhs. Also it
50 // will simpify maintance.
51 // * Changed the naming convension for matrices so that so that they all
52 // (rectangular, triangular and symmetric) all use just "M".
53 // * Triangular and symmetric matrices are now aggregated into simple
54 // classes to simplify the interface and usage.
55 // * 6/12/98: the assignment functions were moved into a seperate file
56 // to remove circular dependencies that existed.
57 
58 #ifndef GEN_MATRIX_OP_H
59 #define GEN_MATRIX_OP_H
60 
61 #include "DenseLinAlgPack_Types.hpp"
62 #include "DenseLinAlgPack_AssertOp.hpp"
63 #include "DenseLinAlgPack_DMatrixClass.hpp"
64 #include "DenseLinAlgPack_DMatrixAsTriSym.hpp"
65 #include "DenseLinAlgPack_DVectorOp.hpp"
66 
67 /* * @name {\bf Basic DMatrix Operation Functions (Level 2,3 BLAS)}.
68  *
69  * These funtions perform that basic linear algebra operations involving; vectors,
70  * rectangular matrices, triangular matrices, and symmetric matrices. The types
71  * for the matrices passed to these functions are DMatrix and DMatrixSlice.
72  * These rectangular matrices can be treated conseptually as square triangular (DMatrixSliceTri)
73  * and symmetric (DMatrixSliceSym) matrices. The functions are ment to provide the basic computations
74  * for wrapper classes for triangular (unit diagonal, uppper and lower etc.)
75  * and symetric (upper or lower triangular storage) which will provide better type
76  * safty than is achieved by using these function directly.
77  *
78  * The implementations of these functions takes care of the following details:
79  *
80  * <ul>
81  * <li> Resizing DMatrix LHS on assignment
82  * <li> Checking preconditions (sizes of arguments) if \Ref{LINALGPACK_CHECK_RHS_SIZES} is defined
83  * </ul>
84  *
85  * The preconditions for all of the functions are that the sizes of the rhs arguments
86  * and lhs arguments agree. If they do not and \Ref{LINALGPACK_CHECK_RHS_SIZES}
87  * is defined, then those functions will throw a #std::length_error# exception.
88  *
89  * Naming convenstion for algebric functions.
90  *
91  * Algebraic funcitons are named according to their types and the operations on those
92  * types. For example, condider the functions:
93  *
94  * #V_VpV(...)# => #DVectorSlice = DVectorSlice + DVectorSlice# \\
95  * #Vp_StV(...)# => #DVectorSlice += Scalar * DVectorSlice#
96  *
97  * Reading the first function identifier from left to right, the first letter 'V' stands for the
98  * type of the lhs argument. The underscore character is ment to stand for the equal sign '='.
99  * The last part of the identifer name, 'VpV' stands for the binary plus operation "V + V".
100  * In the second function the characters 'p_' stands for the '+=' operation.
101  *
102  * The character identifiers for the types of the operands are (all uppercase):
103  *
104  * \begin{center}
105  * \begin{tabular}{ll}
106  * types & abreviation \\
107  * \hline
108  * scalar (value_type) & S \\
109  * 1-D vectors (DVector (lhs), DVectorSlice) & V \\
110  * 2-D matrices (DMatrix (lhs)
111  * , DMatrixSlice, DMatrixSliceTri, DMatrixSliceTriEle
112  * , DMatrixSliceSym) & M \\
113  * \end{tabular}
114  * \end{center}
115  *
116  * The identifers for the arithmetic operations are (all lowercase):
117  *
118  * \begin{center}
119  * \begin{tabular}{ll}
120  * Arithmetic operation & abreviation \\
121  * \hline
122  * + (binary plus) & p \\
123  * - (binary minus and unary negation) & m \\
124  * * (binary multiplation, times) & t \\
125  * \end{tabular}
126  * \end{center}
127  *
128  * The types and order of the arguments to these algebraic functions is also
129  * associated with the names of the identifer of the function. The lhs
130  * argument(s) always appears first as in the identifer name. The the
131  * rhs argment(s) appear as they appear in the identifer name. Each type
132  * operand as one or more arguments associated with it. For example, a 'V'
133  * for DVectorSlice in a rhs expression only has the type argument 'const DVectorSlice&'.
134  * A matrix, whether it is rectangular (DMatrixSlice), triangular (DMatrixSliceTri, DMatrixSliceTriEle)
135  * or symmetric (DMatrixSliceSym).
136  *
137  * The identifer names and the corresponding type arguments are:
138  *
139  * \begin{center}
140  * \begin{tabular}{ll}
141  * {\bf Abreviation} & {\bf Arguments} \\
142  * \hline
143  * S & #value_type# \\
144  * V (DVector, lhs only) & #DVector&# \\
145  * V (DVectorSlice, lhs) & #DVectorSlice&# \\
146  * V (DVectorSlice, rhs) & #const DVectorSlice&# \\
147  * M (DMatrix, lhs only) & #DMatrix&# \\
148  * M (DMatrixSlice, lhs) & #DMatrixSlice&# \\
149  * M (DMatrixSlice, rhs) & #const DMatrixSlice&, BLAS_Cpp::Transp# \\
150  * M (Element-wise operation
151  * Triangular DMatrixSlice
152  * , lhs) & #DMatrixSliceTriEle&# \\
153  * M (Element-wise operation
154  * Triangular DMatrixSlice
155  * , rhs) & #const DMatrixSliceTriEle&, BLAS_Cpp::Transp# \\
156  * M (Structure dependent operation
157  * Triangular DMatrixSlice
158  * , rhs only) & #const DMatrixSliceTri&, BLAS_Cpp::Transp# \\
159  * M (Symmetric DMatrixSlice
160  * , lhs) & #DMatrixSliceTri&# \\
161  * M (Symmetric DMatrixSlice
162  * , rhs) & #cosnt DMatrixSliceTri&, BLAS_Cpp::Transp# \\
163  * \end{tabular}
164  * \end{center}
165  *
166  * Using the table above you can deduce the argments by looking at the function identifer name.
167  * For example, the function #V_MtV# using a triangular matrix and a DVector as the lhs the argument
168  * type list is:
169  * #(DVector&, const DMatrixSliceTri&, BLAS_Cpp::Transp, BLAS_Cpp::Diag, const DVectorSlice&)#.
170  *
171  * The only variation on this rule is with operations such as: \\
172  * vs_lhs = alpha * op(gms_rhs1) * vs_rhs2 + beta * vs_lhs.\\
173  * For this type of operation the vs_lhs argument is not included twise as the function would
174  * be prototyped as:
175  *
176  * #void Vp_StMtV(DVectorSlice& vs_lhs, value_type alpha, const DMatrixSlice& gms_rhs1
177  * , BLAS_Cpp::Transp trans_rhs1, const DVectorSlice& vs_rhs2, value_type beta);#
178  *
179  * These operations are designed to work with the LinAlgPackOp template functions.
180  * These template functions provide default implementations for variations on
181  * these operations. The BLAS operations for triangular matrix solves do not fit in with
182  * this system of template functions.
183  *
184  * In general it is not allowed that the lhs argument appear in the rhs expression.
185  * The only exception to this are the Level 2 and 3 BLAS operations that involve
186  * triangular matrices. Here it is allowed because this is the way the BLAS routines
187  * are defined.
188  */
189 // @{
190 
191 namespace DenseLinAlgPack {
192 
193 // /////////////////////////////////////////////////////////////////////////////////////////
194 /* * @name {\bf Element-wise Algebraic Operations}.
195  *
196  * These functions that implement element-wise operations for rectangular
197  * and triangular regions of matrices. The rhs operands can be transposed
198  * (op(rhs1) = rhs) or non-transposed (op(rhs1) = trans(rhs1)).
199  *
200  * Functions for triangular matrices allow mixes of upper and lower
201  * triangular regions. Therefore, they provide the machinary for
202  * element-wise operations for triangular and symmetric matrices.
203  */
204 // @{
205 
207 void Mt_S(DMatrixSlice* gms_lhs, value_type alpha);
208 
210 void M_diagVtM( DMatrixSlice* gms_lhs, const DVectorSlice& vs_rhs
211  , const DMatrixSlice& gms_rhs, BLAS_Cpp::Transp trans_rhs );
212 
214 void Mt_S(DMatrixSliceTriEle* tri_lhs, value_type alpha);
215 
217 void Mp_StM(DMatrixSliceTriEle* tri_lhs, value_type alpha, const DMatrixSliceTriEle& tri_rhs);
218 
219 /* * @name LinAlgOpPack compatable (compile-time polymorphism).
220  */
221 // @{
222 
224 void Mp_StM(DMatrixSlice* gms_lhs, value_type alpha, const DMatrixSlice& gms_rhs
225  , BLAS_Cpp::Transp trans_rhs);
226 
228 void Mp_StM(DMatrixSlice* gms_lhs, value_type alpha, const DMatrixSliceSym& sym_rhs
229  , BLAS_Cpp::Transp trans_rhs);
230 
232 void Mp_StM(DMatrixSlice* gms_lhs, value_type alpha, const DMatrixSliceTri& tri_rhs
233  , BLAS_Cpp::Transp trans_rhs);
234 
235 // @}
236 
237 // inline
238 // /// tri_lhs += alpha * tri_rhs (needed for LinAlgOpPack)
239 // void Mp_StM(DMatrixSliceTriEle* tri_lhs, value_type alpha, const DMatrixSliceTriEle& tri_rhs
240 // , BLAS_Cpp::Transp)
241 //{
242 // Mp_StM(tri_lhs, alpha, tri_rhs);
243 //}
244 
245 // end Element-wise Algebraic Operations
246 // @}
247 
248 // /////////////////////////////////////////////////////////////////////////////////////
249 /* * @name {\bf Level-2 BLAS (vector-matrtix) Liner Algebra Operations}.
250  *
251  * These functions are setup as nearly direct calls to the level-2 BLAS.
252  */
253 
254 // @{
255 
257 void Vp_StMtV(DVectorSlice* vs_lhs, value_type alpha, const DMatrixSlice& gms_rhs1
258  , BLAS_Cpp::Transp trans_rhs1, const DVectorSlice& vs_rhs2, value_type beta = 1.0);
259 
261 /* * vs_lhs = alpha * op(sym_rhs1) * vs_rhs2 + beta * vs_lhs. (BLAS xSYMV).
262  *
263  * The transpose argument #trans_rhs1# is ignored and is only included so that
264  * it is compatable with the LinAlgPackOp template functions.
265  */
266 void Vp_StMtV(DVectorSlice* vs_lhs, value_type alpha, const DMatrixSliceSym& sym_rhs1
267  , BLAS_Cpp::Transp trans_rhs1, const DVectorSlice& vs_rhs2, value_type beta = 1.0);
268 
270 /* * v_lhs = op(tri_rhs1) * vs_rhs2 (BLAS xTRMV)
271  *
272  * Here vs_rhs2 and v_lhs can be the same vector.
273  *
274  * Here vs_rhs2 is assigned to v_lhs so if v_lhs is the same as vs_rhs2
275  * no unnecessary copy will be performed before the BLAS function trmv(...)
276  * is called.
277  */
278 void V_MtV(DVector* v_lhs, const DMatrixSliceTri& tri_rhs1, BLAS_Cpp::Transp trans_rhs1
279  , const DVectorSlice& vs_rhs2);
280 
282 /* * vs_lhs = op(tri_rhs1) * vs_rhs2 (BLAS xTRMV)
283  *
284  * Same as previous accept for a DVectorSlice as the lhs.
285  */
286 void V_MtV(DVectorSlice* vs_lhs, const DMatrixSliceTri& tri_rhs1, BLAS_Cpp::Transp trans_rhs1
287  , const DVectorSlice& vs_rhs2);
288 
290 /* * vs_lhs = alpha * op(tri_rhs1) * vs_rhs2 + beta * vs_lhs.
291  *
292  * This function is needed for use with the LinAlgPackOp template functions.
293  * Here vs_lhs and vs_rhs2 may be the same vector because of the way that
294  * the template functions work.
295  *
296  * This function calls #V_MtV(tmp, tri_rhs1, trans_rhs1, vs_rhs2);#
297  * where #tmp# is a temporary vector to hold the result of the operation.
298  *
299  */
300 void Vp_StMtV(DVectorSlice* vs_lhs, value_type alpha, const DMatrixSliceTri& tri_rhs1
301  , BLAS_Cpp::Transp trans_rhs1, const DVectorSlice& vs_rhs2, value_type beta = 1.0);
302 
304 /* * v_lhs = inv(op(tri_rhs1)) * vs_rhs2 (BLAS xTRSV)
305  *
306  * Here vs_rhs2 is assigned to v_lhs so if v_lhs is the same as vs_rhs2
307  * no unnecessary copy will be performed before the BLAS function trsv(...)
308  * is called.
309  *
310  * There are no LinAlgPackOp template functions compatable with this operation.
311  */
312 void V_InvMtV(DVector* v_lhs, const DMatrixSliceTri& tri_rhs1, BLAS_Cpp::Transp trans_rhs1
313  , const DVectorSlice& vs_rhs2);
314 
316 /* * vs_lhs = inv(op(tri_rhs1)) * vs_rhs2 (BLAS xTRSV)
317  *
318  * Same as above except for DVectorSlice as lhs.
319  */
320 void V_InvMtV(DVectorSlice* vs_lhs, const DMatrixSliceTri& tri_rhs1, BLAS_Cpp::Transp trans_rhs1
321  , const DVectorSlice& vs_rhs2);
322 
324 /* * gms_lhs = alpha * vs_rhs1 * vs_rhs2' + gms_lhs (BLAS xGER).
325  *
326  * This results in a direct call the the BLAS function ger(...).
327  * Since this function is performing a special linear algebra operation (a rank-1 update)
328  * it does not use the specal naming sceme as the rest of the more typical operations.
329  * The arguments are ordered similarly to the BLAS specification.
330  *
331  * There is no analog to this operation in the LinAlgPackOp template functions.
332  */
333 void ger(value_type alpha, const DVectorSlice& vs_rhs1, const DVectorSlice& vs_rhs2
334  , DMatrixSlice* gms_lhs);
335 
337 /* * sym_lhs = alpha * vs_rhs * vs_rhs' + sym_lhs (BLAS xSYR).
338  *
339  * This results in a direct call the the BLAS function syr(...).
340  * Since this function is performing a special linear algebra operation (a rank-1 update)
341  * it does not use the specal naming sceme as the rest of the more typical operations.
342  * The arguments are ordered similarly to the BLAS specification.
343  *
344  * There is no analog to this operation in the LinAlgPackOp template functions.
345  */
346 void syr(value_type alpha, const DVectorSlice& vs_rhs, DMatrixSliceSym* sym_lhs);
347 
349 /* * sym_lhs = alpha * vs_rhs1 * vs_rhs2' + alpha * vs_rhs2 * vs_rhs1' + sym_lhs (BLAS xSYR2).
350  *
351  * There is no analog to this operation in the LinAlgPackOp template functions.
352  */
353 void syr2(value_type alpha, const DVectorSlice& vs_rhs1, const DVectorSlice& vs_rhs2
354  , DMatrixSliceSym* sym_lhs);
355 
356 // end Level-2 BLAS (vector-matrtix) Liner Algebra Operations
357 // @}
358 
359 // //////////////////////////////////////////////////////////////////////////////////////////
360 /* * @name {\bf Level-3 BLAS (matrix-matrix) Linear Algebra Operations}.
361  *
362  */
363 
364 // @{
365 // begin Level-3 BLAS (matrix-matrix) Linear Algebra Operations
366 
367 // ////////////////////////////
368 /* * @name Rectangular Matrices
369  */
370 // @{
371 
373 /* * gms_lhs = alpha * op(gms_rhs1) * op(gms_rhs2) + beta * gms_lhs (BLAS xGEMV).
374  *
375  * This function results in a nearly direct call the the BLAS gemv(...) function.
376  * No temporaries need to be created.
377  */
378 void Mp_StMtM(DMatrixSlice* gms_lhs, value_type alpha, const DMatrixSlice& gms_rhs1
379  , BLAS_Cpp::Transp trans_rhs1, const DMatrixSlice& gms_rhs2
380  , BLAS_Cpp::Transp trans_rhs2, value_type beta = 1.0);
381 
382 // end Rectangular Matrices
383 // @}
384 
385 // ////////////////////////////
386 /* * @name Symmetric Matrices
387  */
388 // @{
389 
391 /* * gms_lhs = alpha * op(sym_rhs1) * op(gms_rhs2) + beta * gms_lhs (left) (BLAS xSYMM).
392  *
393  * The straight BLAS call would be:
394  *
395  * gms_lhs = alpha * sym_rhs1 * gms_rhs2 + beta * gms_lhs
396  *
397  * but for compatability with the LinAlgPackOp template functions this form is
398  * used instead. The first transpose argument #trans_rhs1# is ignorned.
399  * If #trans_rhs2 == BLAS_Cpp::trans# then a temporary copy of #gms_rhs2# must
400  * be made to directly call the BLAS function symm(...).
401  *
402  */
403 void Mp_StMtM(DMatrixSlice* gms_lhs, value_type alpha, const DMatrixSliceSym& sym_rhs1
404  , BLAS_Cpp::Transp trans_rhs1, const DMatrixSlice& gms_rhs2
405  , BLAS_Cpp::Transp trans_rhs2, value_type beta = 1.0);
406 
408 /* * gms_lhs = alpha * op(gms_rhs1) * op(sym_rhs2) + beta * gms_lhs (right) (BLAS xSYMM).
409  *
410  * This function is similar to the previous one accept the symmeric matrix now appears
411  * to the right. Again #trans_rhs2# is ignored and a tempory matrix will be created
412  * if #trans_rhs1 == BLAS_Cpp::trans#.
413  */
414 void Mp_StMtM(DMatrixSlice* gms_lhs, value_type alpha, const DMatrixSlice& gms_rhs1
415  , BLAS_Cpp::Transp trans_rhs1, const DMatrixSliceSym& sym_rhs2
416  , BLAS_Cpp::Transp trans_rhs2, value_type beta = 1.0);
417 
419 /* * sym_lhs = alpha * op(gms_rhs) * op(gms_rhs') + beta * sym_lhs (BLAS xSYRK).
420  *
421  * This results in a direct call the the BLAS function syrk(...).
422  * Since this function is performing a special linear algebra operation (a rank-k update)
423  * it does not use the specal naming sceme as the rest of the more typical operations.
424  * The arguments are ordered similarly to the BLAS specification.
425  *
426  * There is no analog to this operation in the LinAlgPackOp template functions.
427  */
428 void syrk(BLAS_Cpp::Transp trans, value_type alpha, const DMatrixSlice& gms_rhs
429  , value_type beta, DMatrixSliceSym* sym_lhs);
430 
432 /* * sym_lhs = alpha * op(gms_rhs1) * op(gms_rhs2') + alpha * op(gms_rhs2) * op(gms_rhs1')
433  * + beta * sym_lhs (BLAS xSYR2K).
434  *
435  * Like syrk(...) this is a specialized linear algebra operation and does not follow the
436  * standard naming sceme.
437  *
438  * There is no analog to this operation in the LinAlgPackOp template functions.
439  */
440 void syr2k(BLAS_Cpp::Transp trans,value_type alpha, const DMatrixSlice& gms_rhs1
441  , const DMatrixSlice& gms_rhs2, value_type beta, DMatrixSliceSym* sym_lhs);
442 
443 // end Symmetric Matrices
444 // @}
445 
446 // ////////////////////////////
447 /* * @name Triangular Matrices
448  */
449 // @{
450 
452 /* * gm_lhs = alpha * op(tri_rhs1) * op(gms_rhs2) (left) (BLAS xTRMM).
453  *
454  * Here op(gms_rhs2) and gms_lhs can be the same matrix .
455  *
456  * For the BLAS operation trmm(...) to be called #assign(gm_lhs,gms_rhs2,trans_rhs2)#
457  * is called first.
458  */
459 void M_StMtM(DMatrix* gm_lhs, value_type alpha, const DMatrixSliceTri& tri_rhs1
460  , BLAS_Cpp::Transp trans_rhs1, const DMatrixSlice& gms_rhs2
461  , BLAS_Cpp::Transp trans_rhs2);
462 
464 /* * gms_lhs = alpha * op(tri_rhs1) * op(gms_rhs2) (left) (BLAS xTRMM).
465  *
466  * Same as above accept for DMatrixSlice as the lhs.
467  */
468 void M_StMtM(DMatrixSlice* gms_lhs, value_type alpha, const DMatrixSliceTri& tri_rhs1
469  , BLAS_Cpp::Transp trans_rhs1, const DMatrixSlice& gms_rhs2
470  , BLAS_Cpp::Transp trans_rhs2);
471 
473 /* * gm_lhs = alpha * op(gms_rhs1) * op(tri_rhs2) (right) (BLAS xTRMM).
474  *
475  * Here op(gms_rhs1) and gms_lhs can be the same matrix .
476  *
477  * For the BLAS operation trmm(...) to be called #assign(gm_lhs,gms_rhs1,trans_rhs1)#
478  * is called first. This form is used so that it conforms to
479  * the LinAlgPackOp template functions.
480  */
481 void M_StMtM(DMatrix* gm_lhs, value_type alpha, const DMatrixSlice& gms_rhs1
482  , BLAS_Cpp::Transp trans_rhs1, const DMatrixSliceTri& tri_rhs2
483  , BLAS_Cpp::Transp trans_rhs2);
484 
486 /* * gms_lhs = alpha * op(gms_rhs1) * op(tri_rhs2) (right) (BLAS xTRMM).
487  *
488  * Same as above accept for DMatrixSlice as the lhs.
489  */
490 void M_StMtM(DMatrixSlice* gms_lhs, value_type alpha, const DMatrixSlice& gms_rhs1
491  , BLAS_Cpp::Transp trans_rhs1, const DMatrixSliceTri& tri_rhs2
492  , BLAS_Cpp::Transp trans_rhs2);
493 
495 /* * gms_lhs = alpha * op(tri_rhs1) * op(gms_rhs2) + beta * gms_lhs (left).
496  *
497  * This form is included to conform with the LinAlgPackOp template functions.
498  * For this to work, a temporary (#tmp#) is created to hold the result of the
499  * matrix-matrix product.
500  *
501  * It calls #M_StMtM(&tmp,alpha,tri_rhs1,trans_rhs1,gms_rhs2,trans_rhs2);#
502  */
503 void Mp_StMtM(DMatrixSlice* gms_lhs, value_type alpha, const DMatrixSliceTri& tri_rhs1
504  , BLAS_Cpp::Transp trans_rhs1, const DMatrixSlice& gms_rhs2
505  , BLAS_Cpp::Transp trans_rhs2, value_type beta = 1.0);
506 
508 /* * gms_lhs = alpha * op(gms_rhs1) * op(tri_rhs2) + beta * gms_lhs (right).
509  *
510  * This form is included to conform with the LinAlgPackOp template functions.
511  * For this to work, a temporary (#tmp#) is created to hold the result of the
512  * matrix-matrix product.
513  *
514  * It calls #M_StMtM(&tmp,alpha,gms_rhs1,trans_rhs1,tri_rhs2,trans_rhs2);#
515  */
516 void Mp_StMtM(DMatrixSlice* gms_lhs, value_type alpha, const DMatrixSlice& gms_rhs1
517  , BLAS_Cpp::Transp trans_rhs1, const DMatrixSliceTri& tri_rhs2
518  , BLAS_Cpp::Transp trans_rhs2, value_type beta = 1.0);
519 
521 /* * gm_lhs = alpha * inv(op(tri_rhs1)) * op(gms_rhs2) (left) (BLAS xTRSM).
522  *
523  * For the BLAS trsm(...) function to be called #assign(gm_lhs,gms_rhs2,trans_rhs2)#
524  * is called first.
525  *
526  * There is no analog to this operation in the LinAlgPackOp template functions.
527  */
528 void M_StInvMtM(DMatrix* gm_lhs, value_type alpha, const DMatrixSliceTri& tri_rhs1
529  , BLAS_Cpp::Transp trans_rhs1, const DMatrixSlice& gms_rhs2
530  , BLAS_Cpp::Transp trans_rhs2);
531 
533 /* * gms_lhs = alpha * inv(op(tri_rhs1)) * op(gms_rhs2) (left) (BLAS xTRSM).
534  *
535  * Same as above accept for DMatrixSlice as the lhs.
536  */
537 void M_StInvMtM(DMatrixSlice* gms_lhs, value_type alpha, const DMatrixSliceTri& tri_rhs1
538  , BLAS_Cpp::Transp trans_rhs1, const DMatrixSlice& gms_rhs2
539  , BLAS_Cpp::Transp trans_rhs2);
540 
542 /* * gm_lhs = alpha * op(gms_rhs1) * inv(op(tri_rhs2)) (right) (BLAS xTRSM).
543  *
544  * For the BLAS trsm(...) function to be called #assign(gm_lhs,gms_rhs1,trans_rhs1)#
545  * is called first.
546  *
547  * There is no analog to this operation in the LinAlgPackOp template functions.
548  */
549 void M_StMtInvM(DMatrix* gm_lhs, value_type alpha, const DMatrixSlice& gms_rhs1
550  , BLAS_Cpp::Transp trans_rhs1, const DMatrixSliceTri& tri_rhs2
551  , BLAS_Cpp::Transp trans_rhs2);
552 
554 /* * gms_lhs = alpha * op(gms_rhs1) * inv(op(tri_rhs2)) (right) (BLAS xTRSM).
555  *
556  * Same as above accept for DMatrixSlice as the lhs.
557  */
558 void M_StMtInvM(DMatrixSlice* gm_lhs, value_type alpha, const DMatrixSlice& gms_rhs1
559  , BLAS_Cpp::Transp trans_rhs1, const DMatrixSliceTri& tri_rhs2
560  , BLAS_Cpp::Transp trans_rhs2);
561 
562 // end Triangular Matrices
563 // @}
564 
565 // end Level-3 BLAS (matrix-matrix) Linear Algebra Operations
566 // @}
567 
568 } // end namespace DenseLinAlgPack
569 
570 // //////////////////////////////////////////////////////////////////////////////////////
571 // Inline function definitions
572 
573 // end Basic DMatrix Operation Functions
574 // @}
575 
576 #endif // GEN_MATRIX_OP_H
Transp