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