109
110
111
112
113
114
115 CHARACTER UPLO
116 INTEGER INFO, N
117
118
119 INTEGER IPIV( * )
120 COMPLEX AP( * ), WORK( * )
121
122
123
124
125
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
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
138 LOGICAL LSAME
139 COMPLEX CDOTC
141
142
144
145
146 INTRINSIC abs, conjg, real
147
148
149
150
151
152 info = 0
153 upper =
lsame( uplo,
'U' )
154 IF( .NOT.upper .AND. .NOT.
lsame( uplo,
'L' ) )
THEN
155 info = -1
156 ELSE IF( n.LT.0 ) THEN
157 info = -2
158 END IF
159 IF( info.NE.0 ) THEN
160 CALL xerbla(
'CHPTRI', -info )
161 RETURN
162 END IF
163
164
165
166 IF( n.EQ.0 )
167 $ RETURN
168
169
170
171 IF( upper ) THEN
172
173
174
175 kp = n*( n+1 ) / 2
176 DO 10 info = n, 1, -1
177 IF( ipiv( info ).GT.0 .AND. ap( kp ).EQ.zero )
178 $ RETURN
179 kp = kp - info
180 10 CONTINUE
181 ELSE
182
183
184
185 kp = 1
186 DO 20 info = 1, n
187 IF( ipiv( info ).GT.0 .AND. ap( kp ).EQ.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
197
198
199
200
201 k = 1
202 kc = 1
203 30 CONTINUE
204
205
206
207 IF( k.GT.n )
208 $ GO TO 50
209
210 kcnext = kc + k
211 IF( ipiv( k ).GT.0 ) THEN
212
213
214
215
216
217 ap( kc+k-1 ) = one / real( ap( kc+k-1 ) )
218
219
220
221 IF( k.GT.1 ) 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
232
233
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
245
246 IF( k.GT.1 ) 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 IF( kp.NE.k ) THEN
268
269
270
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 IF( kstep.EQ.2 ) 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
300
301
302
303
304 npp = n*( n+1 ) / 2
305 k = n
306 kc = npp
307 60 CONTINUE
308
309
310
311 IF( k.LT.1 )
312 $ GO TO 80
313
314 kcnext = kc - ( n-k+2 )
315 IF( ipiv( k ).GT.0 ) THEN
316
317
318
319
320
321 ap( kc ) = one / real( ap( kc ) )
322
323
324
325 IF( k.LT.n ) 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
336
337
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
349
350 IF( k.LT.n ) 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 IF( kp.NE.k ) THEN
372
373
374
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 = 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 IF( kstep.EQ.2 ) 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
406
subroutine xerbla(srname, info)
subroutine ccopy(n, cx, incx, cy, incy)
CCOPY
complex function cdotc(n, cx, incx, cy, incy)
CDOTC
subroutine chpmv(uplo, n, alpha, ap, x, incx, beta, y, incy)
CHPMV
logical function lsame(ca, cb)
LSAME
subroutine cswap(n, cx, incx, cy, incy)
CSWAP