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 REAL S
139 COMPLEX AK, AKM1, AKM1K, BK, BKM1, DENOM
140
141
142 LOGICAL LSAME
144
145
147
148
149 INTRINSIC conjg, max, real
150
151
152
153 info = 0
154 upper =
lsame( uplo,
'U' )
155 IF( .NOT.upper .AND. .NOT.
lsame( uplo,
'L' ) )
THEN
156 info = -1
157 ELSE IF( n.LT.0 ) THEN
158 info = -2
159 ELSE IF( nrhs.LT.0 ) THEN
160 info = -3
161 ELSE IF( ldb.LT.max( 1, n ) ) THEN
162 info = -7
163 END IF
164 IF( info.NE.0 ) THEN
165 CALL xerbla(
'CHPTRS', -info )
166 RETURN
167 END IF
168
169
170
171 IF( n.EQ.0 .OR. nrhs.EQ.0 )
172 $ RETURN
173
174 IF( upper ) THEN
175
176
177
178
179
180
181
182
183 k = n
184 kc = n*( n+1 ) / 2 + 1
185 10 CONTINUE
186
187
188
189 IF( k.LT.1 )
190 $ GO TO 30
191
192 kc = kc - k
193 IF( ipiv( k ).GT.0 ) THEN
194
195
196
197
198
199 kp = ipiv( k )
200 IF( kp.NE.k )
201 $
CALL cswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
202
203
204
205
206 CALL cgeru( k-1, nrhs, -one, ap( kc ), 1, b( k, 1 ), ldb,
207 $ b( 1, 1 ), ldb )
208
209
210
211 s = real( one ) / real( ap( kc+k-1 ) )
212 CALL csscal( nrhs, s, b( k, 1 ), ldb )
213 k = k - 1
214 ELSE
215
216
217
218
219
220 kp = -ipiv( k )
221 IF( kp.NE.k-1 )
222 $
CALL cswap( nrhs, b( k-1, 1 ), ldb, b( kp, 1 ), ldb )
223
224
225
226
227 CALL cgeru( k-2, nrhs, -one, ap( kc ), 1, b( k, 1 ), ldb,
228 $ b( 1, 1 ), ldb )
229 CALL cgeru( k-2, nrhs, -one, ap( kc-( k-1 ) ), 1,
230 $ b( k-1, 1 ), ldb, b( 1, 1 ), ldb )
231
232
233
234 akm1k = ap( kc+k-2 )
235 akm1 = ap( kc-1 ) / akm1k
236 ak = ap( kc+k-1 ) / conjg( akm1k )
237 denom = akm1*ak - one
238 DO 20 j = 1, nrhs
239 bkm1 = b( k-1, j ) / akm1k
240 bk = b( k, j ) / conjg( akm1k )
241 b( k-1, j ) = ( ak*bkm1-bk ) / denom
242 b( k, j ) = ( akm1*bk-bkm1 ) / denom
243 20 CONTINUE
244 kc = kc - k + 1
245 k = k - 2
246 END IF
247
248 GO TO 10
249 30 CONTINUE
250
251
252
253
254
255
256 k = 1
257 kc = 1
258 40 CONTINUE
259
260
261
262 IF( k.GT.n )
263 $ GO TO 50
264
265 IF( ipiv( k ).GT.0 ) THEN
266
267
268
269
270
271
272 IF( k.GT.1 ) THEN
273 CALL clacgv( nrhs, b( k, 1 ), ldb )
274 CALL cgemv(
'Conjugate transpose', k-1, nrhs, -one, b,
275 $ ldb, ap( kc ), 1, one, b( k, 1 ), ldb )
276 CALL clacgv( nrhs, b( k, 1 ), ldb )
277 END IF
278
279
280
281 kp = ipiv( k )
282 IF( kp.NE.k )
283 $
CALL cswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
284 kc = kc + k
285 k = k + 1
286 ELSE
287
288
289
290
291
292
293 IF( k.GT.1 ) THEN
294 CALL clacgv( nrhs, b( k, 1 ), ldb )
295 CALL cgemv(
'Conjugate transpose', k-1, nrhs, -one, b,
296 $ ldb, ap( kc ), 1, one, b( k, 1 ), ldb )
297 CALL clacgv( nrhs, b( k, 1 ), ldb )
298
299 CALL clacgv( nrhs, b( k+1, 1 ), ldb )
300 CALL cgemv(
'Conjugate transpose', k-1, nrhs, -one, b,
301 $ ldb, ap( kc+k ), 1, one, b( k+1, 1 ), ldb )
302 CALL clacgv( nrhs, b( k+1, 1 ), ldb )
303 END IF
304
305
306
307 kp = -ipiv( k )
308 IF( kp.NE.k )
309 $
CALL cswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
310 kc = kc + 2*k + 1
311 k = k + 2
312 END IF
313
314 GO TO 40
315 50 CONTINUE
316
317 ELSE
318
319
320
321
322
323
324
325
326 k = 1
327 kc = 1
328 60 CONTINUE
329
330
331
332 IF( k.GT.n )
333 $ GO TO 80
334
335 IF( ipiv( k ).GT.0 ) THEN
336
337
338
339
340
341 kp = ipiv( k )
342 IF( kp.NE.k )
343 $
CALL cswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
344
345
346
347
348 IF( k.LT.n )
349 $
CALL cgeru( n-k, nrhs, -one, ap( kc+1 ), 1, b( k, 1 ),
350 $ ldb, b( k+1, 1 ), ldb )
351
352
353
354 s = real( one ) / real( ap( kc ) )
355 CALL csscal( nrhs, s, b( k, 1 ), ldb )
356 kc = kc + n - k + 1
357 k = k + 1
358 ELSE
359
360
361
362
363
364 kp = -ipiv( k )
365 IF( kp.NE.k+1 )
366 $
CALL cswap( nrhs, b( k+1, 1 ), ldb, b( kp, 1 ), ldb )
367
368
369
370
371 IF( k.LT.n-1 ) THEN
372 CALL cgeru( n-k-1, nrhs, -one, ap( kc+2 ), 1, b( k, 1 ),
373 $ ldb, b( k+2, 1 ), ldb )
374 CALL cgeru( n-k-1, nrhs, -one, ap( kc+n-k+2 ), 1,
375 $ b( k+1, 1 ), ldb, b( k+2, 1 ), ldb )
376 END IF
377
378
379
380 akm1k = ap( kc+1 )
381 akm1 = ap( kc ) / conjg( akm1k )
382 ak = ap( kc+n-k+1 ) / akm1k
383 denom = akm1*ak - one
384 DO 70 j = 1, nrhs
385 bkm1 = b( k, j ) / conjg( akm1k )
386 bk = b( k+1, j ) / akm1k
387 b( k, j ) = ( ak*bkm1-bk ) / denom
388 b( k+1, j ) = ( akm1*bk-bkm1 ) / denom
389 70 CONTINUE
390 kc = kc + 2*( n-k ) + 1
391 k = k + 2
392 END IF
393
394 GO TO 60
395 80 CONTINUE
396
397
398
399
400
401
402 k = n
403 kc = n*( n+1 ) / 2 + 1
404 90 CONTINUE
405
406
407
408 IF( k.LT.1 )
409 $ GO TO 100
410
411 kc = kc - ( n-k+1 )
412 IF( ipiv( k ).GT.0 ) THEN
413
414
415
416
417
418
419 IF( k.LT.n ) THEN
420 CALL clacgv( nrhs, b( k, 1 ), ldb )
421 CALL cgemv(
'Conjugate transpose', n-k, nrhs, -one,
422 $ b( k+1, 1 ), ldb, ap( kc+1 ), 1, one,
423 $ b( k, 1 ), ldb )
424 CALL clacgv( nrhs, b( k, 1 ), ldb )
425 END IF
426
427
428
429 kp = ipiv( k )
430 IF( kp.NE.k )
431 $
CALL cswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
432 k = k - 1
433 ELSE
434
435
436
437
438
439
440 IF( k.LT.n ) THEN
441 CALL clacgv( nrhs, b( k, 1 ), ldb )
442 CALL cgemv(
'Conjugate transpose', n-k, nrhs, -one,
443 $ b( k+1, 1 ), ldb, ap( kc+1 ), 1, one,
444 $ b( k, 1 ), ldb )
445 CALL clacgv( nrhs, b( k, 1 ), ldb )
446
447 CALL clacgv( nrhs, b( k-1, 1 ), ldb )
448 CALL cgemv(
'Conjugate transpose', n-k, nrhs, -one,
449 $ b( k+1, 1 ), ldb, ap( kc-( n-k ) ), 1, one,
450 $ b( k-1, 1 ), ldb )
451 CALL clacgv( nrhs, b( k-1, 1 ), ldb )
452 END IF
453
454
455
456 kp = -ipiv( k )
457 IF( kp.NE.k )
458 $
CALL cswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
459 kc = kc - ( n-k+2 )
460 k = k - 2
461 END IF
462
463 GO TO 90
464 100 CONTINUE
465 END IF
466
467 RETURN
468
469
470
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
subroutine clacgv(n, x, incx)
CLACGV conjugates a complex vector.
logical function lsame(ca, cb)
LSAME
subroutine csscal(n, sa, cx, incx)
CSSCAL
subroutine cswap(n, cx, incx, cy, incy)
CSWAP