Annotation of rpl/lapack/lapack/zlargv.f, revision 1.8
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>