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


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