LAPACK 3.3.0

dlartg.f

Go to the documentation of this file.
00001       SUBROUTINE DLARTG( F, G, CS, SN, R )
00002 *
00003 *  -- LAPACK auxiliary routine (version 3.2) --
00004 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
00005 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
00006 *     November 2006
00007 *
00008 *     .. Scalar Arguments ..
00009       DOUBLE PRECISION   CS, F, G, R, SN
00010 *     ..
00011 *
00012 *  Purpose
00013 *  =======
00014 *
00015 *  DLARTG generate a plane rotation so that
00016 *
00017 *     [  CS  SN  ]  .  [ F ]  =  [ R ]   where CS**2 + SN**2 = 1.
00018 *     [ -SN  CS  ]     [ G ]     [ 0 ]
00019 *
00020 *  This is a slower, more accurate version of the BLAS1 routine DROTG,
00021 *  with the following other differences:
00022 *     F and G are unchanged on return.
00023 *     If G=0, then CS=1 and SN=0.
00024 *     If F=0 and (G .ne. 0), then CS=0 and SN=1 without doing any
00025 *        floating point operations (saves work in DBDSQR when
00026 *        there are zeros on the diagonal).
00027 *
00028 *  If F exceeds G in magnitude, CS will be positive.
00029 *
00030 *  Arguments
00031 *  =========
00032 *
00033 *  F       (input) DOUBLE PRECISION
00034 *          The first component of vector to be rotated.
00035 *
00036 *  G       (input) DOUBLE PRECISION
00037 *          The second component of vector to be rotated.
00038 *
00039 *  CS      (output) DOUBLE PRECISION
00040 *          The cosine of the rotation.
00041 *
00042 *  SN      (output) DOUBLE PRECISION
00043 *          The sine of the rotation.
00044 *
00045 *  R       (output) DOUBLE PRECISION
00046 *          The nonzero component of the rotated vector.
00047 *
00048 *  This version has a few statements commented out for thread safety
00049 *  (machine parameters are computed on each entry). 10 feb 03, SJH.
00050 *
00051 *  =====================================================================
00052 *
00053 *     .. Parameters ..
00054       DOUBLE PRECISION   ZERO
00055       PARAMETER          ( ZERO = 0.0D0 )
00056       DOUBLE PRECISION   ONE
00057       PARAMETER          ( ONE = 1.0D0 )
00058       DOUBLE PRECISION   TWO
00059       PARAMETER          ( TWO = 2.0D0 )
00060 *     ..
00061 *     .. Local Scalars ..
00062 *     LOGICAL            FIRST
00063       INTEGER            COUNT, I
00064       DOUBLE PRECISION   EPS, F1, G1, SAFMIN, SAFMN2, SAFMX2, SCALE
00065 *     ..
00066 *     .. External Functions ..
00067       DOUBLE PRECISION   DLAMCH
00068       EXTERNAL           DLAMCH
00069 *     ..
00070 *     .. Intrinsic Functions ..
00071       INTRINSIC          ABS, INT, LOG, MAX, SQRT
00072 *     ..
00073 *     .. Save statement ..
00074 *     SAVE               FIRST, SAFMX2, SAFMIN, SAFMN2
00075 *     ..
00076 *     .. Data statements ..
00077 *     DATA               FIRST / .TRUE. /
00078 *     ..
00079 *     .. Executable Statements ..
00080 *
00081 *     IF( FIRST ) THEN
00082          SAFMIN = DLAMCH( 'S' )
00083          EPS = DLAMCH( 'E' )
00084          SAFMN2 = DLAMCH( 'B' )**INT( LOG( SAFMIN / EPS ) /
00085      $            LOG( DLAMCH( 'B' ) ) / TWO )
00086          SAFMX2 = ONE / SAFMN2
00087 *        FIRST = .FALSE.
00088 *     END IF
00089       IF( G.EQ.ZERO ) THEN
00090          CS = ONE
00091          SN = ZERO
00092          R = F
00093       ELSE IF( F.EQ.ZERO ) THEN
00094          CS = ZERO
00095          SN = ONE
00096          R = G
00097       ELSE
00098          F1 = F
00099          G1 = G
00100          SCALE = MAX( ABS( F1 ), ABS( G1 ) )
00101          IF( SCALE.GE.SAFMX2 ) THEN
00102             COUNT = 0
00103    10       CONTINUE
00104             COUNT = COUNT + 1
00105             F1 = F1*SAFMN2
00106             G1 = G1*SAFMN2
00107             SCALE = MAX( ABS( F1 ), ABS( G1 ) )
00108             IF( SCALE.GE.SAFMX2 )
00109      $         GO TO 10
00110             R = SQRT( F1**2+G1**2 )
00111             CS = F1 / R
00112             SN = G1 / R
00113             DO 20 I = 1, COUNT
00114                R = R*SAFMX2
00115    20       CONTINUE
00116          ELSE IF( SCALE.LE.SAFMN2 ) THEN
00117             COUNT = 0
00118    30       CONTINUE
00119             COUNT = COUNT + 1
00120             F1 = F1*SAFMX2
00121             G1 = G1*SAFMX2
00122             SCALE = MAX( ABS( F1 ), ABS( G1 ) )
00123             IF( SCALE.LE.SAFMN2 )
00124      $         GO TO 30
00125             R = SQRT( F1**2+G1**2 )
00126             CS = F1 / R
00127             SN = G1 / R
00128             DO 40 I = 1, COUNT
00129                R = R*SAFMN2
00130    40       CONTINUE
00131          ELSE
00132             R = SQRT( F1**2+G1**2 )
00133             CS = F1 / R
00134             SN = G1 / R
00135          END IF
00136          IF( ABS( F ).GT.ABS( G ) .AND. CS.LT.ZERO ) THEN
00137             CS = -CS
00138             SN = -SN
00139             R = -R
00140          END IF
00141       END IF
00142       RETURN
00143 *
00144 *     End of DLARTG
00145 *
00146       END
 All Files Functions