1 *> \brief \b CLARGV generates a vector of plane rotations with real cosines and complex sines.
3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download CLARGV + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/clargv.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/clargv.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/clargv.f">
21 * SUBROUTINE CLARGV( N, X, INCX, Y, INCY, C, INCC )
23 * .. Scalar Arguments ..
24 * INTEGER INCC, INCX, INCY, N
26 * .. Array Arguments ..
28 * COMPLEX X( * ), Y( * )
37 *> CLARGV generates a vector of complex plane rotations with real
38 *> cosines, determined by elements of the complex vectors x and y.
41 *> ( c(i) s(i) ) ( x(i) ) = ( r(i) )
42 *> ( -conjg(s(i)) c(i) ) ( y(i) ) = ( 0 )
44 *> where c(i)**2 + ABS(s(i))**2 = 1
46 *> The following conventions are used (these are the same as in CLARTG,
47 *> but differ from the BLAS1 routine CROTG):
48 *> If y(i)=0, then c(i)=1 and s(i)=0.
49 *> If x(i)=0, then c(i)=0 and s(i) is chosen so that r(i) is real.
58 *> The number of plane rotations to be generated.
63 *> X is COMPLEX array, dimension (1+(N-1)*INCX)
64 *> On entry, the vector x.
65 *> On exit, x(i) is overwritten by r(i), for i = 1,...,n.
71 *> The increment between elements of X. INCX > 0.
76 *> Y is COMPLEX array, dimension (1+(N-1)*INCY)
77 *> On entry, the vector y.
78 *> On exit, the sines of the plane rotations.
84 *> The increment between elements of Y. INCY > 0.
89 *> C is REAL array, dimension (1+(N-1)*INCC)
90 *> The cosines of the plane rotations.
96 *> The increment between elements of C. INCC > 0.
102 *> \author Univ. of Tennessee
103 *> \author Univ. of California Berkeley
104 *> \author Univ. of Colorado Denver
107 *> \date September 2012
109 *> \ingroup complexOTHERauxiliary
111 *> \par Further Details:
112 * =====================
116 *> 6-6-96 - Modified with a new algorithm by W. Kahan and J. Demmel
118 *> This version has a few statements commented out for thread safety
119 *> (machine parameters are computed on each entry). 10 feb 03, SJH.
122 * =====================================================================
123 SUBROUTINE CLARGV( N, X, INCX, Y, INCY, C, INCC )
125 * -- LAPACK auxiliary routine (version 3.4.2) --
126 * -- LAPACK is a software package provided by Univ. of Tennessee, --
127 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
130 * .. Scalar Arguments ..
131 INTEGER INCC, INCX, INCY, N
133 * .. Array Arguments ..
135 COMPLEX X( * ), Y( * )
138 * =====================================================================
142 PARAMETER ( TWO = 2.0E+0, ONE = 1.0E+0, ZERO = 0.0E+0 )
144 PARAMETER ( CZERO = ( 0.0E+0, 0.0E+0 ) )
146 * .. Local Scalars ..
148 INTEGER COUNT, I, IC, IX, IY, J
149 REAL CS, D, DI, DR, EPS, F2, F2S, G2, G2S, SAFMIN,
150 $ SAFMN2, SAFMX2, SCALE
151 COMPLEX F, FF, FS, G, GS, R, SN
153 * .. External Functions ..
155 EXTERNAL SLAMCH, SLAPY2
157 * .. Intrinsic Functions ..
158 INTRINSIC ABS, AIMAG, CMPLX, CONJG, INT, LOG, MAX, REAL,
161 * .. Statement Functions ..
164 * .. Save statement ..
165 * SAVE FIRST, SAFMX2, SAFMIN, SAFMN2
167 * .. Data statements ..
168 * DATA FIRST / .TRUE. /
170 * .. Statement Function definitions ..
171 ABS1( FF ) = MAX( ABS( REAL( FF ) ), ABS( AIMAG( FF ) ) )
172 ABSSQ( FF ) = REAL( FF )**2 + AIMAG( FF )**2
174 * .. Executable Statements ..
178 SAFMIN = SLAMCH( 'S' )
180 SAFMN2 = SLAMCH( 'B' )**INT( LOG( SAFMIN / EPS ) /
181 $ LOG( SLAMCH( 'B' ) ) / TWO )
182 SAFMX2 = ONE / SAFMN2
191 * Use identical algorithm as in CLARTG
193 SCALE = MAX( ABS1( F ), ABS1( G ) )
197 IF( SCALE.GE.SAFMX2 ) THEN
203 IF( SCALE.GE.SAFMX2 )
205 ELSE IF( SCALE.LE.SAFMN2 ) THEN
206 IF( G.EQ.CZERO ) THEN
217 IF( SCALE.LE.SAFMN2 )
222 IF( F2.LE.MAX( G2, ONE )*SAFMIN ) THEN
224 * This is a rare case: F is very small.
226 IF( F.EQ.CZERO ) THEN
228 R = SLAPY2( REAL( G ), AIMAG( G ) )
229 * Do complex/real division explicitly with two real
231 D = SLAPY2( REAL( GS ), AIMAG( GS ) )
232 SN = CMPLX( REAL( GS ) / D, -AIMAG( GS ) / D )
235 F2S = SLAPY2( REAL( FS ), AIMAG( FS ) )
236 * G2 and G2S are accurate
237 * G2 is at least SAFMIN, and G2S is at least SAFMN2
239 * Error in CS from underflow in F2S is at most
240 * UNFL / SAFMN2 .lt. sqrt(UNFL*EPS) .lt. EPS
241 * If MAX(G2,ONE)=G2, then F2 .lt. G2*SAFMIN,
242 * and so CS .lt. sqrt(SAFMIN)
243 * If MAX(G2,ONE)=ONE, then F2 .lt. SAFMIN
244 * and so CS .lt. sqrt(SAFMIN)/SAFMN2 = sqrt(EPS)
245 * Therefore, CS = F2S/G2S / sqrt( 1 + (F2S/G2S)**2 ) = F2S/G2S
247 * Make sure abs(FF) = 1
248 * Do complex/real division explicitly with 2 real divisions
249 IF( ABS1( F ).GT.ONE ) THEN
250 D = SLAPY2( REAL( F ), AIMAG( F ) )
251 FF = CMPLX( REAL( F ) / D, AIMAG( F ) / D )
253 DR = SAFMX2*REAL( F )
254 DI = SAFMX2*AIMAG( F )
256 FF = CMPLX( DR / D, DI / D )
258 SN = FF*CMPLX( REAL( GS ) / G2S, -AIMAG( GS ) / G2S )
262 * This is the most common case.
263 * Neither F2 nor F2/G2 are less than SAFMIN
264 * F2S cannot overflow, and it is accurate
266 F2S = SQRT( ONE+G2 / F2 )
267 * Do the F2S(real)*FS(complex) multiply with two real
269 R = CMPLX( F2S*REAL( FS ), F2S*AIMAG( FS ) )
272 * Do complex/real division explicitly with two real divisions
273 SN = CMPLX( REAL( R ) / D, AIMAG( R ) / D )
275 IF( COUNT.NE.0 ) THEN
276 IF( COUNT.GT.0 ) THEN