157
158
159
160
161
162
163 CHARACTER TRANA, TRANB
164 INTEGER INFO, ISGN, LDA, LDB, LDC, M, N
165 REAL SCALE
166
167
168 COMPLEX A( LDA, * ), B( LDB, * ), C( LDC, * )
169
170
171
172
173
174 REAL ONE
175 parameter( one = 1.0e+0 )
176
177
178 LOGICAL NOTRNA, NOTRNB
179 INTEGER J, K, L
180 REAL BIGNUM, DA11, DB, EPS, SCALOC, SGN, SMIN,
181 $ SMLNUM
182 COMPLEX A11, SUML, SUMR, VEC, X11
183
184
185 REAL DUM( 1 )
186
187
188 LOGICAL LSAME
189 REAL CLANGE, SLAMCH
190 COMPLEX CDOTC, CDOTU, CLADIV
192
193
195
196
197 INTRINSIC abs, aimag, cmplx, conjg, max, min, real
198
199
200
201
202
203 notrna =
lsame( trana,
'N' )
204 notrnb =
lsame( tranb,
'N' )
205
206 info = 0
207 IF( .NOT.notrna .AND. .NOT.
lsame( trana,
'C' ) )
THEN
208 info = -1
209 ELSE IF( .NOT.notrnb .AND. .NOT.
lsame( tranb,
'C' ) )
THEN
210 info = -2
211 ELSE IF( isgn.NE.1 .AND. isgn.NE.-1 ) THEN
212 info = -3
213 ELSE IF( m.LT.0 ) THEN
214 info = -4
215 ELSE IF( n.LT.0 ) THEN
216 info = -5
217 ELSE IF( lda.LT.max( 1, m ) ) THEN
218 info = -7
219 ELSE IF( ldb.LT.max( 1, n ) ) THEN
220 info = -9
221 ELSE IF( ldc.LT.max( 1, m ) ) THEN
222 info = -11
223 END IF
224 IF( info.NE.0 ) THEN
225 CALL xerbla(
'CTRSYL', -info )
226 RETURN
227 END IF
228
229
230
231 scale = one
232 IF( m.EQ.0 .OR. n.EQ.0 )
233 $ RETURN
234
235
236
239 bignum = one / smlnum
240 CALL slabad( smlnum, bignum )
241 smlnum = smlnum*real( m*n ) / eps
242 bignum = one / smlnum
243 smin = max( smlnum, eps*
clange(
'M', m, m, a, lda, dum ),
244 $ eps*
clange(
'M', n, n, b, ldb, dum ) )
245 sgn = isgn
246
247 IF( notrna .AND. notrnb ) THEN
248
249
250
251
252
253
254
255
256
257
258
259
260
261 DO 30 l = 1, n
262 DO 20 k = m, 1, -1
263
264 suml =
cdotu( m-k, a( k, min( k+1, m ) ), lda,
265 $ c( min( k+1, m ), l ), 1 )
266 sumr =
cdotu( l-1, c( k, 1 ), ldc, b( 1, l ), 1 )
267 vec = c( k, l ) - ( suml+sgn*sumr )
268
269 scaloc = one
270 a11 = a( k, k ) + sgn*b( l, l )
271 da11 = abs( real( a11 ) ) + abs( aimag( a11 ) )
272 IF( da11.LE.smin ) THEN
273 a11 = smin
274 da11 = smin
275 info = 1
276 END IF
277 db = abs( real( vec ) ) + abs( aimag( vec ) )
278 IF( da11.LT.one .AND. db.GT.one ) THEN
279 IF( db.GT.bignum*da11 )
280 $ scaloc = one / db
281 END IF
282 x11 =
cladiv( vec*cmplx( scaloc ), a11 )
283
284 IF( scaloc.NE.one ) THEN
285 DO 10 j = 1, n
286 CALL csscal( m, scaloc, c( 1, j ), 1 )
287 10 CONTINUE
288 scale = scale*scaloc
289 END IF
290 c( k, l ) = x11
291
292 20 CONTINUE
293 30 CONTINUE
294
295 ELSE IF( .NOT.notrna .AND. notrnb ) THEN
296
297
298
299
300
301
302
303
304
305
306
307
308
309 DO 60 l = 1, n
310 DO 50 k = 1, m
311
312 suml =
cdotc( k-1, a( 1, k ), 1, c( 1, l ), 1 )
313 sumr =
cdotu( l-1, c( k, 1 ), ldc, b( 1, l ), 1 )
314 vec = c( k, l ) - ( suml+sgn*sumr )
315
316 scaloc = one
317 a11 = conjg( a( k, k ) ) + sgn*b( l, l )
318 da11 = abs( real( a11 ) ) + abs( aimag( a11 ) )
319 IF( da11.LE.smin ) THEN
320 a11 = smin
321 da11 = smin
322 info = 1
323 END IF
324 db = abs( real( vec ) ) + abs( aimag( vec ) )
325 IF( da11.LT.one .AND. db.GT.one ) THEN
326 IF( db.GT.bignum*da11 )
327 $ scaloc = one / db
328 END IF
329
330 x11 =
cladiv( vec*cmplx( scaloc ), a11 )
331
332 IF( scaloc.NE.one ) THEN
333 DO 40 j = 1, n
334 CALL csscal( m, scaloc, c( 1, j ), 1 )
335 40 CONTINUE
336 scale = scale*scaloc
337 END IF
338 c( k, l ) = x11
339
340 50 CONTINUE
341 60 CONTINUE
342
343 ELSE IF( .NOT.notrna .AND. .NOT.notrnb ) THEN
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360 DO 90 l = n, 1, -1
361 DO 80 k = 1, m
362
363 suml =
cdotc( k-1, a( 1, k ), 1, c( 1, l ), 1 )
364 sumr =
cdotc( n-l, c( k, min( l+1, n ) ), ldc,
365 $ b( l, min( l+1, n ) ), ldb )
366 vec = c( k, l ) - ( suml+sgn*conjg( sumr ) )
367
368 scaloc = one
369 a11 = conjg( a( k, k )+sgn*b( l, l ) )
370 da11 = abs( real( a11 ) ) + abs( aimag( a11 ) )
371 IF( da11.LE.smin ) THEN
372 a11 = smin
373 da11 = smin
374 info = 1
375 END IF
376 db = abs( real( vec ) ) + abs( aimag( vec ) )
377 IF( da11.LT.one .AND. db.GT.one ) THEN
378 IF( db.GT.bignum*da11 )
379 $ scaloc = one / db
380 END IF
381
382 x11 =
cladiv( vec*cmplx( scaloc ), a11 )
383
384 IF( scaloc.NE.one ) THEN
385 DO 70 j = 1, n
386 CALL csscal( m, scaloc, c( 1, j ), 1 )
387 70 CONTINUE
388 scale = scale*scaloc
389 END IF
390 c( k, l ) = x11
391
392 80 CONTINUE
393 90 CONTINUE
394
395 ELSE IF( notrna .AND. .NOT.notrnb ) THEN
396
397
398
399
400
401
402
403
404
405
406
407
408
409 DO 120 l = n, 1, -1
410 DO 110 k = m, 1, -1
411
412 suml =
cdotu( m-k, a( k, min( k+1, m ) ), lda,
413 $ c( min( k+1, m ), l ), 1 )
414 sumr =
cdotc( n-l, c( k, min( l+1, n ) ), ldc,
415 $ b( l, min( l+1, n ) ), ldb )
416 vec = c( k, l ) - ( suml+sgn*conjg( sumr ) )
417
418 scaloc = one
419 a11 = a( k, k ) + sgn*conjg( b( l, l ) )
420 da11 = abs( real( a11 ) ) + abs( aimag( a11 ) )
421 IF( da11.LE.smin ) THEN
422 a11 = smin
423 da11 = smin
424 info = 1
425 END IF
426 db = abs( real( vec ) ) + abs( aimag( vec ) )
427 IF( da11.LT.one .AND. db.GT.one ) THEN
428 IF( db.GT.bignum*da11 )
429 $ scaloc = one / db
430 END IF
431
432 x11 =
cladiv( vec*cmplx( scaloc ), a11 )
433
434 IF( scaloc.NE.one ) THEN
435 DO 100 j = 1, n
436 CALL csscal( m, scaloc, c( 1, j ), 1 )
437 100 CONTINUE
438 scale = scale*scaloc
439 END IF
440 c( k, l ) = x11
441
442 110 CONTINUE
443 120 CONTINUE
444
445 END IF
446
447 RETURN
448
449
450
subroutine slabad(SMALL, LARGE)
SLABAD
subroutine xerbla(SRNAME, INFO)
XERBLA
logical function lsame(CA, CB)
LSAME
complex function cdotc(N, CX, INCX, CY, INCY)
CDOTC
subroutine csscal(N, SA, CX, INCX)
CSSCAL
complex function cdotu(N, CX, INCX, CY, INCY)
CDOTU
real function clange(NORM, M, N, A, LDA, WORK)
CLANGE returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value ...
complex function cladiv(X, Y)
CLADIV performs complex division in real arithmetic, avoiding unnecessary overflow.
real function slamch(CMACH)
SLAMCH