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


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:55:31