127
128
129
130
131
132
133 CHARACTER UPLO
134 INTEGER INFO, LDA, N
135
136
137 INTEGER IPIV( * )
138 DOUBLE PRECISION A( LDA, * ), WORK( * )
139
140
141
142
143
144 DOUBLE PRECISION ONE, ZERO
145 parameter( one = 1.0d+0, zero = 0.0d+0 )
146
147
148 LOGICAL UPPER
149 INTEGER K, KP, KSTEP
150 DOUBLE PRECISION AK, AKKP1, AKP1, D, T, TEMP
151
152
153 LOGICAL LSAME
154 DOUBLE PRECISION DDOT
156
157
159
160
161 INTRINSIC abs, max
162
163
164
165
166
167 info = 0
168 upper =
lsame( uplo,
'U' )
169 IF( .NOT.upper .AND. .NOT.
lsame( uplo,
'L' ) )
THEN
170 info = -1
171 ELSE IF( n.LT.0 ) THEN
172 info = -2
173 ELSE IF( lda.LT.max( 1, n ) ) THEN
174 info = -4
175 END IF
176 IF( info.NE.0 ) THEN
177 CALL xerbla(
'DSYTRI_ROOK', -info )
178 RETURN
179 END IF
180
181
182
183 IF( n.EQ.0 )
184 $ RETURN
185
186
187
188 IF( upper ) THEN
189
190
191
192 DO 10 info = n, 1, -1
193 IF( ipiv( info ).GT.0 .AND. a( info, info ).EQ.zero )
194 $ RETURN
195 10 CONTINUE
196 ELSE
197
198
199
200 DO 20 info = 1, n
201 IF( ipiv( info ).GT.0 .AND. a( info, info ).EQ.zero )
202 $ RETURN
203 20 CONTINUE
204 END IF
205 info = 0
206
207 IF( upper ) THEN
208
209
210
211
212
213
214 k = 1
215 30 CONTINUE
216
217
218
219 IF( k.GT.n )
220 $ GO TO 40
221
222 IF( ipiv( k ).GT.0 ) THEN
223
224
225
226
227
228 a( k, k ) = one / a( k, k )
229
230
231
232 IF( k.GT.1 ) THEN
233 CALL dcopy( k-1, a( 1, k ), 1, work, 1 )
234 CALL dsymv( uplo, k-1, -one, a, lda, work, 1, zero,
235 $ a( 1, k ), 1 )
236 a( k, k ) = a( k, k ) -
ddot( k-1, work, 1, a( 1, k ),
237 $ 1 )
238 END IF
239 kstep = 1
240 ELSE
241
242
243
244
245
246 t = abs( a( k, k+1 ) )
247 ak = a( k, k ) / t
248 akp1 = a( k+1, k+1 ) / t
249 akkp1 = a( k, k+1 ) / t
250 d = t*( ak*akp1-one )
251 a( k, k ) = akp1 / d
252 a( k+1, k+1 ) = ak / d
253 a( k, k+1 ) = -akkp1 / d
254
255
256
257 IF( k.GT.1 ) THEN
258 CALL dcopy( k-1, a( 1, k ), 1, work, 1 )
259 CALL dsymv( uplo, k-1, -one, a, lda, work, 1, zero,
260 $ a( 1, k ), 1 )
261 a( k, k ) = a( k, k ) -
ddot( k-1, work, 1, a( 1, k ),
262 $ 1 )
263 a( k, k+1 ) = a( k, k+1 ) -
264 $
ddot( k-1, a( 1, k ), 1, a( 1, k+1 ),
265 $ 1 )
266 CALL dcopy( k-1, a( 1, k+1 ), 1, work, 1 )
267 CALL dsymv( uplo, k-1, -one, a, lda, work, 1, zero,
268 $ a( 1, k+1 ), 1 )
269 a( k+1, k+1 ) = a( k+1, k+1 ) -
270 $
ddot( k-1, work, 1, a( 1, k+1 ), 1 )
271 END IF
272 kstep = 2
273 END IF
274
275 IF( kstep.EQ.1 ) THEN
276
277
278
279
280 kp = ipiv( k )
281 IF( kp.NE.k ) THEN
282 IF( kp.GT.1 )
283 $
CALL dswap( kp-1, a( 1, k ), 1, a( 1, kp ), 1 )
284 CALL dswap( k-kp-1, a( kp+1, k ), 1, a( kp, kp+1 ),
285 $ lda )
286 temp = a( k, k )
287 a( k, k ) = a( kp, kp )
288 a( kp, kp ) = temp
289 END IF
290 ELSE
291
292
293
294
295 kp = -ipiv( k )
296 IF( kp.NE.k ) THEN
297 IF( kp.GT.1 )
298 $
CALL dswap( kp-1, a( 1, k ), 1, a( 1, kp ), 1 )
299 CALL dswap( k-kp-1, a( kp+1, k ), 1, a( kp, kp+1 ),
300 $ lda )
301
302 temp = a( k, k )
303 a( k, k ) = a( kp, kp )
304 a( kp, kp ) = temp
305 temp = a( k, k+1 )
306 a( k, k+1 ) = a( kp, k+1 )
307 a( kp, k+1 ) = temp
308 END IF
309
310 k = k + 1
311 kp = -ipiv( k )
312 IF( kp.NE.k ) THEN
313 IF( kp.GT.1 )
314 $
CALL dswap( kp-1, a( 1, k ), 1, a( 1, kp ), 1 )
315 CALL dswap( k-kp-1, a( kp+1, k ), 1, a( kp, kp+1 ),
316 $ lda )
317 temp = a( k, k )
318 a( k, k ) = a( kp, kp )
319 a( kp, kp ) = temp
320 END IF
321 END IF
322
323 k = k + 1
324 GO TO 30
325 40 CONTINUE
326
327 ELSE
328
329
330
331
332
333
334 k = n
335 50 CONTINUE
336
337
338
339 IF( k.LT.1 )
340 $ GO TO 60
341
342 IF( ipiv( k ).GT.0 ) THEN
343
344
345
346
347
348 a( k, k ) = one / a( k, k )
349
350
351
352 IF( k.LT.n ) THEN
353 CALL dcopy( n-k, a( k+1, k ), 1, work, 1 )
354 CALL dsymv( uplo, n-k, -one, a( k+1, k+1 ), lda, work,
355 $ 1,
356 $ zero, a( k+1, k ), 1 )
357 a( k, k ) = a( k, k ) -
ddot( n-k, work, 1, a( k+1,
358 $ k ),
359 $ 1 )
360 END IF
361 kstep = 1
362 ELSE
363
364
365
366
367
368 t = abs( a( k, k-1 ) )
369 ak = a( k-1, k-1 ) / t
370 akp1 = a( k, k ) / t
371 akkp1 = a( k, k-1 ) / t
372 d = t*( ak*akp1-one )
373 a( k-1, k-1 ) = akp1 / d
374 a( k, k ) = ak / d
375 a( k, k-1 ) = -akkp1 / d
376
377
378
379 IF( k.LT.n ) THEN
380 CALL dcopy( n-k, a( k+1, k ), 1, work, 1 )
381 CALL dsymv( uplo, n-k, -one, a( k+1, k+1 ), lda, work,
382 $ 1,
383 $ zero, a( k+1, k ), 1 )
384 a( k, k ) = a( k, k ) -
ddot( n-k, work, 1, a( k+1,
385 $ k ),
386 $ 1 )
387 a( k, k-1 ) = a( k, k-1 ) -
388 $
ddot( n-k, a( k+1, k ), 1, a( k+1,
389 $ k-1 ),
390 $ 1 )
391 CALL dcopy( n-k, a( k+1, k-1 ), 1, work, 1 )
392 CALL dsymv( uplo, n-k, -one, a( k+1, k+1 ), lda, work,
393 $ 1,
394 $ zero, a( k+1, k-1 ), 1 )
395 a( k-1, k-1 ) = a( k-1, k-1 ) -
396 $
ddot( n-k, work, 1, a( k+1, k-1 ), 1 )
397 END IF
398 kstep = 2
399 END IF
400
401 IF( kstep.EQ.1 ) THEN
402
403
404
405
406 kp = ipiv( k )
407 IF( kp.NE.k ) THEN
408 IF( kp.LT.n )
409 $
CALL dswap( n-kp, a( kp+1, k ), 1, a( kp+1, kp ),
410 $ 1 )
411 CALL dswap( kp-k-1, a( k+1, k ), 1, a( kp, k+1 ),
412 $ lda )
413 temp = a( k, k )
414 a( k, k ) = a( kp, kp )
415 a( kp, kp ) = temp
416 END IF
417 ELSE
418
419
420
421
422 kp = -ipiv( k )
423 IF( kp.NE.k ) THEN
424 IF( kp.LT.n )
425 $
CALL dswap( n-kp, a( kp+1, k ), 1, a( kp+1, kp ),
426 $ 1 )
427 CALL dswap( kp-k-1, a( k+1, k ), 1, a( kp, k+1 ),
428 $ lda )
429
430 temp = a( k, k )
431 a( k, k ) = a( kp, kp )
432 a( kp, kp ) = temp
433 temp = a( k, k-1 )
434 a( k, k-1 ) = a( kp, k-1 )
435 a( kp, k-1 ) = temp
436 END IF
437
438 k = k - 1
439 kp = -ipiv( k )
440 IF( kp.NE.k ) THEN
441 IF( kp.LT.n )
442 $
CALL dswap( n-kp, a( kp+1, k ), 1, a( kp+1, kp ),
443 $ 1 )
444 CALL dswap( kp-k-1, a( k+1, k ), 1, a( kp, k+1 ),
445 $ lda )
446 temp = a( k, k )
447 a( k, k ) = a( kp, kp )
448 a( kp, kp ) = temp
449 END IF
450 END IF
451
452 k = k - 1
453 GO TO 50
454 60 CONTINUE
455 END IF
456
457 RETURN
458
459
460
subroutine xerbla(srname, info)
subroutine dcopy(n, dx, incx, dy, incy)
DCOPY
double precision function ddot(n, dx, incx, dy, incy)
DDOT
subroutine dsymv(uplo, n, alpha, a, lda, x, incx, beta, y, incy)
DSYMV
logical function lsame(ca, cb)
LSAME
subroutine dswap(n, dx, incx, dy, incy)
DSWAP