00001 SUBROUTINE ZGEGS( JOBVSL, JOBVSR, N, A, LDA, B, LDB, ALPHA, BETA,
00002 $ VSL, LDVSL, VSR, LDVSR, WORK, LWORK, RWORK,
00003 $ INFO )
00004
00005
00006
00007
00008
00009
00010
00011 CHARACTER JOBVSL, JOBVSR
00012 INTEGER INFO, LDA, LDB, LDVSL, LDVSR, LWORK, N
00013
00014
00015 DOUBLE PRECISION RWORK( * )
00016 COMPLEX*16 A( LDA, * ), ALPHA( * ), B( LDB, * ),
00017 $ BETA( * ), VSL( LDVSL, * ), VSR( LDVSR, * ),
00018 $ WORK( * )
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 DOUBLE PRECISION ZERO, ONE
00146 PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
00147 COMPLEX*16 CZERO, CONE
00148 PARAMETER ( CZERO = ( 0.0D0, 0.0D0 ),
00149 $ CONE = ( 1.0D0, 0.0D0 ) )
00150
00151
00152 LOGICAL ILASCL, ILBSCL, ILVSL, ILVSR, LQUERY
00153 INTEGER ICOLS, IHI, IINFO, IJOBVL, IJOBVR, ILEFT, ILO,
00154 $ IRIGHT, IROWS, IRWORK, ITAU, IWORK, LOPT,
00155 $ LWKMIN, LWKOPT, NB, NB1, NB2, NB3
00156 DOUBLE PRECISION ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS,
00157 $ SAFMIN, SMLNUM
00158
00159
00160 EXTERNAL XERBLA, ZGEQRF, ZGGBAK, ZGGBAL, ZGGHRD, ZHGEQZ,
00161 $ ZLACPY, ZLASCL, ZLASET, ZUNGQR, ZUNMQR
00162
00163
00164 LOGICAL LSAME
00165 INTEGER ILAENV
00166 DOUBLE PRECISION DLAMCH, ZLANGE
00167 EXTERNAL LSAME, ILAENV, DLAMCH, ZLANGE
00168
00169
00170 INTRINSIC INT, MAX
00171
00172
00173
00174
00175
00176 IF( LSAME( JOBVSL, 'N' ) ) THEN
00177 IJOBVL = 1
00178 ILVSL = .FALSE.
00179 ELSE IF( LSAME( JOBVSL, 'V' ) ) THEN
00180 IJOBVL = 2
00181 ILVSL = .TRUE.
00182 ELSE
00183 IJOBVL = -1
00184 ILVSL = .FALSE.
00185 END IF
00186
00187 IF( LSAME( JOBVSR, 'N' ) ) THEN
00188 IJOBVR = 1
00189 ILVSR = .FALSE.
00190 ELSE IF( LSAME( JOBVSR, 'V' ) ) THEN
00191 IJOBVR = 2
00192 ILVSR = .TRUE.
00193 ELSE
00194 IJOBVR = -1
00195 ILVSR = .FALSE.
00196 END IF
00197
00198
00199
00200 LWKMIN = MAX( 2*N, 1 )
00201 LWKOPT = LWKMIN
00202 WORK( 1 ) = LWKOPT
00203 LQUERY = ( LWORK.EQ.-1 )
00204 INFO = 0
00205 IF( IJOBVL.LE.0 ) THEN
00206 INFO = -1
00207 ELSE IF( IJOBVR.LE.0 ) THEN
00208 INFO = -2
00209 ELSE IF( N.LT.0 ) THEN
00210 INFO = -3
00211 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
00212 INFO = -5
00213 ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
00214 INFO = -7
00215 ELSE IF( LDVSL.LT.1 .OR. ( ILVSL .AND. LDVSL.LT.N ) ) THEN
00216 INFO = -11
00217 ELSE IF( LDVSR.LT.1 .OR. ( ILVSR .AND. LDVSR.LT.N ) ) THEN
00218 INFO = -13
00219 ELSE IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY ) THEN
00220 INFO = -15
00221 END IF
00222
00223 IF( INFO.EQ.0 ) THEN
00224 NB1 = ILAENV( 1, 'ZGEQRF', ' ', N, N, -1, -1 )
00225 NB2 = ILAENV( 1, 'ZUNMQR', ' ', N, N, N, -1 )
00226 NB3 = ILAENV( 1, 'ZUNGQR', ' ', N, N, N, -1 )
00227 NB = MAX( NB1, NB2, NB3 )
00228 LOPT = N*( NB+1 )
00229 WORK( 1 ) = LOPT
00230 END IF
00231
00232 IF( INFO.NE.0 ) THEN
00233 CALL XERBLA( 'ZGEGS ', -INFO )
00234 RETURN
00235 ELSE IF( LQUERY ) THEN
00236 RETURN
00237 END IF
00238
00239
00240
00241 IF( N.EQ.0 )
00242 $ RETURN
00243
00244
00245
00246 EPS = DLAMCH( 'E' )*DLAMCH( 'B' )
00247 SAFMIN = DLAMCH( 'S' )
00248 SMLNUM = N*SAFMIN / EPS
00249 BIGNUM = ONE / SMLNUM
00250
00251
00252
00253 ANRM = ZLANGE( 'M', N, N, A, LDA, RWORK )
00254 ILASCL = .FALSE.
00255 IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
00256 ANRMTO = SMLNUM
00257 ILASCL = .TRUE.
00258 ELSE IF( ANRM.GT.BIGNUM ) THEN
00259 ANRMTO = BIGNUM
00260 ILASCL = .TRUE.
00261 END IF
00262
00263 IF( ILASCL ) THEN
00264 CALL ZLASCL( 'G', -1, -1, ANRM, ANRMTO, N, N, A, LDA, IINFO )
00265 IF( IINFO.NE.0 ) THEN
00266 INFO = N + 9
00267 RETURN
00268 END IF
00269 END IF
00270
00271
00272
00273 BNRM = ZLANGE( 'M', N, N, B, LDB, RWORK )
00274 ILBSCL = .FALSE.
00275 IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
00276 BNRMTO = SMLNUM
00277 ILBSCL = .TRUE.
00278 ELSE IF( BNRM.GT.BIGNUM ) THEN
00279 BNRMTO = BIGNUM
00280 ILBSCL = .TRUE.
00281 END IF
00282
00283 IF( ILBSCL ) THEN
00284 CALL ZLASCL( 'G', -1, -1, BNRM, BNRMTO, N, N, B, LDB, IINFO )
00285 IF( IINFO.NE.0 ) THEN
00286 INFO = N + 9
00287 RETURN
00288 END IF
00289 END IF
00290
00291
00292
00293 ILEFT = 1
00294 IRIGHT = N + 1
00295 IRWORK = IRIGHT + N
00296 IWORK = 1
00297 CALL ZGGBAL( 'P', N, A, LDA, B, LDB, ILO, IHI, RWORK( ILEFT ),
00298 $ RWORK( IRIGHT ), RWORK( IRWORK ), IINFO )
00299 IF( IINFO.NE.0 ) THEN
00300 INFO = N + 1
00301 GO TO 10
00302 END IF
00303
00304
00305
00306 IROWS = IHI + 1 - ILO
00307 ICOLS = N + 1 - ILO
00308 ITAU = IWORK
00309 IWORK = ITAU + IROWS
00310 CALL ZGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),
00311 $ WORK( IWORK ), LWORK+1-IWORK, IINFO )
00312 IF( IINFO.GE.0 )
00313 $ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
00314 IF( IINFO.NE.0 ) THEN
00315 INFO = N + 2
00316 GO TO 10
00317 END IF
00318
00319 CALL ZUNMQR( 'L', 'C', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,
00320 $ WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWORK ),
00321 $ LWORK+1-IWORK, IINFO )
00322 IF( IINFO.GE.0 )
00323 $ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
00324 IF( IINFO.NE.0 ) THEN
00325 INFO = N + 3
00326 GO TO 10
00327 END IF
00328
00329 IF( ILVSL ) THEN
00330 CALL ZLASET( 'Full', N, N, CZERO, CONE, VSL, LDVSL )
00331 CALL ZLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,
00332 $ VSL( ILO+1, ILO ), LDVSL )
00333 CALL ZUNGQR( IROWS, IROWS, IROWS, VSL( ILO, ILO ), LDVSL,
00334 $ WORK( ITAU ), WORK( IWORK ), LWORK+1-IWORK,
00335 $ IINFO )
00336 IF( IINFO.GE.0 )
00337 $ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
00338 IF( IINFO.NE.0 ) THEN
00339 INFO = N + 4
00340 GO TO 10
00341 END IF
00342 END IF
00343
00344 IF( ILVSR )
00345 $ CALL ZLASET( 'Full', N, N, CZERO, CONE, VSR, LDVSR )
00346
00347
00348
00349 CALL ZGGHRD( JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB, VSL,
00350 $ LDVSL, VSR, LDVSR, IINFO )
00351 IF( IINFO.NE.0 ) THEN
00352 INFO = N + 5
00353 GO TO 10
00354 END IF
00355
00356
00357
00358 IWORK = ITAU
00359 CALL ZHGEQZ( 'S', JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB,
00360 $ ALPHA, BETA, VSL, LDVSL, VSR, LDVSR, WORK( IWORK ),
00361 $ LWORK+1-IWORK, RWORK( IRWORK ), IINFO )
00362 IF( IINFO.GE.0 )
00363 $ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
00364 IF( IINFO.NE.0 ) THEN
00365 IF( IINFO.GT.0 .AND. IINFO.LE.N ) THEN
00366 INFO = IINFO
00367 ELSE IF( IINFO.GT.N .AND. IINFO.LE.2*N ) THEN
00368 INFO = IINFO - N
00369 ELSE
00370 INFO = N + 6
00371 END IF
00372 GO TO 10
00373 END IF
00374
00375
00376
00377 IF( ILVSL ) THEN
00378 CALL ZGGBAK( 'P', 'L', N, ILO, IHI, RWORK( ILEFT ),
00379 $ RWORK( IRIGHT ), N, VSL, LDVSL, IINFO )
00380 IF( IINFO.NE.0 ) THEN
00381 INFO = N + 7
00382 GO TO 10
00383 END IF
00384 END IF
00385 IF( ILVSR ) THEN
00386 CALL ZGGBAK( 'P', 'R', N, ILO, IHI, RWORK( ILEFT ),
00387 $ RWORK( IRIGHT ), N, VSR, LDVSR, IINFO )
00388 IF( IINFO.NE.0 ) THEN
00389 INFO = N + 8
00390 GO TO 10
00391 END IF
00392 END IF
00393
00394
00395
00396 IF( ILASCL ) THEN
00397 CALL ZLASCL( 'U', -1, -1, ANRMTO, ANRM, N, N, A, LDA, IINFO )
00398 IF( IINFO.NE.0 ) THEN
00399 INFO = N + 9
00400 RETURN
00401 END IF
00402 CALL ZLASCL( 'G', -1, -1, ANRMTO, ANRM, N, 1, ALPHA, N, IINFO )
00403 IF( IINFO.NE.0 ) THEN
00404 INFO = N + 9
00405 RETURN
00406 END IF
00407 END IF
00408
00409 IF( ILBSCL ) THEN
00410 CALL ZLASCL( 'U', -1, -1, BNRMTO, BNRM, N, N, B, LDB, IINFO )
00411 IF( IINFO.NE.0 ) THEN
00412 INFO = N + 9
00413 RETURN
00414 END IF
00415 CALL ZLASCL( 'G', -1, -1, BNRMTO, BNRM, N, 1, BETA, N, IINFO )
00416 IF( IINFO.NE.0 ) THEN
00417 INFO = N + 9
00418 RETURN
00419 END IF
00420 END IF
00421
00422 10 CONTINUE
00423 WORK( 1 ) = LWKOPT
00424
00425 RETURN
00426
00427
00428
00429 END