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