Annotation of rpl/lapack/lapack/zlargv.f, revision 1.10
1.8 bertrand 1: *> \brief \b ZLARGV
2: *
3: * =========== DOCUMENTATION ===========
4: *
5: * Online html documentation available at
6: * http://www.netlib.org/lapack/explore-html/
7: *
8: *> \htmlonly
9: *> Download ZLARGV + dependencies
10: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zlargv.f">
11: *> [TGZ]</a>
12: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zlargv.f">
13: *> [ZIP]</a>
14: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zlargv.f">
15: *> [TXT]</a>
16: *> \endhtmlonly
17: *
18: * Definition:
19: * ===========
20: *
21: * SUBROUTINE ZLARGV( N, X, INCX, Y, INCY, C, INCC )
22: *
23: * .. Scalar Arguments ..
24: * INTEGER INCC, INCX, INCY, N
25: * ..
26: * .. Array Arguments ..
27: * DOUBLE PRECISION C( * )
28: * COMPLEX*16 X( * ), Y( * )
29: * ..
30: *
31: *
32: *> \par Purpose:
33: * =============
34: *>
35: *> \verbatim
36: *>
37: *> ZLARGV generates a vector of complex plane rotations with real
38: *> cosines, determined by elements of the complex vectors x and y.
39: *> For i = 1,2,...,n
40: *>
41: *> ( c(i) s(i) ) ( x(i) ) = ( r(i) )
42: *> ( -conjg(s(i)) c(i) ) ( y(i) ) = ( 0 )
43: *>
44: *> where c(i)**2 + ABS(s(i))**2 = 1
45: *>
46: *> The following conventions are used (these are the same as in ZLARTG,
47: *> but differ from the BLAS1 routine ZROTG):
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.
50: *> \endverbatim
51: *
52: * Arguments:
53: * ==========
54: *
55: *> \param[in] N
56: *> \verbatim
57: *> N is INTEGER
58: *> The number of plane rotations to be generated.
59: *> \endverbatim
60: *>
61: *> \param[in,out] X
62: *> \verbatim
63: *> X is COMPLEX*16 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.
66: *> \endverbatim
67: *>
68: *> \param[in] INCX
69: *> \verbatim
70: *> INCX is INTEGER
71: *> The increment between elements of X. INCX > 0.
72: *> \endverbatim
73: *>
74: *> \param[in,out] Y
75: *> \verbatim
76: *> Y is COMPLEX*16 array, dimension (1+(N-1)*INCY)
77: *> On entry, the vector y.
78: *> On exit, the sines of the plane rotations.
79: *> \endverbatim
80: *>
81: *> \param[in] INCY
82: *> \verbatim
83: *> INCY is INTEGER
84: *> The increment between elements of Y. INCY > 0.
85: *> \endverbatim
86: *>
87: *> \param[out] C
88: *> \verbatim
89: *> C is DOUBLE PRECISION array, dimension (1+(N-1)*INCC)
90: *> The cosines of the plane rotations.
91: *> \endverbatim
92: *>
93: *> \param[in] INCC
94: *> \verbatim
95: *> INCC is INTEGER
96: *> The increment between elements of C. INCC > 0.
97: *> \endverbatim
98: *
99: * Authors:
100: * ========
101: *
102: *> \author Univ. of Tennessee
103: *> \author Univ. of California Berkeley
104: *> \author Univ. of Colorado Denver
105: *> \author NAG Ltd.
106: *
107: *> \date November 2011
108: *
109: *> \ingroup complex16OTHERauxiliary
110: *
111: *> \par Further Details:
112: * =====================
113: *>
114: *> \verbatim
115: *>
116: *> 6-6-96 - Modified with a new algorithm by W. Kahan and J. Demmel
117: *>
118: *> This version has a few statements commented out for thread safety
119: *> (machine parameters are computed on each entry). 10 feb 03, SJH.
120: *> \endverbatim
121: *>
122: * =====================================================================
1.1 bertrand 123: SUBROUTINE ZLARGV( N, X, INCX, Y, INCY, C, INCC )
124: *
1.8 bertrand 125: * -- LAPACK auxiliary routine (version 3.4.0) --
1.1 bertrand 126: * -- LAPACK is a software package provided by Univ. of Tennessee, --
127: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
1.8 bertrand 128: * November 2011
1.1 bertrand 129: *
130: * .. Scalar Arguments ..
131: INTEGER INCC, INCX, INCY, N
132: * ..
133: * .. Array Arguments ..
134: DOUBLE PRECISION C( * )
135: COMPLEX*16 X( * ), Y( * )
136: * ..
137: *
138: * =====================================================================
139: *
140: * .. Parameters ..
141: DOUBLE PRECISION TWO, ONE, ZERO
142: PARAMETER ( TWO = 2.0D+0, ONE = 1.0D+0, ZERO = 0.0D+0 )
143: COMPLEX*16 CZERO
144: PARAMETER ( CZERO = ( 0.0D+0, 0.0D+0 ) )
145: * ..
146: * .. Local Scalars ..
147: * LOGICAL FIRST
148:
149: INTEGER COUNT, I, IC, IX, IY, J
150: DOUBLE PRECISION CS, D, DI, DR, EPS, F2, F2S, G2, G2S, SAFMIN,
151: $ SAFMN2, SAFMX2, SCALE
152: COMPLEX*16 F, FF, FS, G, GS, R, SN
153: * ..
154: * .. External Functions ..
155: DOUBLE PRECISION DLAMCH, DLAPY2
156: EXTERNAL DLAMCH, DLAPY2
157: * ..
158: * .. Intrinsic Functions ..
159: INTRINSIC ABS, DBLE, DCMPLX, DCONJG, DIMAG, INT, LOG,
160: $ MAX, SQRT
161: * ..
162: * .. Statement Functions ..
163: DOUBLE PRECISION ABS1, ABSSQ
164: * ..
165: * .. Save statement ..
166: * SAVE FIRST, SAFMX2, SAFMIN, SAFMN2
167: * ..
168: * .. Data statements ..
169: * DATA FIRST / .TRUE. /
170: * ..
171: * .. Statement Function definitions ..
172: ABS1( FF ) = MAX( ABS( DBLE( FF ) ), ABS( DIMAG( FF ) ) )
173: ABSSQ( FF ) = DBLE( FF )**2 + DIMAG( FF )**2
174: * ..
175: * .. Executable Statements ..
176: *
177: * IF( FIRST ) THEN
178: * FIRST = .FALSE.
179: SAFMIN = DLAMCH( 'S' )
180: EPS = DLAMCH( 'E' )
181: SAFMN2 = DLAMCH( 'B' )**INT( LOG( SAFMIN / EPS ) /
182: $ LOG( DLAMCH( 'B' ) ) / TWO )
183: SAFMX2 = ONE / SAFMN2
184: * END IF
185: IX = 1
186: IY = 1
187: IC = 1
188: DO 60 I = 1, N
189: F = X( IX )
190: G = Y( IY )
191: *
192: * Use identical algorithm as in ZLARTG
193: *
194: SCALE = MAX( ABS1( F ), ABS1( G ) )
195: FS = F
196: GS = G
197: COUNT = 0
198: IF( SCALE.GE.SAFMX2 ) THEN
199: 10 CONTINUE
200: COUNT = COUNT + 1
201: FS = FS*SAFMN2
202: GS = GS*SAFMN2
203: SCALE = SCALE*SAFMN2
204: IF( SCALE.GE.SAFMX2 )
205: $ GO TO 10
206: ELSE IF( SCALE.LE.SAFMN2 ) THEN
207: IF( G.EQ.CZERO ) THEN
208: CS = ONE
209: SN = CZERO
210: R = F
211: GO TO 50
212: END IF
213: 20 CONTINUE
214: COUNT = COUNT - 1
215: FS = FS*SAFMX2
216: GS = GS*SAFMX2
217: SCALE = SCALE*SAFMX2
218: IF( SCALE.LE.SAFMN2 )
219: $ GO TO 20
220: END IF
221: F2 = ABSSQ( FS )
222: G2 = ABSSQ( GS )
223: IF( F2.LE.MAX( G2, ONE )*SAFMIN ) THEN
224: *
225: * This is a rare case: F is very small.
226: *
227: IF( F.EQ.CZERO ) THEN
228: CS = ZERO
229: R = DLAPY2( DBLE( G ), DIMAG( G ) )
230: * Do complex/real division explicitly with two real
231: * divisions
232: D = DLAPY2( DBLE( GS ), DIMAG( GS ) )
233: SN = DCMPLX( DBLE( GS ) / D, -DIMAG( GS ) / D )
234: GO TO 50
235: END IF
236: F2S = DLAPY2( DBLE( FS ), DIMAG( FS ) )
237: * G2 and G2S are accurate
238: * G2 is at least SAFMIN, and G2S is at least SAFMN2
239: G2S = SQRT( G2 )
240: * Error in CS from underflow in F2S is at most
241: * UNFL / SAFMN2 .lt. sqrt(UNFL*EPS) .lt. EPS
242: * If MAX(G2,ONE)=G2, then F2 .lt. G2*SAFMIN,
243: * and so CS .lt. sqrt(SAFMIN)
244: * If MAX(G2,ONE)=ONE, then F2 .lt. SAFMIN
245: * and so CS .lt. sqrt(SAFMIN)/SAFMN2 = sqrt(EPS)
246: * Therefore, CS = F2S/G2S / sqrt( 1 + (F2S/G2S)**2 ) = F2S/G2S
247: CS = F2S / G2S
248: * Make sure abs(FF) = 1
249: * Do complex/real division explicitly with 2 real divisions
250: IF( ABS1( F ).GT.ONE ) THEN
251: D = DLAPY2( DBLE( F ), DIMAG( F ) )
252: FF = DCMPLX( DBLE( F ) / D, DIMAG( F ) / D )
253: ELSE
254: DR = SAFMX2*DBLE( F )
255: DI = SAFMX2*DIMAG( F )
256: D = DLAPY2( DR, DI )
257: FF = DCMPLX( DR / D, DI / D )
258: END IF
259: SN = FF*DCMPLX( DBLE( GS ) / G2S, -DIMAG( GS ) / G2S )
260: R = CS*F + SN*G
261: ELSE
262: *
263: * This is the most common case.
264: * Neither F2 nor F2/G2 are less than SAFMIN
265: * F2S cannot overflow, and it is accurate
266: *
267: F2S = SQRT( ONE+G2 / F2 )
268: * Do the F2S(real)*FS(complex) multiply with two real
269: * multiplies
270: R = DCMPLX( F2S*DBLE( FS ), F2S*DIMAG( FS ) )
271: CS = ONE / F2S
272: D = F2 + G2
273: * Do complex/real division explicitly with two real divisions
274: SN = DCMPLX( DBLE( R ) / D, DIMAG( R ) / D )
275: SN = SN*DCONJG( GS )
276: IF( COUNT.NE.0 ) THEN
277: IF( COUNT.GT.0 ) THEN
278: DO 30 J = 1, COUNT
279: R = R*SAFMX2
280: 30 CONTINUE
281: ELSE
282: DO 40 J = 1, -COUNT
283: R = R*SAFMN2
284: 40 CONTINUE
285: END IF
286: END IF
287: END IF
288: 50 CONTINUE
289: C( IC ) = CS
290: Y( IY ) = SN
291: X( IX ) = R
292: IC = IC + INCC
293: IY = IY + INCY
294: IX = IX + INCX
295: 60 CONTINUE
296: RETURN
297: *
298: * End of ZLARGV
299: *
300: END
CVSweb interface <joel.bertrand@systella.fr>