115
116
117
118
119
120
121 CHARACTER UPLO
122 INTEGER INFO, LDB, N, NRHS
123
124
125 INTEGER IPIV( * )
126 COMPLEX AP( * ), B( LDB, * )
127
128
129
130
131
132 COMPLEX ONE
133 parameter( one = ( 1.0e+0, 0.0e+0 ) )
134
135
136 LOGICAL UPPER
137 INTEGER J, K, KC, KP
138 COMPLEX AK, AKM1, AKM1K, BK, BKM1, DENOM
139
140
141 LOGICAL LSAME
143
144
146
147
148 INTRINSIC max
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 ELSE IF( nrhs.LT.0 ) THEN
159 info = -3
160 ELSE IF( ldb.LT.max( 1, n ) ) THEN
161 info = -7
162 END IF
163 IF( info.NE.0 ) THEN
164 CALL xerbla(
'CSPTRS', -info )
165 RETURN
166 END IF
167
168
169
170 IF( n.EQ.0 .OR. nrhs.EQ.0 )
171 $ RETURN
172
173 IF( upper ) THEN
174
175
176
177
178
179
180
181
182 k = n
183 kc = n*( n+1 ) / 2 + 1
184 10 CONTINUE
185
186
187
188 IF( k.LT.1 )
189 $ GO TO 30
190
191 kc = kc - k
192 IF( ipiv( k ).GT.0 ) THEN
193
194
195
196
197
198 kp = ipiv( k )
199 IF( kp.NE.k )
200 $
CALL cswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
201
202
203
204
205 CALL cgeru( k-1, nrhs, -one, ap( kc ), 1, b( k, 1 ), ldb,
206 $ b( 1, 1 ), ldb )
207
208
209
210 CALL cscal( nrhs, one / ap( kc+k-1 ), b( k, 1 ), ldb )
211 k = k - 1
212 ELSE
213
214
215
216
217
218 kp = -ipiv( k )
219 IF( kp.NE.k-1 )
220 $
CALL cswap( nrhs, b( k-1, 1 ), ldb, b( kp, 1 ), ldb )
221
222
223
224
225 CALL cgeru( k-2, nrhs, -one, ap( kc ), 1, b( k, 1 ), ldb,
226 $ b( 1, 1 ), ldb )
227 CALL cgeru( k-2, nrhs, -one, ap( kc-( k-1 ) ), 1,
228 $ b( k-1, 1 ), ldb, b( 1, 1 ), ldb )
229
230
231
232 akm1k = ap( kc+k-2 )
233 akm1 = ap( kc-1 ) / akm1k
234 ak = ap( kc+k-1 ) / akm1k
235 denom = akm1*ak - one
236 DO 20 j = 1, nrhs
237 bkm1 = b( k-1, j ) / akm1k
238 bk = b( k, j ) / akm1k
239 b( k-1, j ) = ( ak*bkm1-bk ) / denom
240 b( k, j ) = ( akm1*bk-bkm1 ) / denom
241 20 CONTINUE
242 kc = kc - k + 1
243 k = k - 2
244 END IF
245
246 GO TO 10
247 30 CONTINUE
248
249
250
251
252
253
254 k = 1
255 kc = 1
256 40 CONTINUE
257
258
259
260 IF( k.GT.n )
261 $ GO TO 50
262
263 IF( ipiv( k ).GT.0 ) THEN
264
265
266
267
268
269
270 CALL cgemv(
'Transpose', k-1, nrhs, -one, b, ldb, ap( kc ),
271 $ 1, one, b( k, 1 ), ldb )
272
273
274
275 kp = ipiv( k )
276 IF( kp.NE.k )
277 $
CALL cswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
278 kc = kc + k
279 k = k + 1
280 ELSE
281
282
283
284
285
286
287 CALL cgemv(
'Transpose', k-1, nrhs, -one, b, ldb, ap( kc ),
288 $ 1, one, b( k, 1 ), ldb )
289 CALL cgemv(
'Transpose', k-1, nrhs, -one, b, ldb,
290 $ ap( kc+k ), 1, one, b( k+1, 1 ), ldb )
291
292
293
294 kp = -ipiv( k )
295 IF( kp.NE.k )
296 $
CALL cswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
297 kc = kc + 2*k + 1
298 k = k + 2
299 END IF
300
301 GO TO 40
302 50 CONTINUE
303
304 ELSE
305
306
307
308
309
310
311
312
313 k = 1
314 kc = 1
315 60 CONTINUE
316
317
318
319 IF( k.GT.n )
320 $ GO TO 80
321
322 IF( ipiv( k ).GT.0 ) THEN
323
324
325
326
327
328 kp = ipiv( k )
329 IF( kp.NE.k )
330 $
CALL cswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
331
332
333
334
335 IF( k.LT.n )
336 $
CALL cgeru( n-k, nrhs, -one, ap( kc+1 ), 1, b( k, 1 ),
337 $ ldb, b( k+1, 1 ), ldb )
338
339
340
341 CALL cscal( nrhs, one / ap( kc ), b( k, 1 ), ldb )
342 kc = kc + n - k + 1
343 k = k + 1
344 ELSE
345
346
347
348
349
350 kp = -ipiv( k )
351 IF( kp.NE.k+1 )
352 $
CALL cswap( nrhs, b( k+1, 1 ), ldb, b( kp, 1 ), ldb )
353
354
355
356
357 IF( k.LT.n-1 ) THEN
358 CALL cgeru( n-k-1, nrhs, -one, ap( kc+2 ), 1, b( k, 1 ),
359 $ ldb, b( k+2, 1 ), ldb )
360 CALL cgeru( n-k-1, nrhs, -one, ap( kc+n-k+2 ), 1,
361 $ b( k+1, 1 ), ldb, b( k+2, 1 ), ldb )
362 END IF
363
364
365
366 akm1k = ap( kc+1 )
367 akm1 = ap( kc ) / akm1k
368 ak = ap( kc+n-k+1 ) / akm1k
369 denom = akm1*ak - one
370 DO 70 j = 1, nrhs
371 bkm1 = b( k, j ) / akm1k
372 bk = b( k+1, j ) / akm1k
373 b( k, j ) = ( ak*bkm1-bk ) / denom
374 b( k+1, j ) = ( akm1*bk-bkm1 ) / denom
375 70 CONTINUE
376 kc = kc + 2*( n-k ) + 1
377 k = k + 2
378 END IF
379
380 GO TO 60
381 80 CONTINUE
382
383
384
385
386
387
388 k = n
389 kc = n*( n+1 ) / 2 + 1
390 90 CONTINUE
391
392
393
394 IF( k.LT.1 )
395 $ GO TO 100
396
397 kc = kc - ( n-k+1 )
398 IF( ipiv( k ).GT.0 ) THEN
399
400
401
402
403
404
405 IF( k.LT.n )
406 $
CALL cgemv(
'Transpose', n-k, nrhs, -one, b( k+1, 1 ),
407 $ ldb, ap( kc+1 ), 1, one, b( k, 1 ), ldb )
408
409
410
411 kp = ipiv( k )
412 IF( kp.NE.k )
413 $
CALL cswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
414 k = k - 1
415 ELSE
416
417
418
419
420
421
422 IF( k.LT.n ) THEN
423 CALL cgemv(
'Transpose', n-k, nrhs, -one, b( k+1, 1 ),
424 $ ldb, ap( kc+1 ), 1, one, b( k, 1 ), ldb )
425 CALL cgemv(
'Transpose', n-k, nrhs, -one, b( k+1, 1 ),
426 $ ldb, ap( kc-( n-k ) ), 1, one, b( k-1, 1 ),
427 $ ldb )
428 END IF
429
430
431
432 kp = -ipiv( k )
433 IF( kp.NE.k )
434 $
CALL cswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
435 kc = kc - ( n-k+2 )
436 k = k - 2
437 END IF
438
439 GO TO 90
440 100 CONTINUE
441 END IF
442
443 RETURN
444
445
446
subroutine xerbla(srname, info)
subroutine cgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
CGEMV
subroutine cgeru(m, n, alpha, x, incx, y, incy, a, lda)
CGERU
logical function lsame(ca, cb)
LSAME
subroutine cscal(n, ca, cx, incx)
CSCAL
subroutine cswap(n, cx, incx, cy, incy)
CSWAP