107
108
109
110
111
112
113 CHARACTER UPLO
114 INTEGER INFO, N
115
116
117 INTEGER IPIV( * )
118 COMPLEX AP( * ), WORK( * )
119
120
121
122
123
124 COMPLEX ONE, ZERO
125 parameter( one = ( 1.0e+0, 0.0e+0 ),
126 $ zero = ( 0.0e+0, 0.0e+0 ) )
127
128
129 LOGICAL UPPER
130 INTEGER J, K, KC, KCNEXT, KP, KPC, KSTEP, KX, NPP
131 COMPLEX AK, AKKP1, AKP1, D, T, TEMP
132
133
134 LOGICAL LSAME
135 COMPLEX CDOTU
137
138
140
141
142 INTRINSIC abs
143
144
145
146
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
161
162 IF( n.EQ.0 )
163 $ RETURN
164
165
166
167 IF( upper ) THEN
168
169
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
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
193
194
195
196
197 k = 1
198 kc = 1
199 30 CONTINUE
200
201
202
203 IF( k.GT.n )
204 $ GO TO 50
205
206 kcnext = kc + k
207 IF( ipiv( k ).GT.0 ) THEN
208
209
210
211
212
213 ap( kc+k-1 ) = one / ap( kc+k-1 )
214
215
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
229
230
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
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
269
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
298
299
300
301
302 npp = n*( n+1 ) / 2
303 k = n
304 kc = npp
305 60 CONTINUE
306
307
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
316
317
318
319 ap( kc ) = one / ap( kc )
320
321
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
334
335
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
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
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 = 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
405
subroutine xerbla(srname, info)
subroutine ccopy(n, cx, incx, cy, incy)
CCOPY
complex function cdotu(n, cx, incx, cy, incy)
CDOTU
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
logical function lsame(ca, cb)
LSAME
subroutine cswap(n, cx, incx, cy, incy)
CSWAP