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