1 *> \brief \b CLARTG generates a plane rotation with real cosine and complex sine.
3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download CLARTG + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/clartg.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/clartg.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/clartg.f">
21 * SUBROUTINE CLARTG( F, G, CS, SN, R )
23 * .. Scalar Arguments ..
34 *> CLARTG generates a plane rotation so that
36 *> [ CS SN ] [ F ] [ R ]
37 *> [ __ ] . [ ] = [ ] where CS**2 + |SN|**2 = 1.
38 *> [ -SN CS ] [ G ] [ 0 ]
40 *> This is a faster version of the BLAS1 routine CROTG, except for
41 *> the following differences:
42 *> F and G are unchanged on return.
43 *> If G=0, then CS=1 and SN=0.
44 *> If F=0, then CS=0 and SN is chosen so that R is real.
53 *> The first component of vector to be rotated.
59 *> The second component of vector to be rotated.
65 *> The cosine of the rotation.
71 *> The sine of the rotation.
77 *> The nonzero component of the rotated vector.
83 *> \author Univ. of Tennessee
84 *> \author Univ. of California Berkeley
85 *> \author Univ. of Colorado Denver
88 *> \date November 2013
90 *> \ingroup complexOTHERauxiliary
92 *> \par Further Details:
93 * =====================
97 *> 3-5-96 - Modified with a new algorithm by W. Kahan and J. Demmel
99 *> This version has a few statements commented out for thread safety
100 *> (machine parameters are computed on each entry). 10 feb 03, SJH.
103 * =====================================================================
104 SUBROUTINE CLARTG( F, G, CS, SN, R )
106 * -- LAPACK auxiliary routine (version 3.5.0) --
107 * -- LAPACK is a software package provided by Univ. of Tennessee, --
108 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
111 * .. Scalar Arguments ..
116 * =====================================================================
120 PARAMETER ( TWO = 2.0E+0, ONE = 1.0E+0, ZERO = 0.0E+0 )
122 PARAMETER ( CZERO = ( 0.0E+0, 0.0E+0 ) )
124 * .. Local Scalars ..
127 REAL D, DI, DR, EPS, F2, F2S, G2, G2S, SAFMIN,
128 $ SAFMN2, SAFMX2, SCALE
131 * .. External Functions ..
134 EXTERNAL SLAMCH, SLAPY2, SISNAN
136 * .. Intrinsic Functions ..
137 INTRINSIC ABS, AIMAG, CMPLX, CONJG, INT, LOG, MAX, REAL,
140 * .. Statement Functions ..
143 * .. Statement Function definitions ..
144 ABS1( FF ) = MAX( ABS( REAL( FF ) ), ABS( AIMAG( FF ) ) )
145 ABSSQ( FF ) = REAL( FF )**2 + AIMAG( FF )**2
147 * .. Executable Statements ..
149 SAFMIN = SLAMCH( 'S' )
151 SAFMN2 = SLAMCH( 'B' )**INT( LOG( SAFMIN / EPS ) /
152 $ LOG( SLAMCH( 'B' ) ) / TWO )
153 SAFMX2 = ONE / SAFMN2
154 SCALE = MAX( ABS1( F ), ABS1( G ) )
158 IF( SCALE.GE.SAFMX2 ) THEN
164 IF( SCALE.GE.SAFMX2 )
166 ELSE IF( SCALE.LE.SAFMN2 ) THEN
167 IF( G.EQ.CZERO.OR.SISNAN( ABS( G ) ) ) THEN
178 IF( SCALE.LE.SAFMN2 )
183 IF( F2.LE.MAX( G2, ONE )*SAFMIN ) THEN
185 * This is a rare case: F is very small.
187 IF( F.EQ.CZERO ) THEN
189 R = SLAPY2( REAL( G ), AIMAG( G ) )
190 * Do complex/real division explicitly with two real divisions
191 D = SLAPY2( REAL( GS ), AIMAG( GS ) )
192 SN = CMPLX( REAL( GS ) / D, -AIMAG( GS ) / D )
195 F2S = SLAPY2( REAL( FS ), AIMAG( FS ) )
196 * G2 and G2S are accurate
197 * G2 is at least SAFMIN, and G2S is at least SAFMN2
199 * Error in CS from underflow in F2S is at most
200 * UNFL / SAFMN2 .lt. sqrt(UNFL*EPS) .lt. EPS
201 * If MAX(G2,ONE)=G2, then F2 .lt. G2*SAFMIN,
202 * and so CS .lt. sqrt(SAFMIN)
203 * If MAX(G2,ONE)=ONE, then F2 .lt. SAFMIN
204 * and so CS .lt. sqrt(SAFMIN)/SAFMN2 = sqrt(EPS)
205 * Therefore, CS = F2S/G2S / sqrt( 1 + (F2S/G2S)**2 ) = F2S/G2S
207 * Make sure abs(FF) = 1
208 * Do complex/real division explicitly with 2 real divisions
209 IF( ABS1( F ).GT.ONE ) THEN
210 D = SLAPY2( REAL( F ), AIMAG( F ) )
211 FF = CMPLX( REAL( F ) / D, AIMAG( F ) / D )
213 DR = SAFMX2*REAL( F )
214 DI = SAFMX2*AIMAG( F )
216 FF = CMPLX( DR / D, DI / D )
218 SN = FF*CMPLX( REAL( GS ) / G2S, -AIMAG( GS ) / G2S )
222 * This is the most common case.
223 * Neither F2 nor F2/G2 are less than SAFMIN
224 * F2S cannot overflow, and it is accurate
226 F2S = SQRT( ONE+G2 / F2 )
227 * Do the F2S(real)*FS(complex) multiply with two real multiplies
228 R = CMPLX( F2S*REAL( FS ), F2S*AIMAG( FS ) )
231 * Do complex/real division explicitly with two real divisions
232 SN = CMPLX( REAL( R ) / D, AIMAG( R ) / D )
234 IF( COUNT.NE.0 ) THEN
235 IF( COUNT.GT.0 ) THEN