132
133
134
135
136
137
138 CHARACTER UPLO
139 INTEGER INFO, LDA, LDB, N, NRHS
140
141
142 INTEGER IPIV( * )
143 REAL A( LDA, * ), B( LDB, * ), WORK( * )
144
145
146
147
148
149 REAL ONE
150 parameter( one = 1.0e+0 )
151
152
153 LOGICAL UPPER
154 INTEGER I, IINFO, J, K, KP
155 REAL AK, AKM1, AKM1K, BK, BKM1, DENOM
156
157
158 LOGICAL LSAME
160
161
163
164
165 INTRINSIC max
166
167
168
169 info = 0
170 upper =
lsame( uplo,
'U' )
171 IF( .NOT.upper .AND. .NOT.
lsame( uplo,
'L' ) )
THEN
172 info = -1
173 ELSE IF( n.LT.0 ) THEN
174 info = -2
175 ELSE IF( nrhs.LT.0 ) THEN
176 info = -3
177 ELSE IF( lda.LT.max( 1, n ) ) THEN
178 info = -5
179 ELSE IF( ldb.LT.max( 1, n ) ) THEN
180 info = -8
181 END IF
182 IF( info.NE.0 ) THEN
183 CALL xerbla(
'SSYTRS2', -info )
184 RETURN
185 END IF
186
187
188
189 IF( n.EQ.0 .OR. nrhs.EQ.0 )
190 $ RETURN
191
192
193
194 CALL ssyconv( uplo,
'C', n, a, lda, ipiv, work, iinfo )
195
196 IF( upper ) THEN
197
198
199
200
201 k=n
202 DO WHILE ( k .GE. 1 )
203 IF( ipiv( k ).GT.0 ) THEN
204
205
206 kp = ipiv( k )
207 IF( kp.NE.k )
208 $
CALL sswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
209 k=k-1
210 ELSE
211
212
213 kp = -ipiv( k )
214 IF( kp.EQ.-ipiv( k-1 ) )
215 $
CALL sswap( nrhs, b( k-1, 1 ), ldb, b( kp, 1 ), ldb )
216 k=k-2
217 END IF
218 END DO
219
220
221
222 CALL strsm(
'L',
'U',
'N',
'U',n,nrhs,one,a,lda,b,ldb)
223
224
225
226 i=n
227 DO WHILE ( i .GE. 1 )
228 IF( ipiv(i) .GT. 0 ) THEN
229 CALL sscal( nrhs, one / a( i, i ), b( i, 1 ), ldb )
230 ELSEIF ( i .GT. 1) THEN
231 IF ( ipiv(i-1) .EQ. ipiv(i) ) THEN
232 akm1k = work(i)
233 akm1 = a( i-1, i-1 ) / akm1k
234 ak = a( i, i ) / akm1k
235 denom = akm1*ak - one
236 DO 15 j = 1, nrhs
237 bkm1 = b( i-1, j ) / akm1k
238 bk = b( i, j ) / akm1k
239 b( i-1, j ) = ( ak*bkm1-bk ) / denom
240 b( i, j ) = ( akm1*bk-bkm1 ) / denom
241 15 CONTINUE
242 i = i - 1
243 ENDIF
244 ENDIF
245 i = i - 1
246 END DO
247
248
249
250 CALL strsm(
'L',
'U',
'T',
'U',n,nrhs,one,a,lda,b,ldb)
251
252
253
254 k=1
255 DO WHILE ( k .LE. n )
256 IF( ipiv( k ).GT.0 ) THEN
257
258
259 kp = ipiv( k )
260 IF( kp.NE.k )
261 $
CALL sswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
262 k=k+1
263 ELSE
264
265
266 kp = -ipiv( k )
267 IF( k .LT. n .AND. kp.EQ.-ipiv( k+1 ) )
268 $
CALL sswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
269 k=k+2
270 ENDIF
271 END DO
272
273 ELSE
274
275
276
277
278 k=1
279 DO WHILE ( k .LE. n )
280 IF( ipiv( k ).GT.0 ) THEN
281
282
283 kp = ipiv( k )
284 IF( kp.NE.k )
285 $
CALL sswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
286 k=k+1
287 ELSE
288
289
290 kp = -ipiv( k+1 )
291 IF( kp.EQ.-ipiv( k ) )
292 $
CALL sswap( nrhs, b( k+1, 1 ), ldb, b( kp, 1 ), ldb )
293 k=k+2
294 ENDIF
295 END DO
296
297
298
299 CALL strsm(
'L',
'L',
'N',
'U',n,nrhs,one,a,lda,b,ldb)
300
301
302
303 i=1
304 DO WHILE ( i .LE. n )
305 IF( ipiv(i) .GT. 0 ) THEN
306 CALL sscal( nrhs, one / a( i, i ), b( i, 1 ), ldb )
307 ELSE
308 akm1k = work(i)
309 akm1 = a( i, i ) / akm1k
310 ak = a( i+1, i+1 ) / akm1k
311 denom = akm1*ak - one
312 DO 25 j = 1, nrhs
313 bkm1 = b( i, j ) / akm1k
314 bk = b( i+1, j ) / akm1k
315 b( i, j ) = ( ak*bkm1-bk ) / denom
316 b( i+1, j ) = ( akm1*bk-bkm1 ) / denom
317 25 CONTINUE
318 i = i + 1
319 ENDIF
320 i = i + 1
321 END DO
322
323
324
325 CALL strsm(
'L',
'L',
'T',
'U',n,nrhs,one,a,lda,b,ldb)
326
327
328
329 k=n
330 DO WHILE ( k .GE. 1 )
331 IF( ipiv( k ).GT.0 ) THEN
332
333
334 kp = ipiv( k )
335 IF( kp.NE.k )
336 $
CALL sswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
337 k=k-1
338 ELSE
339
340
341 kp = -ipiv( k )
342 IF( k.GT.1 .AND. kp.EQ.-ipiv( k-1 ) )
343 $
CALL sswap( nrhs, b( k, 1 ), ldb, b( kp, 1 ), ldb )
344 k=k-2
345 ENDIF
346 END DO
347
348 END IF
349
350
351
352 CALL ssyconv( uplo,
'R', n, a, lda, ipiv, work, iinfo )
353
354 RETURN
355
356
357
subroutine xerbla(srname, info)
logical function lsame(ca, cb)
LSAME
subroutine sscal(n, sa, sx, incx)
SSCAL
subroutine sswap(n, sx, incx, sy, incy)
SSWAP
subroutine ssyconv(uplo, way, n, a, lda, ipiv, e, info)
SSYCONV
subroutine strsm(side, uplo, transa, diag, m, n, alpha, a, lda, b, ldb)
STRSM