1 /* ---------------------------------------------------------------------
2 *
3 *  -- PBLAS auxiliary routine (version 2.0) --
4 *     University of Tennessee, Knoxville, Oak Ridge National Laboratory,
5 *     and University of California, Berkeley.
6 *     April 1, 1998
7 *
8 *  ---------------------------------------------------------------------
9 */
10 /*
11 *  Include files
12 */
13 #include "../pblas.h"
14 #include "../PBpblas.h"
15 #include "../PBtools.h"
16 #include "../PBblacs.h"
17 #include "../PBblas.h"
18 
19 #ifdef __STDC__
PB_Ctztrmv(PBTYP_T * TYPE,char * SIDE,char * UPLO,char * TRANS,char * DIAG,int M,int N,int K,int IOFFD,char * ALPHA,char * A,int LDA,char * X,int LDX,char * Y,int LDY)20 void PB_Ctztrmv( PBTYP_T * TYPE, char * SIDE, char * UPLO, char * TRANS,
21                  char * DIAG, int M, int N, int K, int IOFFD,
22                  char * ALPHA, char * A, int LDA, char * X, int LDX,
23                  char * Y, int LDY )
24 #else
25 void PB_Ctztrmv( TYPE, SIDE, UPLO, TRANS, DIAG, M, N, K, IOFFD, ALPHA,
26                  A, LDA, X, LDX, Y, LDY )
27 /*
28 *  .. Scalar Arguments ..
29 */
30    char               * SIDE, * UPLO, * TRANS, * DIAG;
31    int                IOFFD, K, LDA, LDX, LDY, M, N;
32    char               * ALPHA;
33 /*
34 *  .. Array Arguments ..
35 */
36    char               * A, * X, * Y;
37    PBTYP_T            * TYPE;
38 #endif
39 {
40 /*
41 *  Purpose
42 *  =======
43 *
44 *  PB_Ctztrmv  performs the matrix-vector  operation
45 *
46 *     y := A * x,  or  y := A' * x,  or  y := conjg( A' ) * x,
47 *
48 *  where  alpha  and beta  are scalars, x and y are vectors, and A is an
49 *  m by n trapezoidal triangular matrix.
50 *
51 *  Arguments
52 *  =========
53 *
54 *  TYPE    (local input) pointer to a PBTYP_T structure
55 *          On entry,  TYPE  is a pointer to a structure of type PBTYP_T,
56 *          that contains type information (See pblas.h).
57 *
58 *  SIDE    (dummy) pointer to CHAR
59 *          In this routine, SIDE is a dummy (unused) argument.
60 *
61 *  UPLO    (input) pointer to CHAR
62 *          On entry, UPLO  specifies which part of the matrix A is to be
63 *          referenced as follows:
64 *
65 *             UPLO = 'L' or 'l' the lower trapezoid of A is referenced,
66 *
67 *             UPLO = 'U' or 'u' the upper trapezoid of A is referenced,
68 *
69 *             otherwise         all of the matrix A is referenced.
70 *
71 *  TRANS   (input) pointer to CHAR
72 *          On entry,  TRANS  specifies  the operation to be performed as
73 *          follows:
74 *
75 *             TRANS = 'N' or 'n':  y := A*x,
76 *
77 *             TRANS = 'T' or 't':  y := A'*x,
78 *
79 *             TRANS = 'C' or 'c':  y := A'*x  or  y := conjg( A' )*x.
80 *
81 *  DIAG    (input) pointer to CHAR
82 *          On entry, DIAG  specifies whether or not A is unit triangular
83 *          as follows:
84 *
85 *             DIAG = 'U' or 'u'  A is assumed to be unit triangular.
86 *
87 *             DIAG = 'N' or 'n'  A is not assumed to be unit triangular.
88 *
89 *  M       (input) INTEGER
90 *          On entry,  M  specifies the number of rows of the matrix A. M
91 *          must be at least zero.
92 *
93 *  N       (input) INTEGER
94 *          On entry, N  specifies the number of columns of the matrix A.
95 *          N must be at least zero.
96 *
97 *  K       (dummy) INTEGER
98 *          In this routine, K is a dummy (unused) argument.
99 *
100 *  IOFFD   (input) INTEGER
101 *          On entry, IOFFD specifies the position of the offdiagonal de-
102 *          limiting the upper and lower trapezoidal part of A as follows
103 *          (see the notes below):
104 *
105 *             IOFFD = 0  specifies the main diagonal A( i, i ),
106 *                        with i = 1 ... MIN( M, N ),
107 *             IOFFD > 0  specifies the subdiagonal   A( i+IOFFD, i ),
108 *                        with i = 1 ... MIN( M-IOFFD, N ),
109 *             IOFFD < 0  specifies the superdiagonal A( i, i-IOFFD ),
110 *                        with i = 1 ... MIN( M, N+IOFFD ).
111 *
112 *  ALPHA   (dummy) pointer to CHAR
113 *          In this routine, ALPHA is a dummy (unused) argument.
114 *
115 *  A       (input) pointer to CHAR
116 *          On entry, A is an array of dimension (LDA,N) containing the m
117 *          by n matrix A. Only the trapezoidal part of  A  determined by
118 *          UPLO  and  IOFFD is referenced.  When  DIAG = 'U' or 'u', the
119 *          diagonal elements of  A  are  not  referenced either, but are
120 *          assumed to be unity.
121 *
122 *  LDA     (input) INTEGER
123 *          On entry, LDA specifies the leading dimension of the array A.
124 *          LDA must be at least max( 1, M ).
125 *
126 *  X       (input) pointer to CHAR
127 *          On entry, X is an array of dimension (LDX,Kx).  Before entry,
128 *          with  TRANS = 'N' or 'n', the array X must contain the n ele-
129 *          ment vector x corresponding to the columns of  A.  Otherwise,
130 *          the array X must contain the m element vector x corresponding
131 *          to the rows of A.  When  TRANS is 'N' or 'n', LDX is at least
132 *          1, and Kx is at least N. Otherwise, LDX is at least max(1,M),
133 *          and Kx is at least 1.
134 *
135 *  LDX     (input) INTEGER
136 *          On entry, LDX specifies the leading dimension of the array X.
137 *          LDX  must  be  at  least  1  when  TRANS  is  'N' or 'n'  and
138 *          max( 1, M ) otherwise.
139 *
140 *  Y       (input/output) pointer to CHAR
141 *          On entry, Y is an array of dimension (LDY,Ky). On exit,  with
142 *          TRANS = 'N' or 'n', the array Y contains the m element vector
143 *          y corresponding to the rows of A. Otherwise, the array Y con-
144 *          tains the n element vector y corresponding to the  columns of
145 *          A. When TRANS is 'N' or 'n', LDY is at least max( 1, M ), and
146 *          Ky is at least 1. Otherwise, LDY is at least 1, and Ky is  at
147 *          least N. On exit,  Y  is  overwritten  by the partial updated
148 *          vector y.
149 *
150 *  LDY     (input) INTEGER
151 *          On entry, LDY specifies the leading dimension of the array Y.
152 *          LDY  must  be  at  least  max( 1, M ) when  TRANS  is  'N' or
153 *          'n' and 1 otherwise.
154 *
155 *  Notes
156 *  =====
157 *                           N                                    N
158 *             ----------------------------                  -----------
159 *            |       d                    |                |           |
160 *          M |         d         Upper    |                |    Upper  |
161 *            | Lower     d                |                |d          |
162 *            |             d              |              M |  d        |
163 *             ----------------------------                 |    d      |
164 *                                                          |      d    |
165 *               IOFFD < 0                                  | Lower  d  |
166 *                                                          |          d|
167 *                  N                                       |           |
168 *             -----------                                   -----------
169 *            |    d Upper|
170 *            |      d    |                                   IOFFD > 0
171 *          M |        d  |
172 *            |          d|                              N
173 *            |  Lower    |                 ----------------------------
174 *            |           |                |          Upper             |
175 *            |           |                |d                           |
176 *            |           |                |  d                         |
177 *            |           |                |    d                       |
178 *            |           |                |Lower d                     |
179 *             -----------                  ----------------------------
180 *
181 *  -- Written on April 1, 1998 by
182 *     Antoine Petitet, University of Tennessee, Knoxville 37996, USA.
183 *
184 *  ---------------------------------------------------------------------
185 */
186 /*
187 *  .. Local Scalars ..
188 */
189    int                ione = 1;
190    char               * Aptr = NULL;
191 /* ..
192 *  .. Executable Statements ..
193 *
194 */
195    if( ( M <= 0 ) || ( N <= 0 ) ) return;
196 
197    if( ( Mupcase( UPLO[0] ) == CLOWER ) || ( Mupcase( UPLO[0] ) == CUPPER ) )
198    {
199       Aptr = PB_Cmalloc( M * N * TYPE->size );
200       TYPE->Ftzpadcpy( C2F_CHAR( UPLO ), C2F_CHAR( DIAG ), &M, &N, &IOFFD,
201                        A, &LDA, Aptr, &M );
202       if( Mupcase( TRANS[0] ) == CNOTRAN )
203       {
204          TYPE->Fgemv( C2F_CHAR( TRANS ), &M, &N, ALPHA, Aptr, &M, X, &LDX,
205                       TYPE->one, Y, &ione );
206       }
207       else
208       {
209          TYPE->Fgemv( C2F_CHAR( TRANS ), &M, &N, ALPHA, Aptr, &M, X, &ione,
210                       TYPE->one, Y, &LDY );
211       }
212       if( Aptr ) free( Aptr );
213    }
214    else
215    {
216       if( Mupcase( TRANS[0] ) == CNOTRAN )
217       {
218          TYPE->Fgemv( C2F_CHAR( TRANS ), &M, &N, ALPHA, A, &LDA, X, &LDX,
219                       TYPE->one, Y, &ione );
220       }
221       else
222       {
223          TYPE->Fgemv( C2F_CHAR( TRANS ), &M, &N, ALPHA, A, &LDA, X, &ione,
224                       TYPE->one, Y, &LDY );
225       }
226    }
227 /*
228 *  End of PB_Ctztrmv
229 */
230 }
231