SUBROUTINE CTGSYL( TRANS, IJOB, M, N, A, LDA, B, LDB, C, LDC, D,
$ LDD, E, LDE, F, LDF, SCALE, DIF, WORK, LWORK,
$ IWORK, INFO )
CHARACTER TRANS
INTEGER IJOB, INFO, LDA, LDB, LDC, LDD, LDE, LDF,
$ LWORK, M, N
REAL DIF, SCALE
INTEGER IWORK( * )
COMPLEX A( LDA, * ), B( LDB, * ), C( LDC, * ),
$ D( LDD, * ), E( LDE, * ), F( LDF, * ),
$ WORK( * )
REAL ZERO, ONE
PARAMETER ( ZERO = 0.0E+0, ONE = 1.0E+0 )
COMPLEX CZERO
PARAMETER ( CZERO = (0.0E+0, 0.0E+0) )
LOGICAL LQUERY, NOTRAN
INTEGER I, IE, IFUNC, IROUND, IS, ISOLVE, J, JE, JS, K,
$ LINFO, LWMIN, MB, NB, P, PQ, Q
REAL DSCALE, DSUM, SCALE2, SCALOC
LOGICAL LSAME
INTEGER ILAENV
EXTERNAL LSAME, ILAENV
EXTERNAL CGEMM, CLACPY, CLASET, CSCAL, CTGSY2, XERBLA
INTRINSIC CMPLX, MAX, REAL, SQRT
INFO = 0
NOTRAN = LSAME( TRANS, 'N' )
LQUERY = ( LWORK.EQ.-1 )
IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'C' ) ) THEN
INFO = -1
ELSE IF( NOTRAN ) THEN
IF( ( IJOB.LT.0 ) .OR. ( IJOB.GT.4 ) ) THEN
INFO = -2
END IF
END IF
IF( INFO.EQ.0 ) THEN
IF( M.LE.0 ) THEN
INFO = -3
ELSE IF( N.LE.0 ) THEN
INFO = -4
ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
INFO = -6
ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
INFO = -8
ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
INFO = -10
ELSE IF( LDD.LT.MAX( 1, M ) ) THEN
INFO = -12
ELSE IF( LDE.LT.MAX( 1, N ) ) THEN
INFO = -14
ELSE IF( LDF.LT.MAX( 1, M ) ) THEN
INFO = -16
END IF
END IF
IF( INFO.EQ.0 ) THEN
IF( NOTRAN ) THEN
IF( IJOB.EQ.1 .OR. IJOB.EQ.2 ) THEN
LWMIN = MAX( 1, 2*M*N )
ELSE
LWMIN = 1
END IF
ELSE
LWMIN = 1
END IF
WORK( 1 ) = LWMIN
IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THEN
INFO = -20
END IF
END IF
IF( INFO.NE.0 ) THEN
CALL XERBLA( 'CTGSYL', -INFO )
RETURN
ELSE IF( LQUERY ) THEN
RETURN
END IF
IF( M.EQ.0 .OR. N.EQ.0 ) THEN
SCALE = 1
IF( NOTRAN ) THEN
IF( IJOB.NE.0 ) THEN
DIF = 0
END IF
END IF
RETURN
END IF
MB = ILAENV( 2, 'CTGSYL', TRANS, M, N, -1, -1 )
NB = ILAENV( 5, 'CTGSYL', TRANS, M, N, -1, -1 )
ISOLVE = 1
IFUNC = 0
IF( NOTRAN ) THEN
IF( IJOB.GE.3 ) THEN
IFUNC = IJOB - 2
CALL CLASET( 'F', M, N, CZERO, CZERO, C, LDC )
CALL CLASET( 'F', M, N, CZERO, CZERO, F, LDF )
ELSE IF( IJOB.GE.1 .AND. NOTRAN ) THEN
ISOLVE = 2
END IF
END IF
IF( ( MB.LE.1 .AND. NB.LE.1 ) .OR. ( MB.GE.M .AND. NB.GE.N ) )
$ THEN
DO 30 IROUND = 1, ISOLVE
SCALE = ONE
DSCALE = ZERO
DSUM = ONE
PQ = M*N
CALL CTGSY2( TRANS, IFUNC, M, N, A, LDA, B, LDB, C, LDC, D,
$ LDD, E, LDE, F, LDF, SCALE, DSUM, DSCALE,
$ INFO )
IF( DSCALE.NE.ZERO ) THEN
IF( IJOB.EQ.1 .OR. IJOB.EQ.3 ) THEN
DIF = SQRT( REAL( 2*M*N ) ) / ( DSCALE*SQRT( DSUM ) )
ELSE
DIF = SQRT( REAL( PQ ) ) / ( DSCALE*SQRT( DSUM ) )
END IF
END IF
IF( ISOLVE.EQ.2 .AND. IROUND.EQ.1 ) THEN
IF( NOTRAN ) THEN
IFUNC = IJOB
END IF
SCALE2 = SCALE
CALL CLACPY( 'F', M, N, C, LDC, WORK, M )
CALL CLACPY( 'F', M, N, F, LDF, WORK( M*N+1 ), M )
CALL CLASET( 'F', M, N, CZERO, CZERO, C, LDC )
CALL CLASET( 'F', M, N, CZERO, CZERO, F, LDF )
ELSE IF( ISOLVE.EQ.2 .AND. IROUND.EQ.2 ) THEN
CALL CLACPY( 'F', M, N, WORK, M, C, LDC )
CALL CLACPY( 'F', M, N, WORK( M*N+1 ), M, F, LDF )
SCALE = SCALE2
END IF
30 CONTINUE
RETURN
END IF
P = 0
I = 1
40 CONTINUE
IF( I.GT.M )
$ GO TO 50
P = P + 1
IWORK( P ) = I
I = I + MB
IF( I.GE.M )
$ GO TO 50
GO TO 40
50 CONTINUE
IWORK( P+1 ) = M + 1
IF( IWORK( P ).EQ.IWORK( P+1 ) )
$ P = P - 1
Q = P + 1
J = 1
60 CONTINUE
IF( J.GT.N )
$ GO TO 70
Q = Q + 1
IWORK( Q ) = J
J = J + NB
IF( J.GE.N )
$ GO TO 70
GO TO 60
70 CONTINUE
IWORK( Q+1 ) = N + 1
IF( IWORK( Q ).EQ.IWORK( Q+1 ) )
$ Q = Q - 1
IF( NOTRAN ) THEN
DO 150 IROUND = 1, ISOLVE
PQ = 0
SCALE = ONE
DSCALE = ZERO
DSUM = ONE
DO 130 J = P + 2, Q
JS = IWORK( J )
JE = IWORK( J+1 ) - 1
NB = JE - JS + 1
DO 120 I = P, 1, -1
IS = IWORK( I )
IE = IWORK( I+1 ) - 1
MB = IE - IS + 1
CALL CTGSY2( TRANS, IFUNC, MB, NB, A( IS, IS ), LDA,
$ B( JS, JS ), LDB, C( IS, JS ), LDC,
$ D( IS, IS ), LDD, E( JS, JS ), LDE,
$ F( IS, JS ), LDF, SCALOC, DSUM, DSCALE,
$ LINFO )
IF( LINFO.GT.0 )
$ INFO = LINFO
PQ = PQ + MB*NB
IF( SCALOC.NE.ONE ) THEN
DO 80 K = 1, JS - 1
CALL CSCAL( M, CMPLX( SCALOC, ZERO ), C( 1, K ),
$ 1 )
CALL CSCAL( M, CMPLX( SCALOC, ZERO ), F( 1, K ),
$ 1 )
80 CONTINUE
DO 90 K = JS, JE
CALL CSCAL( IS-1, CMPLX( SCALOC, ZERO ),
$ C( 1, K ), 1 )
CALL CSCAL( IS-1, CMPLX( SCALOC, ZERO ),
$ F( 1, K ), 1 )
90 CONTINUE
DO 100 K = JS, JE
CALL CSCAL( M-IE, CMPLX( SCALOC, ZERO ),
$ C( IE+1, K ), 1 )
CALL CSCAL( M-IE, CMPLX( SCALOC, ZERO ),
$ F( IE+1, K ), 1 )
100 CONTINUE
DO 110 K = JE + 1, N
CALL CSCAL( M, CMPLX( SCALOC, ZERO ), C( 1, K ),
$ 1 )
CALL CSCAL( M, CMPLX( SCALOC, ZERO ), F( 1, K ),
$ 1 )
110 CONTINUE
SCALE = SCALE*SCALOC
END IF
IF( I.GT.1 ) THEN
CALL CGEMM( 'N', 'N', IS-1, NB, MB,
$ CMPLX( -ONE, ZERO ), A( 1, IS ), LDA,
$ C( IS, JS ), LDC, CMPLX( ONE, ZERO ),
$ C( 1, JS ), LDC )
CALL CGEMM( 'N', 'N', IS-1, NB, MB,
$ CMPLX( -ONE, ZERO ), D( 1, IS ), LDD,
$ C( IS, JS ), LDC, CMPLX( ONE, ZERO ),
$ F( 1, JS ), LDF )
END IF
IF( J.LT.Q ) THEN
CALL CGEMM( 'N', 'N', MB, N-JE, NB,
$ CMPLX( ONE, ZERO ), F( IS, JS ), LDF,
$ B( JS, JE+1 ), LDB, CMPLX( ONE, ZERO ),
$ C( IS, JE+1 ), LDC )
CALL CGEMM( 'N', 'N', MB, N-JE, NB,
$ CMPLX( ONE, ZERO ), F( IS, JS ), LDF,
$ E( JS, JE+1 ), LDE, CMPLX( ONE, ZERO ),
$ F( IS, JE+1 ), LDF )
END IF
120 CONTINUE
130 CONTINUE
IF( DSCALE.NE.ZERO ) THEN
IF( IJOB.EQ.1 .OR. IJOB.EQ.3 ) THEN
DIF = SQRT( REAL( 2*M*N ) ) / ( DSCALE*SQRT( DSUM ) )
ELSE
DIF = SQRT( REAL( PQ ) ) / ( DSCALE*SQRT( DSUM ) )
END IF
END IF
IF( ISOLVE.EQ.2 .AND. IROUND.EQ.1 ) THEN
IF( NOTRAN ) THEN
IFUNC = IJOB
END IF
SCALE2 = SCALE
CALL CLACPY( 'F', M, N, C, LDC, WORK, M )
CALL CLACPY( 'F', M, N, F, LDF, WORK( M*N+1 ), M )
CALL CLASET( 'F', M, N, CZERO, CZERO, C, LDC )
CALL CLASET( 'F', M, N, CZERO, CZERO, F, LDF )
ELSE IF( ISOLVE.EQ.2 .AND. IROUND.EQ.2 ) THEN
CALL CLACPY( 'F', M, N, WORK, M, C, LDC )
CALL CLACPY( 'F', M, N, WORK( M*N+1 ), M, F, LDF )
SCALE = SCALE2
END IF
150 CONTINUE
ELSE
SCALE = ONE
DO 210 I = 1, P
IS = IWORK( I )
IE = IWORK( I+1 ) - 1
MB = IE - IS + 1
DO 200 J = Q, P + 2, -1
JS = IWORK( J )
JE = IWORK( J+1 ) - 1
NB = JE - JS + 1
CALL CTGSY2( TRANS, IFUNC, MB, NB, A( IS, IS ), LDA,
$ B( JS, JS ), LDB, C( IS, JS ), LDC,
$ D( IS, IS ), LDD, E( JS, JS ), LDE,
$ F( IS, JS ), LDF, SCALOC, DSUM, DSCALE,
$ LINFO )
IF( LINFO.GT.0 )
$ INFO = LINFO
IF( SCALOC.NE.ONE ) THEN
DO 160 K = 1, JS - 1
CALL CSCAL( M, CMPLX( SCALOC, ZERO ), C( 1, K ),
$ 1 )
CALL CSCAL( M, CMPLX( SCALOC, ZERO ), F( 1, K ),
$ 1 )
160 CONTINUE
DO 170 K = JS, JE
CALL CSCAL( IS-1, CMPLX( SCALOC, ZERO ), C( 1, K ),
$ 1 )
CALL CSCAL( IS-1, CMPLX( SCALOC, ZERO ), F( 1, K ),
$ 1 )
170 CONTINUE
DO 180 K = JS, JE
CALL CSCAL( M-IE, CMPLX( SCALOC, ZERO ),
$ C( IE+1, K ), 1 )
CALL CSCAL( M-IE, CMPLX( SCALOC, ZERO ),
$ F( IE+1, K ), 1 )
180 CONTINUE
DO 190 K = JE + 1, N
CALL CSCAL( M, CMPLX( SCALOC, ZERO ), C( 1, K ),
$ 1 )
CALL CSCAL( M, CMPLX( SCALOC, ZERO ), F( 1, K ),
$ 1 )
190 CONTINUE
SCALE = SCALE*SCALOC
END IF
IF( J.GT.P+2 ) THEN
CALL CGEMM( 'N', 'C', MB, JS-1, NB,
$ CMPLX( ONE, ZERO ), C( IS, JS ), LDC,
$ B( 1, JS ), LDB, CMPLX( ONE, ZERO ),
$ F( IS, 1 ), LDF )
CALL CGEMM( 'N', 'C', MB, JS-1, NB,
$ CMPLX( ONE, ZERO ), F( IS, JS ), LDF,
$ E( 1, JS ), LDE, CMPLX( ONE, ZERO ),
$ F( IS, 1 ), LDF )
END IF
IF( I.LT.P ) THEN
CALL CGEMM( 'C', 'N', M-IE, NB, MB,
$ CMPLX( -ONE, ZERO ), A( IS, IE+1 ), LDA,
$ C( IS, JS ), LDC, CMPLX( ONE, ZERO ),
$ C( IE+1, JS ), LDC )
CALL CGEMM( 'C', 'N', M-IE, NB, MB,
$ CMPLX( -ONE, ZERO ), D( IS, IE+1 ), LDD,
$ F( IS, JS ), LDF, CMPLX( ONE, ZERO ),
$ C( IE+1, JS ), LDC )
END IF
200 CONTINUE
210 CONTINUE
END IF
WORK( 1 ) = LWMIN
RETURN
END