LAPACK 3.12.0
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
zlavsy_rook.f
Go to the documentation of this file.
1*> \brief \b ZLAVSY_ROOK
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8* Definition:
9* ===========
10*
11* SUBROUTINE ZLAVSY_ROOK( UPLO, TRANS, DIAG, N, NRHS, A, LDA, IPIV, B,
12* LDB, INFO )
13*
14* .. Scalar Arguments ..
15* CHARACTER DIAG, TRANS, UPLO
16* INTEGER INFO, LDA, LDB, N, NRHS
17* ..
18* .. Array Arguments ..
19* INTEGER IPIV( * )
20* COMPLEX*16 A( LDA, * ), B( LDB, * )
21* ..
22*
23*
24*> \par Purpose:
25* =============
26*>
27*> \verbatim
28*>
29*> ZLAVSY_ROOK performs one of the matrix-vector operations
30*> x := A*x or x := A'*x,
31*> where x is an N element vector and A is one of the factors
32*> from the block U*D*U' or L*D*L' factorization computed by ZSYTRF_ROOK.
33*>
34*> If TRANS = 'N', multiplies by U or U * D (or L or L * D)
35*> If TRANS = 'T', multiplies by U' or D * U' (or L' or D * L')
36*> \endverbatim
37*
38* Arguments:
39* ==========
40*
41*> \param[in] UPLO
42*> \verbatim
43*> UPLO is CHARACTER*1
44*> Specifies whether the factor stored in A is upper or lower
45*> triangular.
46*> = 'U': Upper triangular
47*> = 'L': Lower triangular
48*> \endverbatim
49*>
50*> \param[in] TRANS
51*> \verbatim
52*> TRANS is CHARACTER*1
53*> Specifies the operation to be performed:
54*> = 'N': x := A*x
55*> = 'T': x := A'*x
56*> \endverbatim
57*>
58*> \param[in] DIAG
59*> \verbatim
60*> DIAG is CHARACTER*1
61*> Specifies whether or not the diagonal blocks are unit
62*> matrices. If the diagonal blocks are assumed to be unit,
63*> then A = U or A = L, otherwise A = U*D or A = L*D.
64*> = 'U': Diagonal blocks are assumed to be unit matrices.
65*> = 'N': Diagonal blocks are assumed to be non-unit matrices.
66*> \endverbatim
67*>
68*> \param[in] N
69*> \verbatim
70*> N is INTEGER
71*> The number of rows and columns of the matrix A. N >= 0.
72*> \endverbatim
73*>
74*> \param[in] NRHS
75*> \verbatim
76*> NRHS is INTEGER
77*> The number of right hand sides, i.e., the number of vectors
78*> x to be multiplied by A. NRHS >= 0.
79*> \endverbatim
80*>
81*> \param[in] A
82*> \verbatim
83*> A is COMPLEX*16 array, dimension (LDA,N)
84*> The block diagonal matrix D and the multipliers used to
85*> obtain the factor U or L as computed by ZSYTRF_ROOK.
86*> Stored as a 2-D triangular matrix.
87*> \endverbatim
88*>
89*> \param[in] LDA
90*> \verbatim
91*> LDA is INTEGER
92*> The leading dimension of the array A. LDA >= max(1,N).
93*> \endverbatim
94*>
95*> \param[in] IPIV
96*> \verbatim
97*> IPIV is INTEGER array, dimension (N)
98*> Details of the interchanges and the block structure of D,
99*> as determined by ZSYTRF_ROOK.
100*>
101*> If UPLO = 'U':
102*> If IPIV(k) > 0, then rows and columns k and IPIV(k)
103*> were interchanged and D(k,k) is a 1-by-1 diagonal block.
104*> (If IPIV( k ) = k, no interchange was done).
105*>
106*> If IPIV(k) < 0 and IPIV(k-1) < 0, then rows and
107*> columns k and -IPIV(k) were interchanged and rows and
108*> columns k-1 and -IPIV(k-1) were inerchaged,
109*> D(k-1:k,k-1:k) is a 2-by-2 diagonal block.
110*>
111*> If UPLO = 'L':
112*> If IPIV(k) > 0, then rows and columns k and IPIV(k)
113*> were interchanged and D(k,k) is a 1-by-1 diagonal block.
114*> (If IPIV( k ) = k, no interchange was done).
115*>
116*> If IPIV(k) < 0 and IPIV(k+1) < 0, then rows and
117*> columns k and -IPIV(k) were interchanged and rows and
118*> columns k+1 and -IPIV(k+1) were inerchaged,
119*> D(k:k+1,k:k+1) is a 2-by-2 diagonal block.
120*> \endverbatim
121*>
122*> \param[in,out] B
123*> \verbatim
124*> B is COMPLEX*16 array, dimension (LDB,NRHS)
125*> On entry, B contains NRHS vectors of length N.
126*> On exit, B is overwritten with the product A * B.
127*> \endverbatim
128*>
129*> \param[in] LDB
130*> \verbatim
131*> LDB is INTEGER
132*> The leading dimension of the array B. LDB >= max(1,N).
133*> \endverbatim
134*>
135*> \param[out] INFO
136*> \verbatim
137*> INFO is INTEGER
138*> = 0: successful exit
139*> < 0: if INFO = -k, the k-th argument had an illegal value
140*> \endverbatim
141*
142* Authors:
143* ========
144*
145*> \author Univ. of Tennessee
146*> \author Univ. of California Berkeley
147*> \author Univ. of Colorado Denver
148*> \author NAG Ltd.
149*
150*> \ingroup complex16_lin
151*
152* =====================================================================
153 SUBROUTINE zlavsy_rook( UPLO, TRANS, DIAG, N, NRHS, A, LDA, IPIV,
154 $ B, LDB, INFO )
155*
156* -- LAPACK test routine --
157* -- LAPACK is a software package provided by Univ. of Tennessee, --
158* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
159*
160* .. Scalar Arguments ..
161 CHARACTER DIAG, TRANS, UPLO
162 INTEGER INFO, LDA, LDB, N, NRHS
163* ..
164* .. Array Arguments ..
165 INTEGER IPIV( * )
166 COMPLEX*16 A( LDA, * ), B( LDB, * )
167* ..
168*
169* =====================================================================
170*
171* .. Parameters ..
172 COMPLEX*16 CONE
173 parameter( cone = ( 1.0d+0, 0.0d+0 ) )
174* ..
175* .. Local Scalars ..
176 LOGICAL NOUNIT
177 INTEGER J, K, KP
178 COMPLEX*16 D11, D12, D21, D22, T1, T2
179* ..
180* .. External Functions ..
181 LOGICAL LSAME
182 EXTERNAL lsame
183* ..
184* .. External Subroutines ..
185 EXTERNAL xerbla, zgemv, zgeru, zscal, zswap
186* ..
187* .. Intrinsic Functions ..
188 INTRINSIC abs, max
189* ..
190* .. Executable Statements ..
191*
192* Test the input parameters.
193*
194 info = 0
195 IF( .NOT.lsame( uplo, 'U' ) .AND. .NOT.lsame( uplo, 'L' ) ) THEN
196 info = -1
197 ELSE IF( .NOT.lsame( trans, 'N' ) .AND. .NOT.lsame( trans, 'T' ) )
198 $ THEN
199 info = -2
200 ELSE IF( .NOT.lsame( diag, 'U' ) .AND. .NOT.lsame( diag, 'N' ) )
201 $ THEN
202 info = -3
203 ELSE IF( n.LT.0 ) THEN
204 info = -4
205 ELSE IF( lda.LT.max( 1, n ) ) THEN
206 info = -6
207 ELSE IF( ldb.LT.max( 1, n ) ) THEN
208 info = -9
209 END IF
210 IF( info.NE.0 ) THEN
211 CALL xerbla( 'ZLAVSY_ROOK ', -info )
212 RETURN
213 END IF
214*
215* Quick return if possible.
216*
217 IF( n.EQ.0 )
218 $ RETURN
219*
220 nounit = lsame( diag, 'N' )
221*------------------------------------------
222*
223* Compute B := A * B (No transpose)
224*
225*------------------------------------------
226 IF( lsame( trans, 'N' ) ) THEN
227*
228* Compute B := U*B
229* where U = P(m)*inv(U(m))* ... *P(1)*inv(U(1))
230*
231 IF( lsame( uplo, 'U' ) ) THEN
232*
233* Loop forward applying the transformations.
234*
235 k = 1
236 10 CONTINUE
237 IF( k.GT.n )
238 $ GO TO 30
239 IF( ipiv( k ).GT.0 ) THEN
240*
241* 1 x 1 pivot block
242*
243* Multiply by the diagonal element if forming U * D.
244*
245 IF( nounit )
246 $ CALL zscal( nrhs, a( k, k ), b( k, 1 ), ldb )
247*
248* Multiply by P(K) * inv(U(K)) if K > 1.
249*
250 IF( k.GT.1 ) THEN
251*
252* Apply the transformation.
253*
254 CALL zgeru( k-1, nrhs, cone, a( 1, k ), 1, b( k, 1 ),
255 $ ldb, b( 1, 1 ), ldb )
256*
257* Interchange if P(K) != I.
258*
259 kp = ipiv( k )
260 IF( kp.NE.k )
261 $ CALL zswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
262 END IF
263 k = k + 1
264 ELSE
265*
266* 2 x 2 pivot block
267*
268* Multiply by the diagonal block if forming U * D.
269*
270 IF( nounit ) THEN
271 d11 = a( k, k )
272 d22 = a( k+1, k+1 )
273 d12 = a( k, k+1 )
274 d21 = d12
275 DO 20 j = 1, nrhs
276 t1 = b( k, j )
277 t2 = b( k+1, j )
278 b( k, j ) = d11*t1 + d12*t2
279 b( k+1, j ) = d21*t1 + d22*t2
280 20 CONTINUE
281 END IF
282*
283* Multiply by P(K) * inv(U(K)) if K > 1.
284*
285 IF( k.GT.1 ) THEN
286*
287* Apply the transformations.
288*
289 CALL zgeru( k-1, nrhs, cone, a( 1, k ), 1, b( k, 1 ),
290 $ ldb, b( 1, 1 ), ldb )
291 CALL zgeru( k-1, nrhs, cone, a( 1, k+1 ), 1,
292 $ b( k+1, 1 ), ldb, b( 1, 1 ), ldb )
293*
294* Interchange if a permutation was applied at the
295* K-th step of the factorization.
296*
297* Swap the first of pair with IMAXth
298*
299 kp = abs( ipiv( k ) )
300 IF( kp.NE.k )
301 $ CALL zswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
302*
303* NOW swap the first of pair with Pth
304*
305 kp = abs( ipiv( k+1 ) )
306 IF( kp.NE.k+1 )
307 $ CALL zswap( nrhs, b( k+1, 1 ), ldb, b( kp, 1 ),
308 $ ldb )
309 END IF
310 k = k + 2
311 END IF
312 GO TO 10
313 30 CONTINUE
314*
315* Compute B := L*B
316* where L = P(1)*inv(L(1))* ... *P(m)*inv(L(m)) .
317*
318 ELSE
319*
320* Loop backward applying the transformations to B.
321*
322 k = n
323 40 CONTINUE
324 IF( k.LT.1 )
325 $ GO TO 60
326*
327* Test the pivot index. If greater than zero, a 1 x 1
328* pivot was used, otherwise a 2 x 2 pivot was used.
329*
330 IF( ipiv( k ).GT.0 ) THEN
331*
332* 1 x 1 pivot block:
333*
334* Multiply by the diagonal element if forming L * D.
335*
336 IF( nounit )
337 $ CALL zscal( nrhs, a( k, k ), b( k, 1 ), ldb )
338*
339* Multiply by P(K) * inv(L(K)) if K < N.
340*
341 IF( k.NE.n ) THEN
342 kp = ipiv( k )
343*
344* Apply the transformation.
345*
346 CALL zgeru( n-k, nrhs, cone, a( k+1, k ), 1,
347 $ b( k, 1 ), ldb, b( k+1, 1 ), ldb )
348*
349* Interchange if a permutation was applied at the
350* K-th step of the factorization.
351*
352 IF( kp.NE.k )
353 $ CALL zswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
354 END IF
355 k = k - 1
356*
357 ELSE
358*
359* 2 x 2 pivot block:
360*
361* Multiply by the diagonal block if forming L * D.
362*
363 IF( nounit ) THEN
364 d11 = a( k-1, k-1 )
365 d22 = a( k, k )
366 d21 = a( k, k-1 )
367 d12 = d21
368 DO 50 j = 1, nrhs
369 t1 = b( k-1, j )
370 t2 = b( k, j )
371 b( k-1, j ) = d11*t1 + d12*t2
372 b( k, j ) = d21*t1 + d22*t2
373 50 CONTINUE
374 END IF
375*
376* Multiply by P(K) * inv(L(K)) if K < N.
377*
378 IF( k.NE.n ) THEN
379*
380* Apply the transformation.
381*
382 CALL zgeru( n-k, nrhs, cone, a( k+1, k ), 1,
383 $ b( k, 1 ), ldb, b( k+1, 1 ), ldb )
384 CALL zgeru( n-k, nrhs, cone, a( k+1, k-1 ), 1,
385 $ b( k-1, 1 ), ldb, b( k+1, 1 ), ldb )
386*
387* Interchange if a permutation was applied at the
388* K-th step of the factorization.
389*
390* Swap the second of pair with IMAXth
391*
392 kp = abs( ipiv( k ) )
393 IF( kp.NE.k )
394 $ CALL zswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
395*
396* NOW swap the first of pair with Pth
397*
398 kp = abs( ipiv( k-1 ) )
399 IF( kp.NE.k-1 )
400 $ CALL zswap( nrhs, b( k-1, 1 ), ldb, b( kp, 1 ),
401 $ ldb )
402 END IF
403 k = k - 2
404 END IF
405 GO TO 40
406 60 CONTINUE
407 END IF
408*----------------------------------------
409*
410* Compute B := A' * B (transpose)
411*
412*----------------------------------------
413 ELSE IF( lsame( trans, 'T' ) ) THEN
414*
415* Form B := U'*B
416* where U = P(m)*inv(U(m))* ... *P(1)*inv(U(1))
417* and U' = inv(U'(1))*P(1)* ... *inv(U'(m))*P(m)
418*
419 IF( lsame( uplo, 'U' ) ) THEN
420*
421* Loop backward applying the transformations.
422*
423 k = n
424 70 CONTINUE
425 IF( k.LT.1 )
426 $ GO TO 90
427*
428* 1 x 1 pivot block.
429*
430 IF( ipiv( k ).GT.0 ) THEN
431 IF( k.GT.1 ) THEN
432*
433* Interchange if P(K) != I.
434*
435 kp = ipiv( k )
436 IF( kp.NE.k )
437 $ CALL zswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
438*
439* Apply the transformation
440*
441 CALL zgemv( 'Transpose', k-1, nrhs, cone, b, ldb,
442 $ a( 1, k ), 1, cone, b( k, 1 ), ldb )
443 END IF
444 IF( nounit )
445 $ CALL zscal( nrhs, a( k, k ), b( k, 1 ), ldb )
446 k = k - 1
447*
448* 2 x 2 pivot block.
449*
450 ELSE
451 IF( k.GT.2 ) THEN
452*
453* Swap the second of pair with Pth
454*
455 kp = abs( ipiv( k ) )
456 IF( kp.NE.k )
457 $ CALL zswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
458*
459* Now swap the first of pair with IMAX(r)th
460*
461 kp = abs( ipiv( k-1 ) )
462 IF( kp.NE.k-1 )
463 $ CALL zswap( nrhs, b( k-1, 1 ), ldb, b( kp, 1 ),
464 $ ldb )
465*
466* Apply the transformations
467*
468 CALL zgemv( 'Transpose', k-2, nrhs, cone, b, ldb,
469 $ a( 1, k ), 1, cone, b( k, 1 ), ldb )
470 CALL zgemv( 'Transpose', k-2, nrhs, cone, b, ldb,
471 $ a( 1, k-1 ), 1, cone, b( k-1, 1 ), ldb )
472 END IF
473*
474* Multiply by the diagonal block if non-unit.
475*
476 IF( nounit ) THEN
477 d11 = a( k-1, k-1 )
478 d22 = a( k, k )
479 d12 = a( k-1, k )
480 d21 = d12
481 DO 80 j = 1, nrhs
482 t1 = b( k-1, j )
483 t2 = b( k, j )
484 b( k-1, j ) = d11*t1 + d12*t2
485 b( k, j ) = d21*t1 + d22*t2
486 80 CONTINUE
487 END IF
488 k = k - 2
489 END IF
490 GO TO 70
491 90 CONTINUE
492*
493* Form B := L'*B
494* where L = P(1)*inv(L(1))* ... *P(m)*inv(L(m))
495* and L' = inv(L'(m))*P(m)* ... *inv(L'(1))*P(1)
496*
497 ELSE
498*
499* Loop forward applying the L-transformations.
500*
501 k = 1
502 100 CONTINUE
503 IF( k.GT.n )
504 $ GO TO 120
505*
506* 1 x 1 pivot block
507*
508 IF( ipiv( k ).GT.0 ) THEN
509 IF( k.LT.n ) THEN
510*
511* Interchange if P(K) != I.
512*
513 kp = ipiv( k )
514 IF( kp.NE.k )
515 $ CALL zswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
516*
517* Apply the transformation
518*
519 CALL zgemv( 'Transpose', n-k, nrhs, cone, b( k+1, 1 ),
520 $ ldb, a( k+1, k ), 1, cone, b( k, 1 ), ldb )
521 END IF
522 IF( nounit )
523 $ CALL zscal( nrhs, a( k, k ), b( k, 1 ), ldb )
524 k = k + 1
525*
526* 2 x 2 pivot block.
527*
528 ELSE
529 IF( k.LT.n-1 ) THEN
530*
531* Swap the first of pair with Pth
532*
533 kp = abs( ipiv( k ) )
534 IF( kp.NE.k )
535 $ CALL zswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
536*
537* Now swap the second of pair with IMAX(r)th
538*
539 kp = abs( ipiv( k+1 ) )
540 IF( kp.NE.k+1 )
541 $ CALL zswap( nrhs, b( k+1, 1 ), ldb, b( kp, 1 ),
542 $ ldb )
543*
544* Apply the transformation
545*
546 CALL zgemv( 'Transpose', n-k-1, nrhs, cone,
547 $ b( k+2, 1 ), ldb, a( k+2, k+1 ), 1, cone,
548 $ b( k+1, 1 ), ldb )
549 CALL zgemv( 'Transpose', n-k-1, nrhs, cone,
550 $ b( k+2, 1 ), ldb, a( k+2, k ), 1, cone,
551 $ b( k, 1 ), ldb )
552 END IF
553*
554* Multiply by the diagonal block if non-unit.
555*
556 IF( nounit ) THEN
557 d11 = a( k, k )
558 d22 = a( k+1, k+1 )
559 d21 = a( k+1, k )
560 d12 = d21
561 DO 110 j = 1, nrhs
562 t1 = b( k, j )
563 t2 = b( k+1, j )
564 b( k, j ) = d11*t1 + d12*t2
565 b( k+1, j ) = d21*t1 + d22*t2
566 110 CONTINUE
567 END IF
568 k = k + 2
569 END IF
570 GO TO 100
571 120 CONTINUE
572 END IF
573 END IF
574 RETURN
575*
576* End of ZLAVSY_ROOK
577*
578 END
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine zgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
ZGEMV
Definition zgemv.f:160
subroutine zgeru(m, n, alpha, x, incx, y, incy, a, lda)
ZGERU
Definition zgeru.f:130
subroutine zscal(n, za, zx, incx)
ZSCAL
Definition zscal.f:78
subroutine zswap(n, zx, incx, zy, incy)
ZSWAP
Definition zswap.f:81
subroutine zlavsy_rook(uplo, trans, diag, n, nrhs, a, lda, ipiv, b, ldb, info)
ZLAVSY_ROOK