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 smlnum = smlnum*real( m*n ) / eps
241 bignum = one / smlnum
242 smin = max( smlnum, eps*
clange(
'M', m, m, a, lda, dum ),
243 $ eps*
clange(
'M', n, n, b, ldb, dum ) )
244 sgn = isgn
245
246 IF( notrna .AND. notrnb ) THEN
247
248
249
250
251
252
253
254
255
256
257
258
259
260 DO 30 l = 1, n
261 DO 20 k = m, 1, -1
262
263 suml =
cdotu( m-k, a( k, min( k+1, m ) ), lda,
264 $ c( min( k+1, m ), l ), 1 )
265 sumr =
cdotu( l-1, c( k, 1 ), ldc, b( 1, l ), 1 )
266 vec = c( k, l ) - ( suml+sgn*sumr )
267
268 scaloc = one
269 a11 = a( k, k ) + sgn*b( l, l )
270 da11 = abs( real( a11 ) ) + abs( aimag( a11 ) )
271 IF( da11.LE.smin ) THEN
272 a11 = smin
273 da11 = smin
274 info = 1
275 END IF
276 db = abs( real( vec ) ) + abs( aimag( vec ) )
277 IF( da11.LT.one .AND. db.GT.one ) THEN
278 IF( db.GT.bignum*da11 )
279 $ scaloc = one / db
280 END IF
281 x11 =
cladiv( vec*cmplx( scaloc ), a11 )
282
283 IF( scaloc.NE.one ) THEN
284 DO 10 j = 1, n
285 CALL csscal( m, scaloc, c( 1, j ), 1 )
286 10 CONTINUE
287 scale = scale*scaloc
288 END IF
289 c( k, l ) = x11
290
291 20 CONTINUE
292 30 CONTINUE
293
294 ELSE IF( .NOT.notrna .AND. notrnb ) THEN
295
296
297
298
299
300
301
302
303
304
305
306
307
308 DO 60 l = 1, n
309 DO 50 k = 1, m
310
311 suml =
cdotc( k-1, a( 1, k ), 1, c( 1, l ), 1 )
312 sumr =
cdotu( l-1, c( k, 1 ), ldc, b( 1, l ), 1 )
313 vec = c( k, l ) - ( suml+sgn*sumr )
314
315 scaloc = one
316 a11 = conjg( a( k, k ) ) + sgn*b( l, l )
317 da11 = abs( real( a11 ) ) + abs( aimag( a11 ) )
318 IF( da11.LE.smin ) THEN
319 a11 = smin
320 da11 = smin
321 info = 1
322 END IF
323 db = abs( real( vec ) ) + abs( aimag( vec ) )
324 IF( da11.LT.one .AND. db.GT.one ) THEN
325 IF( db.GT.bignum*da11 )
326 $ scaloc = one / db
327 END IF
328
329 x11 =
cladiv( vec*cmplx( scaloc ), a11 )
330
331 IF( scaloc.NE.one ) THEN
332 DO 40 j = 1, n
333 CALL csscal( m, scaloc, c( 1, j ), 1 )
334 40 CONTINUE
335 scale = scale*scaloc
336 END IF
337 c( k, l ) = x11
338
339 50 CONTINUE
340 60 CONTINUE
341
342 ELSE IF( .NOT.notrna .AND. .NOT.notrnb ) THEN
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359 DO 90 l = n, 1, -1
360 DO 80 k = 1, m
361
362 suml =
cdotc( k-1, a( 1, k ), 1, c( 1, l ), 1 )
363 sumr =
cdotc( n-l, c( k, min( l+1, n ) ), ldc,
364 $ b( l, min( l+1, n ) ), ldb )
365 vec = c( k, l ) - ( suml+sgn*conjg( sumr ) )
366
367 scaloc = one
368 a11 = conjg( a( k, k )+sgn*b( l, l ) )
369 da11 = abs( real( a11 ) ) + abs( aimag( a11 ) )
370 IF( da11.LE.smin ) THEN
371 a11 = smin
372 da11 = smin
373 info = 1
374 END IF
375 db = abs( real( vec ) ) + abs( aimag( vec ) )
376 IF( da11.LT.one .AND. db.GT.one ) THEN
377 IF( db.GT.bignum*da11 )
378 $ scaloc = one / db
379 END IF
380
381 x11 =
cladiv( vec*cmplx( scaloc ), a11 )
382
383 IF( scaloc.NE.one ) THEN
384 DO 70 j = 1, n
385 CALL csscal( m, scaloc, c( 1, j ), 1 )
386 70 CONTINUE
387 scale = scale*scaloc
388 END IF
389 c( k, l ) = x11
390
391 80 CONTINUE
392 90 CONTINUE
393
394 ELSE IF( notrna .AND. .NOT.notrnb ) THEN
395
396
397
398
399
400
401
402
403
404
405
406
407
408 DO 120 l = n, 1, -1
409 DO 110 k = m, 1, -1
410
411 suml =
cdotu( m-k, a( k, min( k+1, m ) ), lda,
412 $ c( min( k+1, m ), l ), 1 )
413 sumr =
cdotc( n-l, c( k, min( l+1, n ) ), ldc,
414 $ b( l, min( l+1, n ) ), ldb )
415 vec = c( k, l ) - ( suml+sgn*conjg( sumr ) )
416
417 scaloc = one
418 a11 = a( k, k ) + sgn*conjg( b( l, l ) )
419 da11 = abs( real( a11 ) ) + abs( aimag( a11 ) )
420 IF( da11.LE.smin ) THEN
421 a11 = smin
422 da11 = smin
423 info = 1
424 END IF
425 db = abs( real( vec ) ) + abs( aimag( vec ) )
426 IF( da11.LT.one .AND. db.GT.one ) THEN
427 IF( db.GT.bignum*da11 )
428 $ scaloc = one / db
429 END IF
430
431 x11 =
cladiv( vec*cmplx( scaloc ), a11 )
432
433 IF( scaloc.NE.one ) THEN
434 DO 100 j = 1, n
435 CALL csscal( m, scaloc, c( 1, j ), 1 )
436 100 CONTINUE
437 scale = scale*scaloc
438 END IF
439 c( k, l ) = x11
440
441 110 CONTINUE
442 120 CONTINUE
443
444 END IF
445
446 RETURN
447
448
449
subroutine xerbla(srname, info)
complex function cdotu(n, cx, incx, cy, incy)
CDOTU
complex function cdotc(n, cx, incx, cy, incy)
CDOTC
complex function cladiv(x, y)
CLADIV performs complex division in real arithmetic, avoiding unnecessary overflow.
real function slamch(cmach)
SLAMCH
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 ...
logical function lsame(ca, cb)
LSAME
subroutine csscal(n, sa, cx, incx)
CSSCAL