1: #region Translated by Jose Antonio De Santiago-Castillo.
2:
3: //Translated by Jose Antonio De Santiago-Castillo.
4: //E-mail:JAntonioDeSantiago@gmail.com
5: //Web: www.DotNumerics.com
6: //
7: //Fortran to C# Translation.
8: //Translated by:
9: //F2CSharp Version 0.71 (November 10, 2009)
10: //Code Optimizations: None
11: //
12: #endregion
13:
14: using System;
15: using DotNumerics.FortranLibrary;
16:
17: namespace DotNumerics.CSLapack
18: {
19: /// <summary>
20: /// Purpose
21: /// =======
22: ///
23: /// DTRMM performs one of the matrix-matrix operations
24: ///
25: /// B := alpha*op( A )*B, or B := alpha*B*op( A ),
26: ///
27: /// where alpha is a scalar, B is an m by n matrix, A is a unit, or
28: /// non-unit, upper or lower triangular matrix and op( A ) is one of
29: ///
30: /// op( A ) = A or op( A ) = A'.
31: ///
32: /// Parameters
33: /// ==========
34: ///
35: /// SIDE - CHARACTER*1.
36: /// On entry, SIDE specifies whether op( A ) multiplies B from
37: /// the left or right as follows:
38: ///
39: /// SIDE = 'L' or 'l' B := alpha*op( A )*B.
40: ///
41: /// SIDE = 'R' or 'r' B := alpha*B*op( A ).
42: ///
43: /// Unchanged on exit.
44: ///
45: /// UPLO - CHARACTER*1.
46: /// On entry, UPLO specifies whether the matrix A is an upper or
47: /// lower triangular matrix as follows:
48: ///
49: /// UPLO = 'U' or 'u' A is an upper triangular matrix.
50: ///
51: /// UPLO = 'L' or 'l' A is a lower triangular matrix.
52: ///
53: /// Unchanged on exit.
54: ///
55: /// TRANSA - CHARACTER*1.
56: /// On entry, TRANSA specifies the form of op( A ) to be used in
57: /// the matrix multiplication as follows:
58: ///
59: /// TRANSA = 'N' or 'n' op( A ) = A.
60: ///
61: /// TRANSA = 'T' or 't' op( A ) = A'.
62: ///
63: /// TRANSA = 'C' or 'c' op( A ) = A'.
64: ///
65: /// Unchanged on exit.
66: ///
67: /// DIAG - CHARACTER*1.
68: /// On entry, DIAG specifies whether or not A is unit triangular
69: /// as follows:
70: ///
71: /// DIAG = 'U' or 'u' A is assumed to be unit triangular.
72: ///
73: /// DIAG = 'N' or 'n' A is not assumed to be unit
74: /// triangular.
75: ///
76: /// Unchanged on exit.
77: ///
78: /// M - INTEGER.
79: /// On entry, M specifies the number of rows of B. M must be at
80: /// least zero.
81: /// Unchanged on exit.
82: ///
83: /// N - INTEGER.
84: /// On entry, N specifies the number of columns of B. N must be
85: /// at least zero.
86: /// Unchanged on exit.
87: ///
88: /// ALPHA - DOUBLE PRECISION.
89: /// On entry, ALPHA specifies the scalar alpha. When alpha is
90: /// zero then A is not referenced and B need not be set before
91: /// entry.
92: /// Unchanged on exit.
93: ///
94: /// A - DOUBLE PRECISION array of DIMENSION ( LDA, k ), where k is m
95: /// when SIDE = 'L' or 'l' and is n when SIDE = 'R' or 'r'.
96: /// Before entry with UPLO = 'U' or 'u', the leading k by k
97: /// upper triangular part of the array A must contain the upper
98: /// triangular matrix and the strictly lower triangular part of
99: /// A is not referenced.
100: /// Before entry with UPLO = 'L' or 'l', the leading k by k
101: /// lower triangular part of the array A must contain the lower
102: /// triangular matrix and the strictly upper triangular part of
103: /// A is not referenced.
104: /// Note that when DIAG = 'U' or 'u', the diagonal elements of
105: /// A are not referenced either, but are assumed to be unity.
106: /// Unchanged on exit.
107: ///
108: /// LDA - INTEGER.
109: /// On entry, LDA specifies the first dimension of A as declared
110: /// in the calling (sub) program. When SIDE = 'L' or 'l' then
111: /// LDA must be at least max( 1, m ), when SIDE = 'R' or 'r'
112: /// then LDA must be at least max( 1, n ).
113: /// Unchanged on exit.
114: ///
115: /// B - DOUBLE PRECISION array of DIMENSION ( LDB, n ).
116: /// Before entry, the leading m by n part of the array B must
117: /// contain the matrix B, and on exit is overwritten by the
118: /// transformed matrix.
119: ///
120: /// LDB - INTEGER.
121: /// On entry, LDB specifies the first dimension of B as declared
122: /// in the calling (sub) program. LDB must be at least
123: /// max( 1, m ).
124: /// Unchanged on exit.
125: ///</summary>
126: public class DTRMM
127: {
128:
129:
130: #region Dependencies
131:
132: LSAME _lsame; XERBLA _xerbla;
133:
134: #endregion
135:
136:
137: #region Fields
138:
139: bool LSIDE = false; bool NOUNIT = false; bool UPPER = false; int I = 0; int INFO = 0; int J = 0; int K = 0; int NROWA = 0;
140: double TEMP = 0;const double ONE = 1.0E+0; const double ZERO = 0.0E+0;
141:
142: #endregion
143:
144: public DTRMM(LSAME lsame, XERBLA xerbla)
145: {
146:
147:
148: #region Set Dependencies
149:
150: this._lsame = lsame; this._xerbla = xerbla;
151:
152: #endregion
153:
154: }
155:
156: public DTRMM()
157: {
158:
159:
160: #region Dependencies (Initialization)
161:
162: LSAME lsame = new LSAME();
163: XERBLA xerbla = new XERBLA();
164:
165: #endregion
166:
167:
168: #region Set Dependencies
169:
170: this._lsame = lsame; this._xerbla = xerbla;
171:
172: #endregion
173:
174: }
175: /// <summary>
176: /// Purpose
177: /// =======
178: ///
179: /// DTRMM performs one of the matrix-matrix operations
180: ///
181: /// B := alpha*op( A )*B, or B := alpha*B*op( A ),
182: ///
183: /// where alpha is a scalar, B is an m by n matrix, A is a unit, or
184: /// non-unit, upper or lower triangular matrix and op( A ) is one of
185: ///
186: /// op( A ) = A or op( A ) = A'.
187: ///
188: /// Parameters
189: /// ==========
190: ///
191: /// SIDE - CHARACTER*1.
192: /// On entry, SIDE specifies whether op( A ) multiplies B from
193: /// the left or right as follows:
194: ///
195: /// SIDE = 'L' or 'l' B := alpha*op( A )*B.
196: ///
197: /// SIDE = 'R' or 'r' B := alpha*B*op( A ).
198: ///
199: /// Unchanged on exit.
200: ///
201: /// UPLO - CHARACTER*1.
202: /// On entry, UPLO specifies whether the matrix A is an upper or
203: /// lower triangular matrix as follows:
204: ///
205: /// UPLO = 'U' or 'u' A is an upper triangular matrix.
206: ///
207: /// UPLO = 'L' or 'l' A is a lower triangular matrix.
208: ///
209: /// Unchanged on exit.
210: ///
211: /// TRANSA - CHARACTER*1.
212: /// On entry, TRANSA specifies the form of op( A ) to be used in
213: /// the matrix multiplication as follows:
214: ///
215: /// TRANSA = 'N' or 'n' op( A ) = A.
216: ///
217: /// TRANSA = 'T' or 't' op( A ) = A'.
218: ///
219: /// TRANSA = 'C' or 'c' op( A ) = A'.
220: ///
221: /// Unchanged on exit.
222: ///
223: /// DIAG - CHARACTER*1.
224: /// On entry, DIAG specifies whether or not A is unit triangular
225: /// as follows:
226: ///
227: /// DIAG = 'U' or 'u' A is assumed to be unit triangular.
228: ///
229: /// DIAG = 'N' or 'n' A is not assumed to be unit
230: /// triangular.
231: ///
232: /// Unchanged on exit.
233: ///
234: /// M - INTEGER.
235: /// On entry, M specifies the number of rows of B. M must be at
236: /// least zero.
237: /// Unchanged on exit.
238: ///
239: /// N - INTEGER.
240: /// On entry, N specifies the number of columns of B. N must be
241: /// at least zero.
242: /// Unchanged on exit.
243: ///
244: /// ALPHA - DOUBLE PRECISION.
245: /// On entry, ALPHA specifies the scalar alpha. When alpha is
246: /// zero then A is not referenced and B need not be set before
247: /// entry.
248: /// Unchanged on exit.
249: ///
250: /// A - DOUBLE PRECISION array of DIMENSION ( LDA, k ), where k is m
251: /// when SIDE = 'L' or 'l' and is n when SIDE = 'R' or 'r'.
252: /// Before entry with UPLO = 'U' or 'u', the leading k by k
253: /// upper triangular part of the array A must contain the upper
254: /// triangular matrix and the strictly lower triangular part of
255: /// A is not referenced.
256: /// Before entry with UPLO = 'L' or 'l', the leading k by k
257: /// lower triangular part of the array A must contain the lower
258: /// triangular matrix and the strictly upper triangular part of
259: /// A is not referenced.
260: /// Note that when DIAG = 'U' or 'u', the diagonal elements of
261: /// A are not referenced either, but are assumed to be unity.
262: /// Unchanged on exit.
263: ///
264: /// LDA - INTEGER.
265: /// On entry, LDA specifies the first dimension of A as declared
266: /// in the calling (sub) program. When SIDE = 'L' or 'l' then
267: /// LDA must be at least max( 1, m ), when SIDE = 'R' or 'r'
268: /// then LDA must be at least max( 1, n ).
269: /// Unchanged on exit.
270: ///
271: /// B - DOUBLE PRECISION array of DIMENSION ( LDB, n ).
272: /// Before entry, the leading m by n part of the array B must
273: /// contain the matrix B, and on exit is overwritten by the
274: /// transformed matrix.
275: ///
276: /// LDB - INTEGER.
277: /// On entry, LDB specifies the first dimension of B as declared
278: /// in the calling (sub) program. LDB must be at least
279: /// max( 1, m ).
280: /// Unchanged on exit.
281: ///</summary>
282: /// <param name="SIDE">
283: /// - CHARACTER*1.
284: /// On entry, SIDE specifies whether op( A ) multiplies B from
285: /// the left or right as follows:
286: ///
287: /// SIDE = 'L' or 'l' B := alpha*op( A )*B.
288: ///
289: /// SIDE = 'R' or 'r' B := alpha*B*op( A ).
290: ///
291: /// Unchanged on exit.
292: ///</param>
293: /// <param name="UPLO">
294: /// - CHARACTER*1.
295: /// On entry, UPLO specifies whether the matrix A is an upper or
296: /// lower triangular matrix as follows:
297: ///
298: /// UPLO = 'U' or 'u' A is an upper triangular matrix.
299: ///
300: /// UPLO = 'L' or 'l' A is a lower triangular matrix.
301: ///
302: /// Unchanged on exit.
303: ///</param>
304: /// <param name="TRANSA">
305: /// - CHARACTER*1.
306: /// On entry, TRANSA specifies the form of op( A ) to be used in
307: /// the matrix multiplication as follows:
308: ///
309: /// TRANSA = 'N' or 'n' op( A ) = A.
310: ///
311: /// TRANSA = 'T' or 't' op( A ) = A'.
312: ///
313: /// TRANSA = 'C' or 'c' op( A ) = A'.
314: ///
315: /// Unchanged on exit.
316: ///</param>
317: /// <param name="DIAG">
318: /// - CHARACTER*1.
319: /// On entry, DIAG specifies whether or not A is unit triangular
320: /// as follows:
321: ///
322: /// DIAG = 'U' or 'u' A is assumed to be unit triangular.
323: ///
324: /// DIAG = 'N' or 'n' A is not assumed to be unit
325: /// triangular.
326: ///
327: /// Unchanged on exit.
328: ///</param>
329: /// <param name="M">
330: /// - INTEGER.
331: /// On entry, M specifies the number of rows of B. M must be at
332: /// least zero.
333: /// Unchanged on exit.
334: ///</param>
335: /// <param name="N">
336: /// - INTEGER.
337: /// On entry, N specifies the number of columns of B. N must be
338: /// at least zero.
339: /// Unchanged on exit.
340: ///</param>
341: /// <param name="ALPHA">
342: /// - DOUBLE PRECISION.
343: /// On entry, ALPHA specifies the scalar alpha. When alpha is
344: /// zero then A is not referenced and B need not be set before
345: /// entry.
346: /// Unchanged on exit.
347: ///</param>
348: /// <param name="A">
349: /// - DOUBLE PRECISION array of DIMENSION ( LDA, k ), where k is m
350: /// when SIDE = 'L' or 'l' and is n when SIDE = 'R' or 'r'.
351: /// Before entry with UPLO = 'U' or 'u', the leading k by k
352: /// upper triangular part of the array A must contain the upper
353: /// triangular matrix and the strictly lower triangular part of
354: /// A is not referenced.
355: /// Before entry with UPLO = 'L' or 'l', the leading k by k
356: /// lower triangular part of the array A must contain the lower
357: /// triangular matrix and the strictly upper triangular part of
358: /// A is not referenced.
359: /// Note that when DIAG = 'U' or 'u', the diagonal elements of
360: /// A are not referenced either, but are assumed to be unity.
361: /// Unchanged on exit.
362: ///</param>
363: /// <param name="LDA">
364: /// - INTEGER.
365: /// On entry, LDA specifies the first dimension of A as declared
366: /// in the calling (sub) program. When SIDE = 'L' or 'l' then
367: /// LDA must be at least max( 1, m ), when SIDE = 'R' or 'r'
368: /// then LDA must be at least max( 1, n ).
369: /// Unchanged on exit.
370: ///</param>
371: /// <param name="B">
372: /// := alpha*op( A )*B, or B := alpha*B*op( A ),
373: ///</param>
374: /// <param name="LDB">
375: /// - INTEGER.
376: /// On entry, LDB specifies the first dimension of B as declared
377: /// in the calling (sub) program. LDB must be at least
378: /// max( 1, m ).
379: /// Unchanged on exit.
380: ///
381: ///</param>
382: public void Run(string SIDE, string UPLO, string TRANSA, string DIAG, int M, int N
383: , double ALPHA, double[] A, int offset_a, int LDA, ref double[] B, int offset_b, int LDB)
384: {
385:
386: #region Array Index Correction
387:
388: int o_a = -1 - LDA + offset_a; int o_b = -1 - LDB + offset_b;
389:
390: #endregion
391:
392:
393: #region Strings
394:
395: SIDE = SIDE.Substring(0, 1); UPLO = UPLO.Substring(0, 1); TRANSA = TRANSA.Substring(0, 1);
396: DIAG = DIAG.Substring(0, 1);
397:
398: #endregion
399:
400:
401: #region Prolog
402:
403: // * .. Scalar Arguments ..
404: // * .. Array Arguments ..
405: // * ..
406: // *
407: // * Purpose
408: // * =======
409: // *
410: // * DTRMM performs one of the matrix-matrix operations
411: // *
412: // * B := alpha*op( A )*B, or B := alpha*B*op( A ),
413: // *
414: // * where alpha is a scalar, B is an m by n matrix, A is a unit, or
415: // * non-unit, upper or lower triangular matrix and op( A ) is one of
416: // *
417: // * op( A ) = A or op( A ) = A'.
418: // *
419: // * Parameters
420: // * ==========
421: // *
422: // * SIDE - CHARACTER*1.
423: // * On entry, SIDE specifies whether op( A ) multiplies B from
424: // * the left or right as follows:
425: // *
426: // * SIDE = 'L' or 'l' B := alpha*op( A )*B.
427: // *
428: // * SIDE = 'R' or 'r' B := alpha*B*op( A ).
429: // *
430: // * Unchanged on exit.
431: // *
432: // * UPLO - CHARACTER*1.
433: // * On entry, UPLO specifies whether the matrix A is an upper or
434: // * lower triangular matrix as follows:
435: // *
436: // * UPLO = 'U' or 'u' A is an upper triangular matrix.
437: // *
438: // * UPLO = 'L' or 'l' A is a lower triangular matrix.
439: // *
440: // * Unchanged on exit.
441: // *
442: // * TRANSA - CHARACTER*1.
443: // * On entry, TRANSA specifies the form of op( A ) to be used in
444: // * the matrix multiplication as follows:
445: // *
446: // * TRANSA = 'N' or 'n' op( A ) = A.
447: // *
448: // * TRANSA = 'T' or 't' op( A ) = A'.
449: // *
450: // * TRANSA = 'C' or 'c' op( A ) = A'.
451: // *
452: // * Unchanged on exit.
453: // *
454: // * DIAG - CHARACTER*1.
455: // * On entry, DIAG specifies whether or not A is unit triangular
456: // * as follows:
457: // *
458: // * DIAG = 'U' or 'u' A is assumed to be unit triangular.
459: // *
460: // * DIAG = 'N' or 'n' A is not assumed to be unit
461: // * triangular.
462: // *
463: // * Unchanged on exit.
464: // *
465: // * M - INTEGER.
466: // * On entry, M specifies the number of rows of B. M must be at
467: // * least zero.
468: // * Unchanged on exit.
469: // *
470: // * N - INTEGER.
471: // * On entry, N specifies the number of columns of B. N must be
472: // * at least zero.
473: // * Unchanged on exit.
474: // *
475: // * ALPHA - DOUBLE PRECISION.
476: // * On entry, ALPHA specifies the scalar alpha. When alpha is
477: // * zero then A is not referenced and B need not be set before
478: // * entry.
479: // * Unchanged on exit.
480: // *
481: // * A - DOUBLE PRECISION array of DIMENSION ( LDA, k ), where k is m
482: // * when SIDE = 'L' or 'l' and is n when SIDE = 'R' or 'r'.
483: // * Before entry with UPLO = 'U' or 'u', the leading k by k
484: // * upper triangular part of the array A must contain the upper
485: // * triangular matrix and the strictly lower triangular part of
486: // * A is not referenced.
487: // * Before entry with UPLO = 'L' or 'l', the leading k by k
488: // * lower triangular part of the array A must contain the lower
489: // * triangular matrix and the strictly upper triangular part of
490: // * A is not referenced.
491: // * Note that when DIAG = 'U' or 'u', the diagonal elements of
492: // * A are not referenced either, but are assumed to be unity.
493: // * Unchanged on exit.
494: // *
495: // * LDA - INTEGER.
496: // * On entry, LDA specifies the first dimension of A as declared
497: // * in the calling (sub) program. When SIDE = 'L' or 'l' then
498: // * LDA must be at least max( 1, m ), when SIDE = 'R' or 'r'
499: // * then LDA must be at least max( 1, n ).
500: // * Unchanged on exit.
501: // *
502: // * B - DOUBLE PRECISION array of DIMENSION ( LDB, n ).
503: // * Before entry, the leading m by n part of the array B must
504: // * contain the matrix B, and on exit is overwritten by the
505: // * transformed matrix.
506: // *
507: // * LDB - INTEGER.
508: // * On entry, LDB specifies the first dimension of B as declared
509: // * in the calling (sub) program. LDB must be at least
510: // * max( 1, m ).
511: // * Unchanged on exit.
512: // *
513: // *
514: // * Level 3 Blas routine.
515: // *
516: // * -- Written on 8-February-1989.
517: // * Jack Dongarra, Argonne National Laboratory.
518: // * Iain Duff, AERE Harwell.
519: // * Jeremy Du Croz, Numerical Algorithms Group Ltd.
520: // * Sven Hammarling, Numerical Algorithms Group Ltd.
521: // *
522: // *
523: // * .. External Functions ..
524: // * .. External Subroutines ..
525: // * .. Intrinsic Functions ..
526: // INTRINSIC MAX;
527: // * .. Local Scalars ..
528: // * .. Parameters ..
529: // * ..
530: // * .. Executable Statements ..
531: // *
532: // * Test the input parameters.
533: // *
534:
535: #endregion
536:
537:
538: #region Body
539:
540: LSIDE = this._lsame.Run(SIDE, "L");
541: if (LSIDE)
542: {
543: NROWA = M;
544: }
545: else
546: {
547: NROWA = N;
548: }
549: NOUNIT = this._lsame.Run(DIAG, "N");
550: UPPER = this._lsame.Run(UPLO, "U");
551: // *
552: INFO = 0;
553: if ((!LSIDE) && (!this._lsame.Run(SIDE, "R")))
554: {
555: INFO = 1;
556: }
557: else
558: {
559: if ((!UPPER) && (!this._lsame.Run(UPLO, "L")))
560: {
561: INFO = 2;
562: }
563: else
564: {
565: if ((!this._lsame.Run(TRANSA, "N")) && (!this._lsame.Run(TRANSA, "T")) && (!this._lsame.Run(TRANSA, "C")))
566: {
567: INFO = 3;
568: }
569: else
570: {
571: if ((!this._lsame.Run(DIAG, "U")) && (!this._lsame.Run(DIAG, "N")))
572: {
573: INFO = 4;
574: }
575: else
576: {
577: if (M < 0)
578: {
579: INFO = 5;
580: }
581: else
582: {
583: if (N < 0)
584: {
585: INFO = 6;
586: }
587: else
588: {
589: if (LDA < Math.Max(1, NROWA))
590: {
591: INFO = 9;
592: }
593: else
594: {
595: if (LDB < Math.Max(1, M))
596: {
597: INFO = 11;
598: }
599: }
600: }
601: }
602: }
603: }
604: }
605: }
606: if (INFO != 0)
607: {
608: this._xerbla.Run("DTRMM ", INFO);
609: return;
610: }
611: // *
612: // * Quick return if possible.
613: // *
614: if (N == 0) return;
615: // *
616: // * And when alpha.eq.zero.
617: // *
618: if (ALPHA == ZERO)
619: {
620: for (J = 1; J <= N; J++)
621: {
622: for (I = 1; I <= M; I++)
623: {
624: B[I+J * LDB + o_b] = ZERO;
625: }
626: }
627: return;
628: }
629: // *
630: // * Start the operations.
631: // *
632: if (LSIDE)
633: {
634: if (this._lsame.Run(TRANSA, "N"))
635: {
636: // *
637: // * Form B := alpha*A*B.
638: // *
639: if (UPPER)
640: {
641: for (J = 1; J <= N; J++)
642: {
643: for (K = 1; K <= M; K++)
644: {
645: if (B[K+J * LDB + o_b] != ZERO)
646: {
647: TEMP = ALPHA * B[K+J * LDB + o_b];
648: for (I = 1; I <= K - 1; I++)
649: {
650: B[I+J * LDB + o_b] = B[I+J * LDB + o_b] + TEMP * A[I+K * LDA + o_a];
651: }
652: if (NOUNIT) TEMP = TEMP * A[K+K * LDA + o_a];
653: B[K+J * LDB + o_b] = TEMP;
654: }
655: }
656: }
657: }
658: else
659: {
660: for (J = 1; J <= N; J++)
661: {
662: for (K = M; K >= 1; K += - 1)
663: {
664: if (B[K+J * LDB + o_b] != ZERO)
665: {
666: TEMP = ALPHA * B[K+J * LDB + o_b];
667: B[K+J * LDB + o_b] = TEMP;
668: if (NOUNIT) B[K+J * LDB + o_b] = B[K+J * LDB + o_b] * A[K+K * LDA + o_a];
669: for (I = K + 1; I <= M; I++)
670: {
671: B[I+J * LDB + o_b] = B[I+J * LDB + o_b] + TEMP * A[I+K * LDA + o_a];
672: }
673: }
674: }
675: }
676: }
677: }
678: else
679: {
680: // *
681: // * Form B := alpha*A'*B.
682: // *
683: if (UPPER)
684: {
685: for (J = 1; J <= N; J++)
686: {
687: for (I = M; I >= 1; I += - 1)
688: {
689: TEMP = B[I+J * LDB + o_b];
690: if (NOUNIT) TEMP = TEMP * A[I+I * LDA + o_a];
691: for (K = 1; K <= I - 1; K++)
692: {
693: TEMP = TEMP + A[K+I * LDA + o_a] * B[K+J * LDB + o_b];
694: }
695: B[I+J * LDB + o_b] = ALPHA * TEMP;
696: }
697: }
698: }
699: else
700: {
701: for (J = 1; J <= N; J++)
702: {
703: for (I = 1; I <= M; I++)
704: {
705: TEMP = B[I+J * LDB + o_b];
706: if (NOUNIT) TEMP = TEMP * A[I+I * LDA + o_a];
707: for (K = I + 1; K <= M; K++)
708: {
709: TEMP = TEMP + A[K+I * LDA + o_a] * B[K+J * LDB + o_b];
710: }
711: B[I+J * LDB + o_b] = ALPHA * TEMP;
712: }
713: }
714: }
715: }
716: }
717: else
718: {
719: if (this._lsame.Run(TRANSA, "N"))
720: {
721: // *
722: // * Form B := alpha*B*A.
723: // *
724: if (UPPER)
725: {
726: for (J = N; J >= 1; J += - 1)
727: {
728: TEMP = ALPHA;
729: if (NOUNIT) TEMP = TEMP * A[J+J * LDA + o_a];
730: for (I = 1; I <= M; I++)
731: {
732: B[I+J * LDB + o_b] = TEMP * B[I+J * LDB + o_b];
733: }
734: for (K = 1; K <= J - 1; K++)
735: {
736: if (A[K+J * LDA + o_a] != ZERO)
737: {
738: TEMP = ALPHA * A[K+J * LDA + o_a];
739: for (I = 1; I <= M; I++)
740: {
741: B[I+J * LDB + o_b] = B[I+J * LDB + o_b] + TEMP * B[I+K * LDB + o_b];
742: }
743: }
744: }
745: }
746: }
747: else
748: {
749: for (J = 1; J <= N; J++)
750: {
751: TEMP = ALPHA;
752: if (NOUNIT) TEMP = TEMP * A[J+J * LDA + o_a];
753: for (I = 1; I <= M; I++)
754: {
755: B[I+J * LDB + o_b] = TEMP * B[I+J * LDB + o_b];
756: }
757: for (K = J + 1; K <= N; K++)
758: {
759: if (A[K+J * LDA + o_a] != ZERO)
760: {
761: TEMP = ALPHA * A[K+J * LDA + o_a];
762: for (I = 1; I <= M; I++)
763: {
764: B[I+J * LDB + o_b] = B[I+J * LDB + o_b] + TEMP * B[I+K * LDB + o_b];
765: }
766: }
767: }
768: }
769: }
770: }
771: else
772: {
773: // *
774: // * Form B := alpha*B*A'.
775: // *
776: if (UPPER)
777: {
778: for (K = 1; K <= N; K++)
779: {
780: for (J = 1; J <= K - 1; J++)
781: {
782: if (A[J+K * LDA + o_a] != ZERO)
783: {
784: TEMP = ALPHA * A[J+K * LDA + o_a];
785: for (I = 1; I <= M; I++)
786: {
787: B[I+J * LDB + o_b] = B[I+J * LDB + o_b] + TEMP * B[I+K * LDB + o_b];
788: }
789: }
790: }
791: TEMP = ALPHA;
792: if (NOUNIT) TEMP = TEMP * A[K+K * LDA + o_a];
793: if (TEMP != ONE)
794: {
795: for (I = 1; I <= M; I++)
796: {
797: B[I+K * LDB + o_b] = TEMP * B[I+K * LDB + o_b];
798: }
799: }
800: }
801: }
802: else
803: {
804: for (K = N; K >= 1; K += - 1)
805: {
806: for (J = K + 1; J <= N; J++)
807: {
808: if (A[J+K * LDA + o_a] != ZERO)
809: {
810: TEMP = ALPHA * A[J+K * LDA + o_a];
811: for (I = 1; I <= M; I++)
812: {
813: B[I+J * LDB + o_b] = B[I+J * LDB + o_b] + TEMP * B[I+K * LDB + o_b];
814: }
815: }
816: }
817: TEMP = ALPHA;
818: if (NOUNIT) TEMP = TEMP * A[K+K * LDA + o_a];
819: if (TEMP != ONE)
820: {
821: for (I = 1; I <= M; I++)
822: {
823: B[I+K * LDB + o_b] = TEMP * B[I+K * LDB + o_b];
824: }
825: }
826: }
827: }
828: }
829: }
830: // *
831: return;
832: // *
833: // * End of DTRMM .
834: // *
835:
836: #endregion
837:
838: }
839: }
840: }