dlasv2.c
Go to the documentation of this file.
00001 /* dlasv2.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 /* Table of constant values */
00017 
00018 static doublereal c_b3 = 2.;
00019 static doublereal c_b4 = 1.;
00020 
00021 /* Subroutine */ int dlasv2_(doublereal *f, doublereal *g, doublereal *h__, 
00022         doublereal *ssmin, doublereal *ssmax, doublereal *snr, doublereal *
00023         csr, doublereal *snl, doublereal *csl)
00024 {
00025     /* System generated locals */
00026     doublereal d__1;
00027 
00028     /* Builtin functions */
00029     double sqrt(doublereal), d_sign(doublereal *, doublereal *);
00030 
00031     /* Local variables */
00032     doublereal a, d__, l, m, r__, s, t, fa, ga, ha, ft, gt, ht, mm, tt, clt, 
00033             crt, slt, srt;
00034     integer pmax;
00035     doublereal temp;
00036     logical swap;
00037     doublereal tsign;
00038     extern doublereal dlamch_(char *);
00039     logical gasmal;
00040 
00041 
00042 /*  -- LAPACK auxiliary routine (version 3.2) -- */
00043 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00044 /*     November 2006 */
00045 
00046 /*     .. Scalar Arguments .. */
00047 /*     .. */
00048 
00049 /*  Purpose */
00050 /*  ======= */
00051 
00052 /*  DLASV2 computes the singular value decomposition of a 2-by-2 */
00053 /*  triangular matrix */
00054 /*     [  F   G  ] */
00055 /*     [  0   H  ]. */
00056 /*  On return, abs(SSMAX) is the larger singular value, abs(SSMIN) is the */
00057 /*  smaller singular value, and (CSL,SNL) and (CSR,SNR) are the left and */
00058 /*  right singular vectors for abs(SSMAX), giving the decomposition */
00059 
00060 /*     [ CSL  SNL ] [  F   G  ] [ CSR -SNR ]  =  [ SSMAX   0   ] */
00061 /*     [-SNL  CSL ] [  0   H  ] [ SNR  CSR ]     [  0    SSMIN ]. */
00062 
00063 /*  Arguments */
00064 /*  ========= */
00065 
00066 /*  F       (input) DOUBLE PRECISION */
00067 /*          The (1,1) element of the 2-by-2 matrix. */
00068 
00069 /*  G       (input) DOUBLE PRECISION */
00070 /*          The (1,2) element of the 2-by-2 matrix. */
00071 
00072 /*  H       (input) DOUBLE PRECISION */
00073 /*          The (2,2) element of the 2-by-2 matrix. */
00074 
00075 /*  SSMIN   (output) DOUBLE PRECISION */
00076 /*          abs(SSMIN) is the smaller singular value. */
00077 
00078 /*  SSMAX   (output) DOUBLE PRECISION */
00079 /*          abs(SSMAX) is the larger singular value. */
00080 
00081 /*  SNL     (output) DOUBLE PRECISION */
00082 /*  CSL     (output) DOUBLE PRECISION */
00083 /*          The vector (CSL, SNL) is a unit left singular vector for the */
00084 /*          singular value abs(SSMAX). */
00085 
00086 /*  SNR     (output) DOUBLE PRECISION */
00087 /*  CSR     (output) DOUBLE PRECISION */
00088 /*          The vector (CSR, SNR) is a unit right singular vector for the */
00089 /*          singular value abs(SSMAX). */
00090 
00091 /*  Further Details */
00092 /*  =============== */
00093 
00094 /*  Any input parameter may be aliased with any output parameter. */
00095 
00096 /*  Barring over/underflow and assuming a guard digit in subtraction, all */
00097 /*  output quantities are correct to within a few units in the last */
00098 /*  place (ulps). */
00099 
00100 /*  In IEEE arithmetic, the code works correctly if one matrix element is */
00101 /*  infinite. */
00102 
00103 /*  Overflow will not occur unless the largest singular value itself */
00104 /*  overflows or is within a few ulps of overflow. (On machines with */
00105 /*  partial overflow, like the Cray, overflow may occur if the largest */
00106 /*  singular value is within a factor of 2 of overflow.) */
00107 
00108 /*  Underflow is harmless if underflow is gradual. Otherwise, results */
00109 /*  may correspond to a matrix modified by perturbations of size near */
00110 /*  the underflow threshold. */
00111 
00112 /* ===================================================================== */
00113 
00114 /*     .. Parameters .. */
00115 /*     .. */
00116 /*     .. Local Scalars .. */
00117 /*     .. */
00118 /*     .. Intrinsic Functions .. */
00119 /*     .. */
00120 /*     .. External Functions .. */
00121 /*     .. */
00122 /*     .. Executable Statements .. */
00123 
00124     ft = *f;
00125     fa = abs(ft);
00126     ht = *h__;
00127     ha = abs(*h__);
00128 
00129 /*     PMAX points to the maximum absolute element of matrix */
00130 /*       PMAX = 1 if F largest in absolute values */
00131 /*       PMAX = 2 if G largest in absolute values */
00132 /*       PMAX = 3 if H largest in absolute values */
00133 
00134     pmax = 1;
00135     swap = ha > fa;
00136     if (swap) {
00137         pmax = 3;
00138         temp = ft;
00139         ft = ht;
00140         ht = temp;
00141         temp = fa;
00142         fa = ha;
00143         ha = temp;
00144 
00145 /*        Now FA .ge. HA */
00146 
00147     }
00148     gt = *g;
00149     ga = abs(gt);
00150     if (ga == 0.) {
00151 
00152 /*        Diagonal matrix */
00153 
00154         *ssmin = ha;
00155         *ssmax = fa;
00156         clt = 1.;
00157         crt = 1.;
00158         slt = 0.;
00159         srt = 0.;
00160     } else {
00161         gasmal = TRUE_;
00162         if (ga > fa) {
00163             pmax = 2;
00164             if (fa / ga < dlamch_("EPS")) {
00165 
00166 /*              Case of very large GA */
00167 
00168                 gasmal = FALSE_;
00169                 *ssmax = ga;
00170                 if (ha > 1.) {
00171                     *ssmin = fa / (ga / ha);
00172                 } else {
00173                     *ssmin = fa / ga * ha;
00174                 }
00175                 clt = 1.;
00176                 slt = ht / gt;
00177                 srt = 1.;
00178                 crt = ft / gt;
00179             }
00180         }
00181         if (gasmal) {
00182 
00183 /*           Normal case */
00184 
00185             d__ = fa - ha;
00186             if (d__ == fa) {
00187 
00188 /*              Copes with infinite F or H */
00189 
00190                 l = 1.;
00191             } else {
00192                 l = d__ / fa;
00193             }
00194 
00195 /*           Note that 0 .le. L .le. 1 */
00196 
00197             m = gt / ft;
00198 
00199 /*           Note that abs(M) .le. 1/macheps */
00200 
00201             t = 2. - l;
00202 
00203 /*           Note that T .ge. 1 */
00204 
00205             mm = m * m;
00206             tt = t * t;
00207             s = sqrt(tt + mm);
00208 
00209 /*           Note that 1 .le. S .le. 1 + 1/macheps */
00210 
00211             if (l == 0.) {
00212                 r__ = abs(m);
00213             } else {
00214                 r__ = sqrt(l * l + mm);
00215             }
00216 
00217 /*           Note that 0 .le. R .le. 1 + 1/macheps */
00218 
00219             a = (s + r__) * .5;
00220 
00221 /*           Note that 1 .le. A .le. 1 + abs(M) */
00222 
00223             *ssmin = ha / a;
00224             *ssmax = fa * a;
00225             if (mm == 0.) {
00226 
00227 /*              Note that M is very tiny */
00228 
00229                 if (l == 0.) {
00230                     t = d_sign(&c_b3, &ft) * d_sign(&c_b4, &gt);
00231                 } else {
00232                     t = gt / d_sign(&d__, &ft) + m / t;
00233                 }
00234             } else {
00235                 t = (m / (s + t) + m / (r__ + l)) * (a + 1.);
00236             }
00237             l = sqrt(t * t + 4.);
00238             crt = 2. / l;
00239             srt = t / l;
00240             clt = (crt + srt * m) / a;
00241             slt = ht / ft * srt / a;
00242         }
00243     }
00244     if (swap) {
00245         *csl = srt;
00246         *snl = crt;
00247         *csr = slt;
00248         *snr = clt;
00249     } else {
00250         *csl = clt;
00251         *snl = slt;
00252         *csr = crt;
00253         *snr = srt;
00254     }
00255 
00256 /*     Correct signs of SSMAX and SSMIN */
00257 
00258     if (pmax == 1) {
00259         tsign = d_sign(&c_b4, csr) * d_sign(&c_b4, csl) * d_sign(&c_b4, f);
00260     }
00261     if (pmax == 2) {
00262         tsign = d_sign(&c_b4, snr) * d_sign(&c_b4, csl) * d_sign(&c_b4, g);
00263     }
00264     if (pmax == 3) {
00265         tsign = d_sign(&c_b4, snr) * d_sign(&c_b4, snl) * d_sign(&c_b4, h__);
00266     }
00267     *ssmax = d_sign(ssmax, &tsign);
00268     d__1 = tsign * d_sign(&c_b4, f) * d_sign(&c_b4, h__);
00269     *ssmin = d_sign(ssmin, &d__1);
00270     return 0;
00271 
00272 /*     End of DLASV2 */
00273 
00274 } /* dlasv2_ */


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