LAPACK  3.4.2
LAPACK: Linear Algebra PACKage
 All Files Functions Groups
zlartg.f
Go to the documentation of this file.
1 *> \brief \b ZLARTG generates a plane rotation with real cosine and complex sine.
2 *
3 * =========== DOCUMENTATION ===========
4 *
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
7 *
8 *> \htmlonly
9 *> Download ZLARTG + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zlartg.f">
11 *> [TGZ]</a>
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zlartg.f">
13 *> [ZIP]</a>
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zlartg.f">
15 *> [TXT]</a>
16 *> \endhtmlonly
17 *
18 * Definition:
19 * ===========
20 *
21 * SUBROUTINE ZLARTG( F, G, CS, SN, R )
22 *
23 * .. Scalar Arguments ..
24 * DOUBLE PRECISION CS
25 * COMPLEX*16 F, G, R, SN
26 * ..
27 *
28 *
29 *> \par Purpose:
30 * =============
31 *>
32 *> \verbatim
33 *>
34 *> ZLARTG generates a plane rotation so that
35 *>
36 *> [ CS SN ] [ F ] [ R ]
37 *> [ __ ] . [ ] = [ ] where CS**2 + |SN|**2 = 1.
38 *> [ -SN CS ] [ G ] [ 0 ]
39 *>
40 *> This is a faster version of the BLAS1 routine ZROTG, 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.
45 *> \endverbatim
46 *
47 * Arguments:
48 * ==========
49 *
50 *> \param[in] F
51 *> \verbatim
52 *> F is COMPLEX*16
53 *> The first component of vector to be rotated.
54 *> \endverbatim
55 *>
56 *> \param[in] G
57 *> \verbatim
58 *> G is COMPLEX*16
59 *> The second component of vector to be rotated.
60 *> \endverbatim
61 *>
62 *> \param[out] CS
63 *> \verbatim
64 *> CS is DOUBLE PRECISION
65 *> The cosine of the rotation.
66 *> \endverbatim
67 *>
68 *> \param[out] SN
69 *> \verbatim
70 *> SN is COMPLEX*16
71 *> The sine of the rotation.
72 *> \endverbatim
73 *>
74 *> \param[out] R
75 *> \verbatim
76 *> R is COMPLEX*16
77 *> The nonzero component of the rotated vector.
78 *> \endverbatim
79 *
80 * Authors:
81 * ========
82 *
83 *> \author Univ. of Tennessee
84 *> \author Univ. of California Berkeley
85 *> \author Univ. of Colorado Denver
86 *> \author NAG Ltd.
87 *
88 *> \date September 2012
89 *
90 *> \ingroup complex16OTHERauxiliary
91 *
92 *> \par Further Details:
93 * =====================
94 *>
95 *> \verbatim
96 *>
97 *> 3-5-96 - Modified with a new algorithm by W. Kahan and J. Demmel
98 *>
99 *> This version has a few statements commented out for thread safety
100 *> (machine parameters are computed on each entry). 10 feb 03, SJH.
101 *> \endverbatim
102 *>
103 * =====================================================================
104  SUBROUTINE zlartg( F, G, CS, SN, R )
105 *
106 * -- LAPACK auxiliary routine (version 3.4.2) --
107 * -- LAPACK is a software package provided by Univ. of Tennessee, --
108 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
109 * September 2012
110 *
111 * .. Scalar Arguments ..
112  DOUBLE PRECISION cs
113  COMPLEX*16 f, g, r, sn
114 * ..
115 *
116 * =====================================================================
117 *
118 * .. Parameters ..
119  DOUBLE PRECISION two, one, zero
120  parameter( two = 2.0d+0, one = 1.0d+0, zero = 0.0d+0 )
121  COMPLEX*16 czero
122  parameter( czero = ( 0.0d+0, 0.0d+0 ) )
123 * ..
124 * .. Local Scalars ..
125 * LOGICAL FIRST
126  INTEGER count, i
127  DOUBLE PRECISION d, di, dr, eps, f2, f2s, g2, g2s, safmin,
128  $ safmn2, safmx2, scale
129  COMPLEX*16 ff, fs, gs
130 * ..
131 * .. External Functions ..
132  DOUBLE PRECISION dlamch, dlapy2
133  EXTERNAL dlamch, dlapy2
134 * ..
135 * .. Intrinsic Functions ..
136  INTRINSIC abs, dble, dcmplx, dconjg, dimag, int, log,
137  $ max, sqrt
138 * ..
139 * .. Statement Functions ..
140  DOUBLE PRECISION abs1, abssq
141 * ..
142 * .. Save statement ..
143 * SAVE FIRST, SAFMX2, SAFMIN, SAFMN2
144 * ..
145 * .. Data statements ..
146 * DATA FIRST / .TRUE. /
147 * ..
148 * .. Statement Function definitions ..
149  abs1( ff ) = max( abs( dble( ff ) ), abs( dimag( ff ) ) )
150  abssq( ff ) = dble( ff )**2 + dimag( ff )**2
151 * ..
152 * .. Executable Statements ..
153 *
154 * IF( FIRST ) THEN
155  safmin = dlamch( 'S' )
156  eps = dlamch( 'E' )
157  safmn2 = dlamch( 'B' )**int( log( safmin / eps ) /
158  $ log( dlamch( 'B' ) ) / two )
159  safmx2 = one / safmn2
160 * FIRST = .FALSE.
161 * END IF
162  scale = max( abs1( f ), abs1( g ) )
163  fs = f
164  gs = g
165  count = 0
166  IF( scale.GE.safmx2 ) THEN
167  10 continue
168  count = count + 1
169  fs = fs*safmn2
170  gs = gs*safmn2
171  scale = scale*safmn2
172  IF( scale.GE.safmx2 )
173  $ go to 10
174  ELSE IF( scale.LE.safmn2 ) THEN
175  IF( g.EQ.czero ) THEN
176  cs = one
177  sn = czero
178  r = f
179  return
180  END IF
181  20 continue
182  count = count - 1
183  fs = fs*safmx2
184  gs = gs*safmx2
185  scale = scale*safmx2
186  IF( scale.LE.safmn2 )
187  $ go to 20
188  END IF
189  f2 = abssq( fs )
190  g2 = abssq( gs )
191  IF( f2.LE.max( g2, one )*safmin ) THEN
192 *
193 * This is a rare case: F is very small.
194 *
195  IF( f.EQ.czero ) THEN
196  cs = zero
197  r = dlapy2( dble( g ), dimag( g ) )
198 * Do complex/real division explicitly with two real divisions
199  d = dlapy2( dble( gs ), dimag( gs ) )
200  sn = dcmplx( dble( gs ) / d, -dimag( gs ) / d )
201  return
202  END IF
203  f2s = dlapy2( dble( fs ), dimag( fs ) )
204 * G2 and G2S are accurate
205 * G2 is at least SAFMIN, and G2S is at least SAFMN2
206  g2s = sqrt( g2 )
207 * Error in CS from underflow in F2S is at most
208 * UNFL / SAFMN2 .lt. sqrt(UNFL*EPS) .lt. EPS
209 * If MAX(G2,ONE)=G2, then F2 .lt. G2*SAFMIN,
210 * and so CS .lt. sqrt(SAFMIN)
211 * If MAX(G2,ONE)=ONE, then F2 .lt. SAFMIN
212 * and so CS .lt. sqrt(SAFMIN)/SAFMN2 = sqrt(EPS)
213 * Therefore, CS = F2S/G2S / sqrt( 1 + (F2S/G2S)**2 ) = F2S/G2S
214  cs = f2s / g2s
215 * Make sure abs(FF) = 1
216 * Do complex/real division explicitly with 2 real divisions
217  IF( abs1( f ).GT.one ) THEN
218  d = dlapy2( dble( f ), dimag( f ) )
219  ff = dcmplx( dble( f ) / d, dimag( f ) / d )
220  ELSE
221  dr = safmx2*dble( f )
222  di = safmx2*dimag( f )
223  d = dlapy2( dr, di )
224  ff = dcmplx( dr / d, di / d )
225  END IF
226  sn = ff*dcmplx( dble( gs ) / g2s, -dimag( gs ) / g2s )
227  r = cs*f + sn*g
228  ELSE
229 *
230 * This is the most common case.
231 * Neither F2 nor F2/G2 are less than SAFMIN
232 * F2S cannot overflow, and it is accurate
233 *
234  f2s = sqrt( one+g2 / f2 )
235 * Do the F2S(real)*FS(complex) multiply with two real multiplies
236  r = dcmplx( f2s*dble( fs ), f2s*dimag( fs ) )
237  cs = one / f2s
238  d = f2 + g2
239 * Do complex/real division explicitly with two real divisions
240  sn = dcmplx( dble( r ) / d, dimag( r ) / d )
241  sn = sn*dconjg( gs )
242  IF( count.NE.0 ) THEN
243  IF( count.GT.0 ) THEN
244  DO 30 i = 1, count
245  r = r*safmx2
246  30 continue
247  ELSE
248  DO 40 i = 1, -count
249  r = r*safmn2
250  40 continue
251  END IF
252  END IF
253  END IF
254  return
255 *
256 * End of ZLARTG
257 *
258  END