LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
zsytrs_3.f
Go to the documentation of this file.
1*> \brief \b ZSYTRS_3
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download ZSYTRS_3 + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zsytrs_3.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zsytrs_3.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zsytrs_3.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE ZSYTRS_3( UPLO, N, NRHS, A, LDA, E, IPIV, B, LDB,
20* INFO )
21*
22* .. Scalar Arguments ..
23* CHARACTER UPLO
24* INTEGER INFO, LDA, LDB, N, NRHS
25* ..
26* .. Array Arguments ..
27* INTEGER IPIV( * )
28* COMPLEX*16 A( LDA, * ), B( LDB, * ), E( * )
29* ..
30*
31*
32*> \par Purpose:
33* =============
34*>
35*> \verbatim
36*> ZSYTRS_3 solves a system of linear equations A * X = B with a complex
37*> symmetric matrix A using the factorization computed
38*> by ZSYTRF_RK or ZSYTRF_BK:
39*>
40*> A = P*U*D*(U**T)*(P**T) or A = P*L*D*(L**T)*(P**T),
41*>
42*> where U (or L) is unit upper (or lower) triangular matrix,
43*> U**T (or L**T) is the transpose of U (or L), P is a permutation
44*> matrix, P**T is the transpose of P, and D is symmetric and block
45*> diagonal with 1-by-1 and 2-by-2 diagonal blocks.
46*>
47*> This algorithm is using Level 3 BLAS.
48*> \endverbatim
49*
50* Arguments:
51* ==========
52*
53*> \param[in] UPLO
54*> \verbatim
55*> UPLO is CHARACTER*1
56*> Specifies whether the details of the factorization are
57*> stored as an upper or lower triangular matrix:
58*> = 'U': Upper triangular, form is A = P*U*D*(U**T)*(P**T);
59*> = 'L': Lower triangular, form is A = P*L*D*(L**T)*(P**T).
60*> \endverbatim
61*>
62*> \param[in] N
63*> \verbatim
64*> N is INTEGER
65*> The order of the matrix A. N >= 0.
66*> \endverbatim
67*>
68*> \param[in] NRHS
69*> \verbatim
70*> NRHS is INTEGER
71*> The number of right hand sides, i.e., the number of columns
72*> of the matrix B. NRHS >= 0.
73*> \endverbatim
74*>
75*> \param[in] A
76*> \verbatim
77*> A is COMPLEX*16 array, dimension (LDA,N)
78*> Diagonal of the block diagonal matrix D and factors U or L
79*> as computed by ZSYTRF_RK and ZSYTRF_BK:
80*> a) ONLY diagonal elements of the symmetric block diagonal
81*> matrix D on the diagonal of A, i.e. D(k,k) = A(k,k);
82*> (superdiagonal (or subdiagonal) elements of D
83*> should be provided on entry in array E), and
84*> b) If UPLO = 'U': factor U in the superdiagonal part of A.
85*> If UPLO = 'L': factor L in the subdiagonal part of A.
86*> \endverbatim
87*>
88*> \param[in] LDA
89*> \verbatim
90*> LDA is INTEGER
91*> The leading dimension of the array A. LDA >= max(1,N).
92*> \endverbatim
93*>
94*> \param[in] E
95*> \verbatim
96*> E is COMPLEX*16 array, dimension (N)
97*> On entry, contains the superdiagonal (or subdiagonal)
98*> elements of the symmetric block diagonal matrix D
99*> with 1-by-1 or 2-by-2 diagonal blocks, where
100*> If UPLO = 'U': E(i) = D(i-1,i),i=2:N, E(1) not referenced;
101*> If UPLO = 'L': E(i) = D(i+1,i),i=1:N-1, E(N) not referenced.
102*>
103*> NOTE: For 1-by-1 diagonal block D(k), where
104*> 1 <= k <= N, the element E(k) is not referenced in both
105*> UPLO = 'U' or UPLO = 'L' cases.
106*> \endverbatim
107*>
108*> \param[in] IPIV
109*> \verbatim
110*> IPIV is INTEGER array, dimension (N)
111*> Details of the interchanges and the block structure of D
112*> as determined by ZSYTRF_RK or ZSYTRF_BK.
113*> \endverbatim
114*>
115*> \param[in,out] B
116*> \verbatim
117*> B is COMPLEX*16 array, dimension (LDB,NRHS)
118*> On entry, the right hand side matrix B.
119*> On exit, the solution matrix X.
120*> \endverbatim
121*>
122*> \param[in] LDB
123*> \verbatim
124*> LDB is INTEGER
125*> The leading dimension of the array B. LDB >= max(1,N).
126*> \endverbatim
127*>
128*> \param[out] INFO
129*> \verbatim
130*> INFO is INTEGER
131*> = 0: successful exit
132*> < 0: if INFO = -i, the i-th argument had an illegal value
133*> \endverbatim
134*
135* Authors:
136* ========
137*
138*> \author Univ. of Tennessee
139*> \author Univ. of California Berkeley
140*> \author Univ. of Colorado Denver
141*> \author NAG Ltd.
142*
143*> \ingroup hetrs_3
144*
145*> \par Contributors:
146* ==================
147*>
148*> \verbatim
149*>
150*> June 2017, Igor Kozachenko,
151*> Computer Science Division,
152*> University of California, Berkeley
153*>
154*> September 2007, Sven Hammarling, Nicholas J. Higham, Craig Lucas,
155*> School of Mathematics,
156*> University of Manchester
157*>
158*> \endverbatim
159*
160* =====================================================================
161 SUBROUTINE zsytrs_3( UPLO, N, NRHS, A, LDA, E, IPIV, B, LDB,
162 $ INFO )
163*
164* -- LAPACK computational routine --
165* -- LAPACK is a software package provided by Univ. of Tennessee, --
166* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
167*
168* .. Scalar Arguments ..
169 CHARACTER UPLO
170 INTEGER INFO, LDA, LDB, N, NRHS
171* ..
172* .. Array Arguments ..
173 INTEGER IPIV( * )
174 COMPLEX*16 A( LDA, * ), B( LDB, * ), E( * )
175* ..
176*
177* =====================================================================
178*
179* .. Parameters ..
180 COMPLEX*16 ONE
181 parameter( one = ( 1.0d+0,0.0d+0 ) )
182* ..
183* .. Local Scalars ..
184 LOGICAL UPPER
185 INTEGER I, J, K, KP
186 COMPLEX*16 AK, AKM1, AKM1K, BK, BKM1, DENOM
187* ..
188* .. External Functions ..
189 LOGICAL LSAME
190 EXTERNAL lsame
191* ..
192* .. External Subroutines ..
193 EXTERNAL zscal, zswap, ztrsm, xerbla
194* ..
195* .. Intrinsic Functions ..
196 INTRINSIC abs, max
197* ..
198* .. Executable Statements ..
199*
200 info = 0
201 upper = lsame( uplo, 'U' )
202 IF( .NOT.upper .AND. .NOT.lsame( uplo, 'L' ) ) THEN
203 info = -1
204 ELSE IF( n.LT.0 ) THEN
205 info = -2
206 ELSE IF( nrhs.LT.0 ) THEN
207 info = -3
208 ELSE IF( lda.LT.max( 1, n ) ) THEN
209 info = -5
210 ELSE IF( ldb.LT.max( 1, n ) ) THEN
211 info = -9
212 END IF
213 IF( info.NE.0 ) THEN
214 CALL xerbla( 'ZSYTRS_3', -info )
215 RETURN
216 END IF
217*
218* Quick return if possible
219*
220 IF( n.EQ.0 .OR. nrhs.EQ.0 )
221 $ RETURN
222*
223 IF( upper ) THEN
224*
225* Begin Upper
226*
227* Solve A*X = B, where A = U*D*U**T.
228*
229* P**T * B
230*
231* Interchange rows K and IPIV(K) of matrix B in the same order
232* that the formation order of IPIV(I) vector for Upper case.
233*
234* (We can do the simple loop over IPIV with decrement -1,
235* since the ABS value of IPIV(I) represents the row index
236* of the interchange with row i in both 1x1 and 2x2 pivot cases)
237*
238 DO k = n, 1, -1
239 kp = abs( ipiv( k ) )
240 IF( kp.NE.k ) THEN
241 CALL zswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
242 END IF
243 END DO
244*
245* Compute (U \P**T * B) -> B [ (U \P**T * B) ]
246*
247 CALL ztrsm( 'L', 'U', 'N', 'U', n, nrhs, one, a, lda, b,
248 $ ldb )
249*
250* Compute D \ B -> B [ D \ (U \P**T * B) ]
251*
252 i = n
253 DO WHILE ( i.GE.1 )
254 IF( ipiv( i ).GT.0 ) THEN
255 CALL zscal( nrhs, one / a( i, i ), b( i, 1 ), ldb )
256 ELSE IF ( i.GT.1 ) THEN
257 akm1k = e( i )
258 akm1 = a( i-1, i-1 ) / akm1k
259 ak = a( i, i ) / akm1k
260 denom = akm1*ak - one
261 DO j = 1, nrhs
262 bkm1 = b( i-1, j ) / akm1k
263 bk = b( i, j ) / akm1k
264 b( i-1, j ) = ( ak*bkm1-bk ) / denom
265 b( i, j ) = ( akm1*bk-bkm1 ) / denom
266 END DO
267 i = i - 1
268 END IF
269 i = i - 1
270 END DO
271*
272* Compute (U**T \ B) -> B [ U**T \ (D \ (U \P**T * B) ) ]
273*
274 CALL ztrsm( 'L', 'U', 'T', 'U', n, nrhs, one, a, lda, b,
275 $ ldb )
276*
277* P * B [ P * (U**T \ (D \ (U \P**T * B) )) ]
278*
279* Interchange rows K and IPIV(K) of matrix B in reverse order
280* from the formation order of IPIV(I) vector for Upper case.
281*
282* (We can do the simple loop over IPIV with increment 1,
283* since the ABS value of IPIV(I) represents the row index
284* of the interchange with row i in both 1x1 and 2x2 pivot cases)
285*
286 DO k = 1, n, 1
287 kp = abs( ipiv( k ) )
288 IF( kp.NE.k ) THEN
289 CALL zswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
290 END IF
291 END DO
292*
293 ELSE
294*
295* Begin Lower
296*
297* Solve A*X = B, where A = L*D*L**T.
298*
299* P**T * B
300* Interchange rows K and IPIV(K) of matrix B in the same order
301* that the formation order of IPIV(I) vector for Lower case.
302*
303* (We can do the simple loop over IPIV with increment 1,
304* since the ABS value of IPIV(I) represents the row index
305* of the interchange with row i in both 1x1 and 2x2 pivot cases)
306*
307 DO k = 1, n, 1
308 kp = abs( ipiv( k ) )
309 IF( kp.NE.k ) THEN
310 CALL zswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
311 END IF
312 END DO
313*
314* Compute (L \P**T * B) -> B [ (L \P**T * B) ]
315*
316 CALL ztrsm( 'L', 'L', 'N', 'U', n, nrhs, one, a, lda, b,
317 $ ldb )
318*
319* Compute D \ B -> B [ D \ (L \P**T * B) ]
320*
321 i = 1
322 DO WHILE ( i.LE.n )
323 IF( ipiv( i ).GT.0 ) THEN
324 CALL zscal( nrhs, one / a( i, i ), b( i, 1 ), ldb )
325 ELSE IF( i.LT.n ) THEN
326 akm1k = e( i )
327 akm1 = a( i, i ) / akm1k
328 ak = a( i+1, i+1 ) / akm1k
329 denom = akm1*ak - one
330 DO j = 1, nrhs
331 bkm1 = b( i, j ) / akm1k
332 bk = b( i+1, j ) / akm1k
333 b( i, j ) = ( ak*bkm1-bk ) / denom
334 b( i+1, j ) = ( akm1*bk-bkm1 ) / denom
335 END DO
336 i = i + 1
337 END IF
338 i = i + 1
339 END DO
340*
341* Compute (L**T \ B) -> B [ L**T \ (D \ (L \P**T * B) ) ]
342*
343 CALL ztrsm('L', 'L', 'T', 'U', n, nrhs, one, a, lda, b,
344 $ ldb )
345*
346* P * B [ P * (L**T \ (D \ (L \P**T * B) )) ]
347*
348* Interchange rows K and IPIV(K) of matrix B in reverse order
349* from the formation order of IPIV(I) vector for Lower case.
350*
351* (We can do the simple loop over IPIV with decrement -1,
352* since the ABS value of IPIV(I) represents the row index
353* of the interchange with row i in both 1x1 and 2x2 pivot cases)
354*
355 DO k = n, 1, -1
356 kp = abs( ipiv( k ) )
357 IF( kp.NE.k ) THEN
358 CALL zswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
359 END IF
360 END DO
361*
362* END Lower
363*
364 END IF
365*
366 RETURN
367*
368* End of ZSYTRS_3
369*
370 END
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine zsytrs_3(uplo, n, nrhs, a, lda, e, ipiv, b, ldb, info)
ZSYTRS_3
Definition zsytrs_3.f:163
subroutine zscal(n, za, zx, incx)
ZSCAL
Definition zscal.f:78
subroutine zswap(n, zx, incx, zy, incy)
ZSWAP
Definition zswap.f:81
subroutine ztrsm(side, uplo, transa, diag, m, n, alpha, a, lda, b, ldb)
ZTRSM
Definition ztrsm.f:180