zlartg.c
Go to the documentation of this file.
00001 /* zlartg.f -- translated by f2c (version 20061008).
00002    You must link the resulting object file with libf2c:
00003         on Microsoft Windows system, link with libf2c.lib;
00004         on Linux or Unix systems, link with .../path/to/libf2c.a -lm
00005         or, if you install libf2c.a in a standard place, with -lf2c -lm
00006         -- in that order, at the end of the command line, as in
00007                 cc *.o -lf2c -lm
00008         Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
00009 
00010                 http://www.netlib.org/f2c/libf2c.zip
00011 */
00012 
00013 #include "f2c.h"
00014 #include "blaswrap.h"
00015 
00016 /* Subroutine */ int zlartg_(doublecomplex *f, doublecomplex *g, doublereal *
00017         cs, doublecomplex *sn, doublecomplex *r__)
00018 {
00019     /* System generated locals */
00020     integer i__1;
00021     doublereal d__1, d__2, d__3, d__4, d__5, d__6, d__7, d__8, d__9, d__10;
00022     doublecomplex z__1, z__2, z__3;
00023 
00024     /* Builtin functions */
00025     double log(doublereal), pow_di(doublereal *, integer *), d_imag(
00026             doublecomplex *), sqrt(doublereal);
00027     void d_cnjg(doublecomplex *, doublecomplex *);
00028 
00029     /* Local variables */
00030     doublereal d__;
00031     integer i__;
00032     doublereal f2, g2;
00033     doublecomplex ff;
00034     doublereal di, dr;
00035     doublecomplex fs, gs;
00036     doublereal f2s, g2s, eps, scale;
00037     integer count;
00038     doublereal safmn2;
00039     extern doublereal dlapy2_(doublereal *, doublereal *);
00040     doublereal safmx2;
00041     extern doublereal dlamch_(char *);
00042     doublereal safmin;
00043 
00044 
00045 /*  -- LAPACK auxiliary routine (version 3.2) -- */
00046 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00047 /*     November 2006 */
00048 
00049 /*     .. Scalar Arguments .. */
00050 /*     .. */
00051 
00052 /*  Purpose */
00053 /*  ======= */
00054 
00055 /*  ZLARTG generates a plane rotation so that */
00056 
00057 /*     [  CS  SN  ]     [ F ]     [ R ] */
00058 /*     [  __      ]  .  [   ]  =  [   ]   where CS**2 + |SN|**2 = 1. */
00059 /*     [ -SN  CS  ]     [ G ]     [ 0 ] */
00060 
00061 /*  This is a faster version of the BLAS1 routine ZROTG, except for */
00062 /*  the following differences: */
00063 /*     F and G are unchanged on return. */
00064 /*     If G=0, then CS=1 and SN=0. */
00065 /*     If F=0, then CS=0 and SN is chosen so that R is real. */
00066 
00067 /*  Arguments */
00068 /*  ========= */
00069 
00070 /*  F       (input) COMPLEX*16 */
00071 /*          The first component of vector to be rotated. */
00072 
00073 /*  G       (input) COMPLEX*16 */
00074 /*          The second component of vector to be rotated. */
00075 
00076 /*  CS      (output) DOUBLE PRECISION */
00077 /*          The cosine of the rotation. */
00078 
00079 /*  SN      (output) COMPLEX*16 */
00080 /*          The sine of the rotation. */
00081 
00082 /*  R       (output) COMPLEX*16 */
00083 /*          The nonzero component of the rotated vector. */
00084 
00085 /*  Further Details */
00086 /*  ======= ======= */
00087 
00088 /*  3-5-96 - Modified with a new algorithm by W. Kahan and J. Demmel */
00089 
00090 /*  This version has a few statements commented out for thread safety */
00091 /*  (machine parameters are computed on each entry). 10 feb 03, SJH. */
00092 
00093 /*  ===================================================================== */
00094 
00095 /*     .. Parameters .. */
00096 /*     .. */
00097 /*     .. Local Scalars .. */
00098 /*     LOGICAL            FIRST */
00099 /*     .. */
00100 /*     .. External Functions .. */
00101 /*     .. */
00102 /*     .. Intrinsic Functions .. */
00103 /*     .. */
00104 /*     .. Statement Functions .. */
00105 /*     .. */
00106 /*     .. Save statement .. */
00107 /*     SAVE               FIRST, SAFMX2, SAFMIN, SAFMN2 */
00108 /*     .. */
00109 /*     .. Data statements .. */
00110 /*     DATA               FIRST / .TRUE. / */
00111 /*     .. */
00112 /*     .. Statement Function definitions .. */
00113 /*     .. */
00114 /*     .. Executable Statements .. */
00115 
00116 /*     IF( FIRST ) THEN */
00117     safmin = dlamch_("S");
00118     eps = dlamch_("E");
00119     d__1 = dlamch_("B");
00120     i__1 = (integer) (log(safmin / eps) / log(dlamch_("B")) / 2.);
00121     safmn2 = pow_di(&d__1, &i__1);
00122     safmx2 = 1. / safmn2;
00123 /*        FIRST = .FALSE. */
00124 /*     END IF */
00125 /* Computing MAX */
00126 /* Computing MAX */
00127     d__7 = (d__1 = f->r, abs(d__1)), d__8 = (d__2 = d_imag(f), abs(d__2));
00128 /* Computing MAX */
00129     d__9 = (d__3 = g->r, abs(d__3)), d__10 = (d__4 = d_imag(g), abs(d__4));
00130     d__5 = max(d__7,d__8), d__6 = max(d__9,d__10);
00131     scale = max(d__5,d__6);
00132     fs.r = f->r, fs.i = f->i;
00133     gs.r = g->r, gs.i = g->i;
00134     count = 0;
00135     if (scale >= safmx2) {
00136 L10:
00137         ++count;
00138         z__1.r = safmn2 * fs.r, z__1.i = safmn2 * fs.i;
00139         fs.r = z__1.r, fs.i = z__1.i;
00140         z__1.r = safmn2 * gs.r, z__1.i = safmn2 * gs.i;
00141         gs.r = z__1.r, gs.i = z__1.i;
00142         scale *= safmn2;
00143         if (scale >= safmx2) {
00144             goto L10;
00145         }
00146     } else if (scale <= safmn2) {
00147         if (g->r == 0. && g->i == 0.) {
00148             *cs = 1.;
00149             sn->r = 0., sn->i = 0.;
00150             r__->r = f->r, r__->i = f->i;
00151             return 0;
00152         }
00153 L20:
00154         --count;
00155         z__1.r = safmx2 * fs.r, z__1.i = safmx2 * fs.i;
00156         fs.r = z__1.r, fs.i = z__1.i;
00157         z__1.r = safmx2 * gs.r, z__1.i = safmx2 * gs.i;
00158         gs.r = z__1.r, gs.i = z__1.i;
00159         scale *= safmx2;
00160         if (scale <= safmn2) {
00161             goto L20;
00162         }
00163     }
00164 /* Computing 2nd power */
00165     d__1 = fs.r;
00166 /* Computing 2nd power */
00167     d__2 = d_imag(&fs);
00168     f2 = d__1 * d__1 + d__2 * d__2;
00169 /* Computing 2nd power */
00170     d__1 = gs.r;
00171 /* Computing 2nd power */
00172     d__2 = d_imag(&gs);
00173     g2 = d__1 * d__1 + d__2 * d__2;
00174     if (f2 <= max(g2,1.) * safmin) {
00175 
00176 /*        This is a rare case: F is very small. */
00177 
00178         if (f->r == 0. && f->i == 0.) {
00179             *cs = 0.;
00180             d__2 = g->r;
00181             d__3 = d_imag(g);
00182             d__1 = dlapy2_(&d__2, &d__3);
00183             r__->r = d__1, r__->i = 0.;
00184 /*           Do complex/real division explicitly with two real divisions */
00185             d__1 = gs.r;
00186             d__2 = d_imag(&gs);
00187             d__ = dlapy2_(&d__1, &d__2);
00188             d__1 = gs.r / d__;
00189             d__2 = -d_imag(&gs) / d__;
00190             z__1.r = d__1, z__1.i = d__2;
00191             sn->r = z__1.r, sn->i = z__1.i;
00192             return 0;
00193         }
00194         d__1 = fs.r;
00195         d__2 = d_imag(&fs);
00196         f2s = dlapy2_(&d__1, &d__2);
00197 /*        G2 and G2S are accurate */
00198 /*        G2 is at least SAFMIN, and G2S is at least SAFMN2 */
00199         g2s = sqrt(g2);
00200 /*        Error in CS from underflow in F2S is at most */
00201 /*        UNFL / SAFMN2 .lt. sqrt(UNFL*EPS) .lt. EPS */
00202 /*        If MAX(G2,ONE)=G2, then F2 .lt. G2*SAFMIN, */
00203 /*        and so CS .lt. sqrt(SAFMIN) */
00204 /*        If MAX(G2,ONE)=ONE, then F2 .lt. SAFMIN */
00205 /*        and so CS .lt. sqrt(SAFMIN)/SAFMN2 = sqrt(EPS) */
00206 /*        Therefore, CS = F2S/G2S / sqrt( 1 + (F2S/G2S)**2 ) = F2S/G2S */
00207         *cs = f2s / g2s;
00208 /*        Make sure abs(FF) = 1 */
00209 /*        Do complex/real division explicitly with 2 real divisions */
00210 /* Computing MAX */
00211         d__3 = (d__1 = f->r, abs(d__1)), d__4 = (d__2 = d_imag(f), abs(d__2));
00212         if (max(d__3,d__4) > 1.) {
00213             d__1 = f->r;
00214             d__2 = d_imag(f);
00215             d__ = dlapy2_(&d__1, &d__2);
00216             d__1 = f->r / d__;
00217             d__2 = d_imag(f) / d__;
00218             z__1.r = d__1, z__1.i = d__2;
00219             ff.r = z__1.r, ff.i = z__1.i;
00220         } else {
00221             dr = safmx2 * f->r;
00222             di = safmx2 * d_imag(f);
00223             d__ = dlapy2_(&dr, &di);
00224             d__1 = dr / d__;
00225             d__2 = di / d__;
00226             z__1.r = d__1, z__1.i = d__2;
00227             ff.r = z__1.r, ff.i = z__1.i;
00228         }
00229         d__1 = gs.r / g2s;
00230         d__2 = -d_imag(&gs) / g2s;
00231         z__2.r = d__1, z__2.i = d__2;
00232         z__1.r = ff.r * z__2.r - ff.i * z__2.i, z__1.i = ff.r * z__2.i + ff.i 
00233                 * z__2.r;
00234         sn->r = z__1.r, sn->i = z__1.i;
00235         z__2.r = *cs * f->r, z__2.i = *cs * f->i;
00236         z__3.r = sn->r * g->r - sn->i * g->i, z__3.i = sn->r * g->i + sn->i * 
00237                 g->r;
00238         z__1.r = z__2.r + z__3.r, z__1.i = z__2.i + z__3.i;
00239         r__->r = z__1.r, r__->i = z__1.i;
00240     } else {
00241 
00242 /*        This is the most common case. */
00243 /*        Neither F2 nor F2/G2 are less than SAFMIN */
00244 /*        F2S cannot overflow, and it is accurate */
00245 
00246         f2s = sqrt(g2 / f2 + 1.);
00247 /*        Do the F2S(real)*FS(complex) multiply with two real multiplies */
00248         d__1 = f2s * fs.r;
00249         d__2 = f2s * d_imag(&fs);
00250         z__1.r = d__1, z__1.i = d__2;
00251         r__->r = z__1.r, r__->i = z__1.i;
00252         *cs = 1. / f2s;
00253         d__ = f2 + g2;
00254 /*        Do complex/real division explicitly with two real divisions */
00255         d__1 = r__->r / d__;
00256         d__2 = d_imag(r__) / d__;
00257         z__1.r = d__1, z__1.i = d__2;
00258         sn->r = z__1.r, sn->i = z__1.i;
00259         d_cnjg(&z__2, &gs);
00260         z__1.r = sn->r * z__2.r - sn->i * z__2.i, z__1.i = sn->r * z__2.i + 
00261                 sn->i * z__2.r;
00262         sn->r = z__1.r, sn->i = z__1.i;
00263         if (count != 0) {
00264             if (count > 0) {
00265                 i__1 = count;
00266                 for (i__ = 1; i__ <= i__1; ++i__) {
00267                     z__1.r = safmx2 * r__->r, z__1.i = safmx2 * r__->i;
00268                     r__->r = z__1.r, r__->i = z__1.i;
00269 /* L30: */
00270                 }
00271             } else {
00272                 i__1 = -count;
00273                 for (i__ = 1; i__ <= i__1; ++i__) {
00274                     z__1.r = safmn2 * r__->r, z__1.i = safmn2 * r__->i;
00275                     r__->r = z__1.r, r__->i = z__1.i;
00276 /* L40: */
00277                 }
00278             }
00279         }
00280     }
00281     return 0;
00282 
00283 /*     End of ZLARTG */
00284 
00285 } /* zlartg_ */


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:56:41