107
108
109
110
111
112
113 CHARACTER UPLO
114 INTEGER INFO, N
115
116
117 INTEGER IPIV( * )
118 COMPLEX*16 AP( * ), WORK( * )
119
120
121
122
123
124 COMPLEX*16 ONE, ZERO
125 parameter( one = ( 1.0d+0, 0.0d+0 ),
126 $ zero = ( 0.0d+0, 0.0d+0 ) )
127
128
129 LOGICAL UPPER
130 INTEGER J, K, KC, KCNEXT, KP, KPC, KSTEP, KX, NPP
131 COMPLEX*16 AK, AKKP1, AKP1, D, T, TEMP
132
133
134 LOGICAL LSAME
135 COMPLEX*16 ZDOTU
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(
'ZSPTRI', -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 zcopy( k-1, ap( kc ), 1, work, 1 )
219 CALL zspmv( uplo, k-1, -one, ap, work, 1, zero,
220 $ ap( kc ),
221 $ 1 )
222 ap( kc+k-1 ) = ap( kc+k-1 ) -
223 $
zdotu( 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 zcopy( k-1, ap( kc ), 1, work, 1 )
245 CALL zspmv( uplo, k-1, -one, ap, work, 1, zero,
246 $ ap( kc ),
247 $ 1 )
248 ap( kc+k-1 ) = ap( kc+k-1 ) -
249 $
zdotu( k-1, work, 1, ap( kc ), 1 )
250 ap( kcnext+k-1 ) = ap( kcnext+k-1 ) -
251 $
zdotu( k-1, ap( kc ), 1,
252 $ ap( kcnext ),
253 $ 1 )
254 CALL zcopy( k-1, ap( kcnext ), 1, work, 1 )
255 CALL zspmv( uplo, k-1, -one, ap, work, 1, zero,
256 $ ap( kcnext ), 1 )
257 ap( kcnext+k ) = ap( kcnext+k ) -
258 $
zdotu( 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 zswap( 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 zcopy( n-k, ap( kc+1 ), 1, work, 1 )
325 CALL zspmv( uplo, n-k, -one, ap( kc+n-k+1 ), work, 1,
326 $ zero, ap( kc+1 ), 1 )
327 ap( kc ) = ap( kc ) -
zdotu( 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 zcopy( n-k, ap( kc+1 ), 1, work, 1 )
350 CALL zspmv( uplo, n-k, -one, ap( kc+( n-k+1 ) ), work,
351 $ 1,
352 $ zero, ap( kc+1 ), 1 )
353 ap( kc ) = ap( kc ) -
zdotu( n-k, work, 1, ap( kc+1 ),
354 $ 1 )
355 ap( kcnext+1 ) = ap( kcnext+1 ) -
356 $
zdotu( n-k, ap( kc+1 ), 1,
357 $ ap( kcnext+2 ), 1 )
358 CALL zcopy( n-k, ap( kcnext+2 ), 1, work, 1 )
359 CALL zspmv( uplo, n-k, -one, ap( kc+( n-k+1 ) ), work,
360 $ 1,
361 $ zero, ap( kcnext+2 ), 1 )
362 ap( kcnext ) = ap( kcnext ) -
363 $
zdotu( 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 zswap( 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 zcopy(n, zx, incx, zy, incy)
ZCOPY
complex *16 function zdotu(n, zx, incx, zy, incy)
ZDOTU
subroutine zspmv(uplo, n, alpha, ap, x, incx, beta, y, incy)
ZSPMV computes a matrix-vector product for complex vectors using a complex symmetric packed matrix
logical function lsame(ca, cb)
LSAME
subroutine zswap(n, zx, incx, zy, incy)
ZSWAP