Add some basic letsimp tests based on bug #3950
[maxima.git] / share / lapack / blas / fortran / ztrmv.f
blob677e212b5813456d81fcda8d97bbdcc7c102c9c9
1 SUBROUTINE ZTRMV ( UPLO, TRANS, DIAG, N, A, LDA, X, INCX )
2 * .. Scalar Arguments ..
3 INTEGER INCX, LDA, N
4 CHARACTER*1 DIAG, TRANS, UPLO
5 * .. Array Arguments ..
6 COMPLEX*16 A( LDA, * ), X( * )
7 * ..
9 * Purpose
10 * =======
12 * ZTRMV performs one of the matrix-vector operations
14 * x := A*x, or x := A'*x, or x := conjg( A' )*x,
16 * where x is an n element vector and A is an n by n unit, or non-unit,
17 * upper or lower triangular matrix.
19 * Parameters
20 * ==========
22 * UPLO - CHARACTER*1.
23 * On entry, UPLO specifies whether the matrix is an upper or
24 * lower triangular matrix as follows:
26 * UPLO = 'U' or 'u' A is an upper triangular matrix.
28 * UPLO = 'L' or 'l' A is a lower triangular matrix.
30 * Unchanged on exit.
32 * TRANS - CHARACTER*1.
33 * On entry, TRANS specifies the operation to be performed as
34 * follows:
36 * TRANS = 'N' or 'n' x := A*x.
38 * TRANS = 'T' or 't' x := A'*x.
40 * TRANS = 'C' or 'c' x := conjg( A' )*x.
42 * Unchanged on exit.
44 * DIAG - CHARACTER*1.
45 * On entry, DIAG specifies whether or not A is unit
46 * triangular as follows:
48 * DIAG = 'U' or 'u' A is assumed to be unit triangular.
50 * DIAG = 'N' or 'n' A is not assumed to be unit
51 * triangular.
53 * Unchanged on exit.
55 * N - INTEGER.
56 * On entry, N specifies the order of the matrix A.
57 * N must be at least zero.
58 * Unchanged on exit.
60 * A - COMPLEX*16 array of DIMENSION ( LDA, n ).
61 * Before entry with UPLO = 'U' or 'u', the leading n by n
62 * upper triangular part of the array A must contain the upper
63 * triangular matrix and the strictly lower triangular part of
64 * A is not referenced.
65 * Before entry with UPLO = 'L' or 'l', the leading n by n
66 * lower triangular part of the array A must contain the lower
67 * triangular matrix and the strictly upper triangular part of
68 * A is not referenced.
69 * Note that when DIAG = 'U' or 'u', the diagonal elements of
70 * A are not referenced either, but are assumed to be unity.
71 * Unchanged on exit.
73 * LDA - INTEGER.
74 * On entry, LDA specifies the first dimension of A as declared
75 * in the calling (sub) program. LDA must be at least
76 * max( 1, n ).
77 * Unchanged on exit.
79 * X - COMPLEX*16 array of dimension at least
80 * ( 1 + ( n - 1 )*abs( INCX ) ).
81 * Before entry, the incremented array X must contain the n
82 * element vector x. On exit, X is overwritten with the
83 * tranformed vector x.
85 * INCX - INTEGER.
86 * On entry, INCX specifies the increment for the elements of
87 * X. INCX must not be zero.
88 * Unchanged on exit.
91 * Level 2 Blas routine.
93 * -- Written on 22-October-1986.
94 * Jack Dongarra, Argonne National Lab.
95 * Jeremy Du Croz, Nag Central Office.
96 * Sven Hammarling, Nag Central Office.
97 * Richard Hanson, Sandia National Labs.
100 * .. Parameters ..
101 COMPLEX*16 ZERO
102 PARAMETER ( ZERO = ( 0.0D+0, 0.0D+0 ) )
103 * .. Local Scalars ..
104 COMPLEX*16 TEMP
105 INTEGER I, INFO, IX, J, JX, KX
106 LOGICAL NOCONJ, NOUNIT
107 * .. External Functions ..
108 LOGICAL LSAME
109 EXTERNAL LSAME
110 * .. External Subroutines ..
111 EXTERNAL XERBLA
112 * .. Intrinsic Functions ..
113 INTRINSIC DCONJG, MAX
114 * ..
115 * .. Executable Statements ..
117 * Test the input parameters.
119 INFO = 0
120 IF ( .NOT.LSAME( UPLO , 'U' ).AND.
121 $ .NOT.LSAME( UPLO , 'L' ) )THEN
122 INFO = 1
123 ELSE IF( .NOT.LSAME( TRANS, 'N' ).AND.
124 $ .NOT.LSAME( TRANS, 'T' ).AND.
125 $ .NOT.LSAME( TRANS, 'C' ) )THEN
126 INFO = 2
127 ELSE IF( .NOT.LSAME( DIAG , 'U' ).AND.
128 $ .NOT.LSAME( DIAG , 'N' ) )THEN
129 INFO = 3
130 ELSE IF( N.LT.0 )THEN
131 INFO = 4
132 ELSE IF( LDA.LT.MAX( 1, N ) )THEN
133 INFO = 6
134 ELSE IF( INCX.EQ.0 )THEN
135 INFO = 8
136 END IF
137 IF( INFO.NE.0 )THEN
138 CALL XERBLA( 'ZTRMV ', INFO )
139 RETURN
140 END IF
142 * Quick return if possible.
144 IF( N.EQ.0 )
145 $ RETURN
147 NOCONJ = LSAME( TRANS, 'T' )
148 NOUNIT = LSAME( DIAG , 'N' )
150 * Set up the start point in X if the increment is not unity. This
151 * will be ( N - 1 )*INCX too small for descending loops.
153 IF( INCX.LE.0 )THEN
154 KX = 1 - ( N - 1 )*INCX
155 ELSE IF( INCX.NE.1 )THEN
156 KX = 1
157 END IF
159 * Start the operations. In this version the elements of A are
160 * accessed sequentially with one pass through A.
162 IF( LSAME( TRANS, 'N' ) )THEN
164 * Form x := A*x.
166 IF( LSAME( UPLO, 'U' ) )THEN
167 IF( INCX.EQ.1 )THEN
168 DO 20, J = 1, N
169 IF( X( J ).NE.ZERO )THEN
170 TEMP = X( J )
171 DO 10, I = 1, J - 1
172 X( I ) = X( I ) + TEMP*A( I, J )
173 10 CONTINUE
174 IF( NOUNIT )
175 $ X( J ) = X( J )*A( J, J )
176 END IF
177 20 CONTINUE
178 ELSE
179 JX = KX
180 DO 40, J = 1, N
181 IF( X( JX ).NE.ZERO )THEN
182 TEMP = X( JX )
183 IX = KX
184 DO 30, I = 1, J - 1
185 X( IX ) = X( IX ) + TEMP*A( I, J )
186 IX = IX + INCX
187 30 CONTINUE
188 IF( NOUNIT )
189 $ X( JX ) = X( JX )*A( J, J )
190 END IF
191 JX = JX + INCX
192 40 CONTINUE
193 END IF
194 ELSE
195 IF( INCX.EQ.1 )THEN
196 DO 60, J = N, 1, -1
197 IF( X( J ).NE.ZERO )THEN
198 TEMP = X( J )
199 DO 50, I = N, J + 1, -1
200 X( I ) = X( I ) + TEMP*A( I, J )
201 50 CONTINUE
202 IF( NOUNIT )
203 $ X( J ) = X( J )*A( J, J )
204 END IF
205 60 CONTINUE
206 ELSE
207 KX = KX + ( N - 1 )*INCX
208 JX = KX
209 DO 80, J = N, 1, -1
210 IF( X( JX ).NE.ZERO )THEN
211 TEMP = X( JX )
212 IX = KX
213 DO 70, I = N, J + 1, -1
214 X( IX ) = X( IX ) + TEMP*A( I, J )
215 IX = IX - INCX
216 70 CONTINUE
217 IF( NOUNIT )
218 $ X( JX ) = X( JX )*A( J, J )
219 END IF
220 JX = JX - INCX
221 80 CONTINUE
222 END IF
223 END IF
224 ELSE
226 * Form x := A'*x or x := conjg( A' )*x.
228 IF( LSAME( UPLO, 'U' ) )THEN
229 IF( INCX.EQ.1 )THEN
230 DO 110, J = N, 1, -1
231 TEMP = X( J )
232 IF( NOCONJ )THEN
233 IF( NOUNIT )
234 $ TEMP = TEMP*A( J, J )
235 DO 90, I = J - 1, 1, -1
236 TEMP = TEMP + A( I, J )*X( I )
237 90 CONTINUE
238 ELSE
239 IF( NOUNIT )
240 $ TEMP = TEMP*DCONJG( A( J, J ) )
241 DO 100, I = J - 1, 1, -1
242 TEMP = TEMP + DCONJG( A( I, J ) )*X( I )
243 100 CONTINUE
244 END IF
245 X( J ) = TEMP
246 110 CONTINUE
247 ELSE
248 JX = KX + ( N - 1 )*INCX
249 DO 140, J = N, 1, -1
250 TEMP = X( JX )
251 IX = JX
252 IF( NOCONJ )THEN
253 IF( NOUNIT )
254 $ TEMP = TEMP*A( J, J )
255 DO 120, I = J - 1, 1, -1
256 IX = IX - INCX
257 TEMP = TEMP + A( I, J )*X( IX )
258 120 CONTINUE
259 ELSE
260 IF( NOUNIT )
261 $ TEMP = TEMP*DCONJG( A( J, J ) )
262 DO 130, I = J - 1, 1, -1
263 IX = IX - INCX
264 TEMP = TEMP + DCONJG( A( I, J ) )*X( IX )
265 130 CONTINUE
266 END IF
267 X( JX ) = TEMP
268 JX = JX - INCX
269 140 CONTINUE
270 END IF
271 ELSE
272 IF( INCX.EQ.1 )THEN
273 DO 170, J = 1, N
274 TEMP = X( J )
275 IF( NOCONJ )THEN
276 IF( NOUNIT )
277 $ TEMP = TEMP*A( J, J )
278 DO 150, I = J + 1, N
279 TEMP = TEMP + A( I, J )*X( I )
280 150 CONTINUE
281 ELSE
282 IF( NOUNIT )
283 $ TEMP = TEMP*DCONJG( A( J, J ) )
284 DO 160, I = J + 1, N
285 TEMP = TEMP + DCONJG( A( I, J ) )*X( I )
286 160 CONTINUE
287 END IF
288 X( J ) = TEMP
289 170 CONTINUE
290 ELSE
291 JX = KX
292 DO 200, J = 1, N
293 TEMP = X( JX )
294 IX = JX
295 IF( NOCONJ )THEN
296 IF( NOUNIT )
297 $ TEMP = TEMP*A( J, J )
298 DO 180, I = J + 1, N
299 IX = IX + INCX
300 TEMP = TEMP + A( I, J )*X( IX )
301 180 CONTINUE
302 ELSE
303 IF( NOUNIT )
304 $ TEMP = TEMP*DCONJG( A( J, J ) )
305 DO 190, I = J + 1, N
306 IX = IX + INCX
307 TEMP = TEMP + DCONJG( A( I, J ) )*X( IX )
308 190 CONTINUE
309 END IF
310 X( JX ) = TEMP
311 JX = JX + INCX
312 200 CONTINUE
313 END IF
314 END IF
315 END IF
317 RETURN
319 * End of ZTRMV .