00001 SUBROUTINE ZLARTG( F, G, CS, SN, R )
00002
00003
00004
00005
00006
00007
00008
00009 DOUBLE PRECISION CS
00010 COMPLEX*16 F, G, R, SN
00011
00012
00013
00014
00015
00016
00017
00018
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 DOUBLE PRECISION TWO, ONE, ZERO
00058 PARAMETER ( TWO = 2.0D+0, ONE = 1.0D+0, ZERO = 0.0D+0 )
00059 COMPLEX*16 CZERO
00060 PARAMETER ( CZERO = ( 0.0D+0, 0.0D+0 ) )
00061
00062
00063
00064 INTEGER COUNT, I
00065 DOUBLE PRECISION D, DI, DR, EPS, F2, F2S, G2, G2S, SAFMIN,
00066 $ SAFMN2, SAFMX2, SCALE
00067 COMPLEX*16 FF, FS, GS
00068
00069
00070 DOUBLE PRECISION DLAMCH, DLAPY2
00071 EXTERNAL DLAMCH, DLAPY2
00072
00073
00074 INTRINSIC ABS, DBLE, DCMPLX, DCONJG, DIMAG, INT, LOG,
00075 $ MAX, SQRT
00076
00077
00078 DOUBLE PRECISION ABS1, ABSSQ
00079
00080
00081
00082
00083
00084
00085
00086
00087 ABS1( FF ) = MAX( ABS( DBLE( FF ) ), ABS( DIMAG( FF ) ) )
00088 ABSSQ( FF ) = DBLE( FF )**2 + DIMAG( FF )**2
00089
00090
00091
00092
00093 SAFMIN = DLAMCH( 'S' )
00094 EPS = DLAMCH( 'E' )
00095 SAFMN2 = DLAMCH( 'B' )**INT( LOG( SAFMIN / EPS ) /
00096 $ LOG( DLAMCH( 'B' ) ) / TWO )
00097 SAFMX2 = ONE / SAFMN2
00098
00099
00100 SCALE = MAX( ABS1( F ), ABS1( G ) )
00101 FS = F
00102 GS = G
00103 COUNT = 0
00104 IF( SCALE.GE.SAFMX2 ) THEN
00105 10 CONTINUE
00106 COUNT = COUNT + 1
00107 FS = FS*SAFMN2
00108 GS = GS*SAFMN2
00109 SCALE = SCALE*SAFMN2
00110 IF( SCALE.GE.SAFMX2 )
00111 $ GO TO 10
00112 ELSE IF( SCALE.LE.SAFMN2 ) THEN
00113 IF( G.EQ.CZERO ) THEN
00114 CS = ONE
00115 SN = CZERO
00116 R = F
00117 RETURN
00118 END IF
00119 20 CONTINUE
00120 COUNT = COUNT - 1
00121 FS = FS*SAFMX2
00122 GS = GS*SAFMX2
00123 SCALE = SCALE*SAFMX2
00124 IF( SCALE.LE.SAFMN2 )
00125 $ GO TO 20
00126 END IF
00127 F2 = ABSSQ( FS )
00128 G2 = ABSSQ( GS )
00129 IF( F2.LE.MAX( G2, ONE )*SAFMIN ) THEN
00130
00131
00132
00133 IF( F.EQ.CZERO ) THEN
00134 CS = ZERO
00135 R = DLAPY2( DBLE( G ), DIMAG( G ) )
00136
00137 D = DLAPY2( DBLE( GS ), DIMAG( GS ) )
00138 SN = DCMPLX( DBLE( GS ) / D, -DIMAG( GS ) / D )
00139 RETURN
00140 END IF
00141 F2S = DLAPY2( DBLE( FS ), DIMAG( FS ) )
00142
00143
00144 G2S = SQRT( G2 )
00145
00146
00147
00148
00149
00150
00151
00152 CS = F2S / G2S
00153
00154
00155 IF( ABS1( F ).GT.ONE ) THEN
00156 D = DLAPY2( DBLE( F ), DIMAG( F ) )
00157 FF = DCMPLX( DBLE( F ) / D, DIMAG( F ) / D )
00158 ELSE
00159 DR = SAFMX2*DBLE( F )
00160 DI = SAFMX2*DIMAG( F )
00161 D = DLAPY2( DR, DI )
00162 FF = DCMPLX( DR / D, DI / D )
00163 END IF
00164 SN = FF*DCMPLX( DBLE( GS ) / G2S, -DIMAG( GS ) / G2S )
00165 R = CS*F + SN*G
00166 ELSE
00167
00168
00169
00170
00171
00172 F2S = SQRT( ONE+G2 / F2 )
00173
00174 R = DCMPLX( F2S*DBLE( FS ), F2S*DIMAG( FS ) )
00175 CS = ONE / F2S
00176 D = F2 + G2
00177
00178 SN = DCMPLX( DBLE( R ) / D, DIMAG( R ) / D )
00179 SN = SN*DCONJG( GS )
00180 IF( COUNT.NE.0 ) THEN
00181 IF( COUNT.GT.0 ) THEN
00182 DO 30 I = 1, COUNT
00183 R = R*SAFMX2
00184 30 CONTINUE
00185 ELSE
00186 DO 40 I = 1, -COUNT
00187 R = R*SAFMN2
00188 40 CONTINUE
00189 END IF
00190 END IF
00191 END IF
00192 RETURN
00193
00194
00195
00196 END