LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
zsytri.f
Go to the documentation of this file.
1*> \brief \b ZSYTRI
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download ZSYTRI + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zsytri.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zsytri.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zsytri.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE ZSYTRI( UPLO, N, A, LDA, IPIV, WORK, INFO )
20*
21* .. Scalar Arguments ..
22* CHARACTER UPLO
23* INTEGER INFO, LDA, N
24* ..
25* .. Array Arguments ..
26* INTEGER IPIV( * )
27* COMPLEX*16 A( LDA, * ), WORK( * )
28* ..
29*
30*
31*> \par Purpose:
32* =============
33*>
34*> \verbatim
35*>
36*> ZSYTRI computes the inverse of a complex symmetric indefinite matrix
37*> A using the factorization A = U*D*U**T or A = L*D*L**T computed by
38*> ZSYTRF.
39*> \endverbatim
40*
41* Arguments:
42* ==========
43*
44*> \param[in] UPLO
45*> \verbatim
46*> UPLO is CHARACTER*1
47*> Specifies whether the details of the factorization are stored
48*> as an upper or lower triangular matrix.
49*> = 'U': Upper triangular, form is A = U*D*U**T;
50*> = 'L': Lower triangular, form is A = L*D*L**T.
51*> \endverbatim
52*>
53*> \param[in] N
54*> \verbatim
55*> N is INTEGER
56*> The order of the matrix A. N >= 0.
57*> \endverbatim
58*>
59*> \param[in,out] A
60*> \verbatim
61*> A is COMPLEX*16 array, dimension (LDA,N)
62*> On entry, the block diagonal matrix D and the multipliers
63*> used to obtain the factor U or L as computed by ZSYTRF.
64*>
65*> On exit, if INFO = 0, the (symmetric) inverse of the original
66*> matrix. If UPLO = 'U', the upper triangular part of the
67*> inverse is formed and the part of A below the diagonal is not
68*> referenced; if UPLO = 'L' the lower triangular part of the
69*> inverse is formed and the part of A above the diagonal is
70*> not referenced.
71*> \endverbatim
72*>
73*> \param[in] LDA
74*> \verbatim
75*> LDA is INTEGER
76*> The leading dimension of the array A. LDA >= max(1,N).
77*> \endverbatim
78*>
79*> \param[in] IPIV
80*> \verbatim
81*> IPIV is INTEGER array, dimension (N)
82*> Details of the interchanges and the block structure of D
83*> as determined by ZSYTRF.
84*> \endverbatim
85*>
86*> \param[out] WORK
87*> \verbatim
88*> WORK is COMPLEX*16 array, dimension (2*N)
89*> \endverbatim
90*>
91*> \param[out] INFO
92*> \verbatim
93*> INFO is INTEGER
94*> = 0: successful exit
95*> < 0: if INFO = -i, the i-th argument had an illegal value
96*> > 0: if INFO = i, D(i,i) = 0; the matrix is singular and its
97*> inverse could not be computed.
98*> \endverbatim
99*
100* Authors:
101* ========
102*
103*> \author Univ. of Tennessee
104*> \author Univ. of California Berkeley
105*> \author Univ. of Colorado Denver
106*> \author NAG Ltd.
107*
108*> \ingroup hetri
109*
110* =====================================================================
111 SUBROUTINE zsytri( UPLO, N, A, LDA, IPIV, WORK, INFO )
112*
113* -- LAPACK computational routine --
114* -- LAPACK is a software package provided by Univ. of Tennessee, --
115* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
116*
117* .. Scalar Arguments ..
118 CHARACTER UPLO
119 INTEGER INFO, LDA, N
120* ..
121* .. Array Arguments ..
122 INTEGER IPIV( * )
123 COMPLEX*16 A( LDA, * ), WORK( * )
124* ..
125*
126* =====================================================================
127*
128* .. Parameters ..
129 COMPLEX*16 ONE, ZERO
130 parameter( one = ( 1.0d+0, 0.0d+0 ),
131 $ zero = ( 0.0d+0, 0.0d+0 ) )
132* ..
133* .. Local Scalars ..
134 LOGICAL UPPER
135 INTEGER K, KP, KSTEP
136 COMPLEX*16 AK, AKKP1, AKP1, D, T, TEMP
137* ..
138* .. External Functions ..
139 LOGICAL LSAME
140 COMPLEX*16 ZDOTU
141 EXTERNAL lsame, zdotu
142* ..
143* .. External Subroutines ..
144 EXTERNAL xerbla, zcopy, zswap, zsymv
145* ..
146* .. Intrinsic Functions ..
147 INTRINSIC abs, max
148* ..
149* .. Executable Statements ..
150*
151* Test the input parameters.
152*
153 info = 0
154 upper = lsame( uplo, 'U' )
155 IF( .NOT.upper .AND. .NOT.lsame( uplo, 'L' ) ) THEN
156 info = -1
157 ELSE IF( n.LT.0 ) THEN
158 info = -2
159 ELSE IF( lda.LT.max( 1, n ) ) THEN
160 info = -4
161 END IF
162 IF( info.NE.0 ) THEN
163 CALL xerbla( 'ZSYTRI', -info )
164 RETURN
165 END IF
166*
167* Quick return if possible
168*
169 IF( n.EQ.0 )
170 $ RETURN
171*
172* Check that the diagonal matrix D is nonsingular.
173*
174 IF( upper ) THEN
175*
176* Upper triangular storage: examine D from bottom to top
177*
178 DO 10 info = n, 1, -1
179 IF( ipiv( info ).GT.0 .AND. a( info, info ).EQ.zero )
180 $ RETURN
181 10 CONTINUE
182 ELSE
183*
184* Lower triangular storage: examine D from top to bottom.
185*
186 DO 20 info = 1, n
187 IF( ipiv( info ).GT.0 .AND. a( info, info ).EQ.zero )
188 $ RETURN
189 20 CONTINUE
190 END IF
191 info = 0
192*
193 IF( upper ) THEN
194*
195* Compute inv(A) from the factorization A = U*D*U**T.
196*
197* K is the main loop index, increasing from 1 to N in steps of
198* 1 or 2, depending on the size of the diagonal blocks.
199*
200 k = 1
201 30 CONTINUE
202*
203* If K > N, exit from loop.
204*
205 IF( k.GT.n )
206 $ GO TO 40
207*
208 IF( ipiv( k ).GT.0 ) THEN
209*
210* 1 x 1 diagonal block
211*
212* Invert the diagonal block.
213*
214 a( k, k ) = one / a( k, k )
215*
216* Compute column K of the inverse.
217*
218 IF( k.GT.1 ) THEN
219 CALL zcopy( k-1, a( 1, k ), 1, work, 1 )
220 CALL zsymv( uplo, k-1, -one, a, lda, work, 1, zero,
221 $ a( 1, k ), 1 )
222 a( k, k ) = a( k, k ) - zdotu( k-1, work, 1, a( 1,
223 $ k ),
224 $ 1 )
225 END IF
226 kstep = 1
227 ELSE
228*
229* 2 x 2 diagonal block
230*
231* Invert the diagonal block.
232*
233 t = a( k, k+1 )
234 ak = a( k, k ) / t
235 akp1 = a( k+1, k+1 ) / t
236 akkp1 = a( k, k+1 ) / t
237 d = t*( ak*akp1-one )
238 a( k, k ) = akp1 / d
239 a( k+1, k+1 ) = ak / d
240 a( k, k+1 ) = -akkp1 / d
241*
242* Compute columns K and K+1 of the inverse.
243*
244 IF( k.GT.1 ) THEN
245 CALL zcopy( k-1, a( 1, k ), 1, work, 1 )
246 CALL zsymv( uplo, k-1, -one, a, lda, work, 1, zero,
247 $ a( 1, k ), 1 )
248 a( k, k ) = a( k, k ) - zdotu( k-1, work, 1, a( 1,
249 $ k ),
250 $ 1 )
251 a( k, k+1 ) = a( k, k+1 ) -
252 $ zdotu( k-1, a( 1, k ), 1, a( 1, k+1 ),
253 $ 1 )
254 CALL zcopy( k-1, a( 1, k+1 ), 1, work, 1 )
255 CALL zsymv( uplo, k-1, -one, a, lda, work, 1, zero,
256 $ a( 1, k+1 ), 1 )
257 a( k+1, k+1 ) = a( k+1, k+1 ) -
258 $ zdotu( k-1, work, 1, a( 1, k+1 ), 1 )
259 END IF
260 kstep = 2
261 END IF
262*
263 kp = abs( ipiv( k ) )
264 IF( kp.NE.k ) THEN
265*
266* Interchange rows and columns K and KP in the leading
267* submatrix A(1:k+1,1:k+1)
268*
269 CALL zswap( kp-1, a( 1, k ), 1, a( 1, kp ), 1 )
270 CALL zswap( k-kp-1, a( kp+1, k ), 1, a( kp, kp+1 ), lda )
271 temp = a( k, k )
272 a( k, k ) = a( kp, kp )
273 a( kp, kp ) = temp
274 IF( kstep.EQ.2 ) THEN
275 temp = a( k, k+1 )
276 a( k, k+1 ) = a( kp, k+1 )
277 a( kp, k+1 ) = temp
278 END IF
279 END IF
280*
281 k = k + kstep
282 GO TO 30
283 40 CONTINUE
284*
285 ELSE
286*
287* Compute inv(A) from the factorization A = L*D*L**T.
288*
289* K is the main loop index, increasing from 1 to N in steps of
290* 1 or 2, depending on the size of the diagonal blocks.
291*
292 k = n
293 50 CONTINUE
294*
295* If K < 1, exit from loop.
296*
297 IF( k.LT.1 )
298 $ GO TO 60
299*
300 IF( ipiv( k ).GT.0 ) THEN
301*
302* 1 x 1 diagonal block
303*
304* Invert the diagonal block.
305*
306 a( k, k ) = one / a( k, k )
307*
308* Compute column K of the inverse.
309*
310 IF( k.LT.n ) THEN
311 CALL zcopy( n-k, a( k+1, k ), 1, work, 1 )
312 CALL zsymv( uplo, n-k, -one, a( k+1, k+1 ), lda, work,
313 $ 1,
314 $ zero, a( k+1, k ), 1 )
315 a( k, k ) = a( k, k ) - zdotu( n-k, work, 1, a( k+1,
316 $ k ),
317 $ 1 )
318 END IF
319 kstep = 1
320 ELSE
321*
322* 2 x 2 diagonal block
323*
324* Invert the diagonal block.
325*
326 t = a( k, k-1 )
327 ak = a( k-1, k-1 ) / t
328 akp1 = a( k, k ) / t
329 akkp1 = a( k, k-1 ) / t
330 d = t*( ak*akp1-one )
331 a( k-1, k-1 ) = akp1 / d
332 a( k, k ) = ak / d
333 a( k, k-1 ) = -akkp1 / d
334*
335* Compute columns K-1 and K of the inverse.
336*
337 IF( k.LT.n ) THEN
338 CALL zcopy( n-k, a( k+1, k ), 1, work, 1 )
339 CALL zsymv( uplo, n-k, -one, a( k+1, k+1 ), lda, work,
340 $ 1,
341 $ zero, a( k+1, k ), 1 )
342 a( k, k ) = a( k, k ) - zdotu( n-k, work, 1, a( k+1,
343 $ k ),
344 $ 1 )
345 a( k, k-1 ) = a( k, k-1 ) -
346 $ zdotu( n-k, a( k+1, k ), 1, a( k+1,
347 $ k-1 ),
348 $ 1 )
349 CALL zcopy( n-k, a( k+1, k-1 ), 1, work, 1 )
350 CALL zsymv( uplo, n-k, -one, a( k+1, k+1 ), lda, work,
351 $ 1,
352 $ zero, a( k+1, k-1 ), 1 )
353 a( k-1, k-1 ) = a( k-1, k-1 ) -
354 $ zdotu( n-k, work, 1, a( k+1, k-1 ),
355 $ 1 )
356 END IF
357 kstep = 2
358 END IF
359*
360 kp = abs( ipiv( k ) )
361 IF( kp.NE.k ) THEN
362*
363* Interchange rows and columns K and KP in the trailing
364* submatrix A(k-1:n,k-1:n)
365*
366 IF( kp.LT.n )
367 $ CALL zswap( n-kp, a( kp+1, k ), 1, a( kp+1, kp ), 1 )
368 CALL zswap( kp-k-1, a( k+1, k ), 1, a( kp, k+1 ), lda )
369 temp = a( k, k )
370 a( k, k ) = a( kp, kp )
371 a( kp, kp ) = temp
372 IF( kstep.EQ.2 ) THEN
373 temp = a( k, k-1 )
374 a( k, k-1 ) = a( kp, k-1 )
375 a( kp, k-1 ) = temp
376 END IF
377 END IF
378*
379 k = k - kstep
380 GO TO 50
381 60 CONTINUE
382 END IF
383*
384 RETURN
385*
386* End of ZSYTRI
387*
388 END
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine zcopy(n, zx, incx, zy, incy)
ZCOPY
Definition zcopy.f:81
subroutine zsymv(uplo, n, alpha, a, lda, x, incx, beta, y, incy)
ZSYMV computes a matrix-vector product for a complex symmetric matrix.
Definition zsymv.f:156
subroutine zsytri(uplo, n, a, lda, ipiv, work, info)
ZSYTRI
Definition zsytri.f:112
subroutine zswap(n, zx, incx, zy, incy)
ZSWAP
Definition zswap.f:81