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