📄 slasv2.c
字号:
/* lapack/single/slasv2.f -- translated by f2c (version 20050501).
You must link the resulting object file with libf2c:
on Microsoft Windows system, link with libf2c.lib;
on Linux or Unix systems, link with .../path/to/libf2c.a -lm
or, if you install libf2c.a in a standard place, with -lf2c -lm
-- in that order, at the end of the command line, as in
cc *.o -lf2c -lm
Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
http://www.netlib.org/f2c/libf2c.zip
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "v3p_netlib.h"
/* Table of constant values */
static real c_b3 = (float)2.;
static real c_b4 = (float)1.;
/*< SUBROUTINE SLASV2( F, G, H, SSMIN, SSMAX, SNR, CSR, SNL, CSL ) >*/
/* Subroutine */ int slasv2_(real *f, real *g, real *h__, real *ssmin, real *
ssmax, real *snr, real *csr, real *snl, real *csl)
{
/* System generated locals */
real r__1;
/* Builtin functions */
double sqrt(doublereal), r_sign(real *, real *);
/* Local variables */
real a, d__, l, m, r__, s, t, fa, ga, ha, ft, gt, ht, mm, tt, clt=0, crt=0,
slt=0, srt=0;
integer pmax;
real temp;
logical swap;
real tsign;
logical gasmal;
extern doublereal slamch_(char *, ftnlen);
/* -- LAPACK auxiliary routine (version 3.0) -- */
/* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */
/* Courant Institute, Argonne National Lab, and Rice University */
/* October 31, 1992 */
/* .. Scalar Arguments .. */
/*< REAL CSL, CSR, F, G, H, SNL, SNR, SSMAX, SSMIN >*/
/* .. */
/* Purpose */
/* ======= */
/* SLASV2 computes the singular value decomposition of a 2-by-2 */
/* triangular matrix */
/* [ F G ] */
/* [ 0 H ]. */
/* On return, abs(SSMAX) is the larger singular value, abs(SSMIN) is the */
/* smaller singular value, and (CSL,SNL) and (CSR,SNR) are the left and */
/* right singular vectors for abs(SSMAX), giving the decomposition */
/* [ CSL SNL ] [ F G ] [ CSR -SNR ] = [ SSMAX 0 ] */
/* [-SNL CSL ] [ 0 H ] [ SNR CSR ] [ 0 SSMIN ]. */
/* Arguments */
/* ========= */
/* F (input) REAL */
/* The (1,1) element of the 2-by-2 matrix. */
/* G (input) REAL */
/* The (1,2) element of the 2-by-2 matrix. */
/* H (input) REAL */
/* The (2,2) element of the 2-by-2 matrix. */
/* SSMIN (output) REAL */
/* abs(SSMIN) is the smaller singular value. */
/* SSMAX (output) REAL */
/* abs(SSMAX) is the larger singular value. */
/* SNL (output) REAL */
/* CSL (output) REAL */
/* The vector (CSL, SNL) is a unit left singular vector for the */
/* singular value abs(SSMAX). */
/* SNR (output) REAL */
/* CSR (output) REAL */
/* The vector (CSR, SNR) is a unit right singular vector for the */
/* singular value abs(SSMAX). */
/* Further Details */
/* =============== */
/* Any input parameter may be aliased with any output parameter. */
/* Barring over/underflow and assuming a guard digit in subtraction, all */
/* output quantities are correct to within a few units in the last */
/* place (ulps). */
/* In IEEE arithmetic, the code works correctly if one matrix element is */
/* infinite. */
/* Overflow will not occur unless the largest singular value itself */
/* overflows or is within a few ulps of overflow. (On machines with */
/* partial overflow, like the Cray, overflow may occur if the largest */
/* singular value is within a factor of 2 of overflow.) */
/* Underflow is harmless if underflow is gradual. Otherwise, results */
/* may correspond to a matrix modified by perturbations of size near */
/* the underflow threshold. */
/* ===================================================================== */
/* .. Parameters .. */
/*< REAL ZERO >*/
/*< PARAMETER ( ZERO = 0.0E0 ) >*/
/*< REAL HALF >*/
/*< PARAMETER ( HALF = 0.5E0 ) >*/
/*< REAL ONE >*/
/*< PARAMETER ( ONE = 1.0E0 ) >*/
/*< REAL TWO >*/
/*< PARAMETER ( TWO = 2.0E0 ) >*/
/*< REAL FOUR >*/
/*< PARAMETER ( FOUR = 4.0E0 ) >*/
/* .. */
/* .. Local Scalars .. */
/*< LOGICAL GASMAL, SWAP >*/
/*< INTEGER PMAX >*/
/*< >*/
/* .. */
/* .. Intrinsic Functions .. */
/*< INTRINSIC ABS, SIGN, SQRT >*/
/* .. */
/* .. External Functions .. */
/*< REAL SLAMCH >*/
/*< EXTERNAL SLAMCH >*/
/* .. */
/* .. Executable Statements .. */
/*< FT = F >*/
ft = *f;
/*< FA = ABS( FT ) >*/
fa = dabs(ft);
/*< HT = H >*/
ht = *h__;
/*< HA = ABS( H ) >*/
ha = dabs(*h__);
/* PMAX points to the maximum absolute element of matrix */
/* PMAX = 1 if F largest in absolute values */
/* PMAX = 2 if G largest in absolute values */
/* PMAX = 3 if H largest in absolute values */
/*< PMAX = 1 >*/
pmax = 1;
/*< SWAP = ( HA.GT.FA ) >*/
swap = ha > fa;
/*< IF( SWAP ) THEN >*/
if (swap) {
/*< PMAX = 3 >*/
pmax = 3;
/*< TEMP = FT >*/
temp = ft;
/*< FT = HT >*/
ft = ht;
/*< HT = TEMP >*/
ht = temp;
/*< TEMP = FA >*/
temp = fa;
/*< FA = HA >*/
fa = ha;
/*< HA = TEMP >*/
ha = temp;
/* Now FA .ge. HA */
/*< END IF >*/
}
/*< GT = G >*/
gt = *g;
/*< GA = ABS( GT ) >*/
ga = dabs(gt);
/*< IF( GA.EQ.ZERO ) THEN >*/
if (ga == (float)0.) {
/* Diagonal matrix */
/*< SSMIN = HA >*/
*ssmin = ha;
/*< SSMAX = FA >*/
*ssmax = fa;
/*< CLT = ONE >*/
clt = (float)1.;
/*< CRT = ONE >*/
crt = (float)1.;
/*< SLT = ZERO >*/
slt = (float)0.;
/*< SRT = ZERO >*/
srt = (float)0.;
/*< ELSE >*/
} else {
/*< GASMAL = .TRUE. >*/
gasmal = TRUE_;
/*< IF( GA.GT.FA ) THEN >*/
if (ga > fa) {
/*< PMAX = 2 >*/
pmax = 2;
/*< IF( ( FA / GA ).LT.SLAMCH( 'EPS' ) ) THEN >*/
if (fa / ga < slamch_("EPS", (ftnlen)3)) {
/* Case of very large GA */
/*< GASMAL = .FALSE. >*/
gasmal = FALSE_;
/*< SSMAX = GA >*/
*ssmax = ga;
/*< IF( HA.GT.ONE ) THEN >*/
if (ha > (float)1.) {
/*< SSMIN = FA / ( GA / HA ) >*/
*ssmin = fa / (ga / ha);
/*< ELSE >*/
} else {
/*< SSMIN = ( FA / GA )*HA >*/
*ssmin = fa / ga * ha;
/*< END IF >*/
}
/*< CLT = ONE >*/
clt = (float)1.;
/*< SLT = HT / GT >*/
slt = ht / gt;
/*< SRT = ONE >*/
srt = (float)1.;
/*< CRT = FT / GT >*/
crt = ft / gt;
/*< END IF >*/
}
/*< END IF >*/
}
/*< IF( GASMAL ) THEN >*/
if (gasmal) {
/* Normal case */
/*< D = FA - HA >*/
d__ = fa - ha;
/*< IF( D.EQ.FA ) THEN >*/
if (d__ == fa) {
/* Copes with infinite F or H */
/*< L = ONE >*/
l = (float)1.;
/*< ELSE >*/
} else {
/*< L = D / FA >*/
l = d__ / fa;
/*< END IF >*/
}
/* Note that 0 .le. L .le. 1 */
/*< M = GT / FT >*/
m = gt / ft;
/* Note that abs(M) .le. 1/macheps */
/*< T = TWO - L >*/
t = (float)2. - l;
/* Note that T .ge. 1 */
/*< MM = M*M >*/
mm = m * m;
/*< TT = T*T >*/
tt = t * t;
/*< S = SQRT( TT+MM ) >*/
s = sqrt(tt + mm);
/* Note that 1 .le. S .le. 1 + 1/macheps */
/*< IF( L.EQ.ZERO ) THEN >*/
if (l == (float)0.) {
/*< R = ABS( M ) >*/
r__ = dabs(m);
/*< ELSE >*/
} else {
/*< R = SQRT( L*L+MM ) >*/
r__ = sqrt(l * l + mm);
/*< END IF >*/
}
/* Note that 0 .le. R .le. 1 + 1/macheps */
/*< A = HALF*( S+R ) >*/
a = (s + r__) * (float).5;
/* Note that 1 .le. A .le. 1 + abs(M) */
/*< SSMIN = HA / A >*/
*ssmin = ha / a;
/*< SSMAX = FA*A >*/
*ssmax = fa * a;
/*< IF( MM.EQ.ZERO ) THEN >*/
if (mm == (float)0.) {
/* Note that M is very tiny */
/*< IF( L.EQ.ZERO ) THEN >*/
if (l == (float)0.) {
/*< T = SIGN( TWO, FT )*SIGN( ONE, GT ) >*/
t = r_sign(&c_b3, &ft) * r_sign(&c_b4, >);
/*< ELSE >*/
} else {
/*< T = GT / SIGN( D, FT ) + M / T >*/
t = gt / r_sign(&d__, &ft) + m / t;
/*< END IF >*/
}
/*< ELSE >*/
} else {
/*< T = ( M / ( S+T )+M / ( R+L ) )*( ONE+A ) >*/
t = (m / (s + t) + m / (r__ + l)) * (a + (float)1.);
/*< END IF >*/
}
/*< L = SQRT( T*T+FOUR ) >*/
l = sqrt(t * t + (float)4.);
/*< CRT = TWO / L >*/
crt = (float)2. / l;
/*< SRT = T / L >*/
srt = t / l;
/*< CLT = ( CRT+SRT*M ) / A >*/
clt = (crt + srt * m) / a;
/*< SLT = ( HT / FT )*SRT / A >*/
slt = ht / ft * srt / a;
/*< END IF >*/
}
/*< END IF >*/
}
/*< IF( SWAP ) THEN >*/
if (swap) {
/*< CSL = SRT >*/
*csl = srt;
/*< SNL = CRT >*/
*snl = crt;
/*< CSR = SLT >*/
*csr = slt;
/*< SNR = CLT >*/
*snr = clt;
/*< ELSE >*/
} else {
/*< CSL = CLT >*/
*csl = clt;
/*< SNL = SLT >*/
*snl = slt;
/*< CSR = CRT >*/
*csr = crt;
/*< SNR = SRT >*/
*snr = srt;
/*< END IF >*/
}
/* Correct signs of SSMAX and SSMIN */
/*< >*/
if (pmax == 1) {
tsign = r_sign(&c_b4, csr) * r_sign(&c_b4, csl) * r_sign(&c_b4, f);
}
/*< >*/
if (pmax == 2) {
tsign = r_sign(&c_b4, snr) * r_sign(&c_b4, csl) * r_sign(&c_b4, g);
}
/*< >*/
if (pmax == 3) {
tsign = r_sign(&c_b4, snr) * r_sign(&c_b4, snl) * r_sign(&c_b4, h__);
}
/*< SSMAX = SIGN( SSMAX, TSIGN ) >*/
*ssmax = r_sign(ssmax, &tsign);
/*< SSMIN = SIGN( SSMIN, TSIGN*SIGN( ONE, F )*SIGN( ONE, H ) ) >*/
r__1 = tsign * r_sign(&c_b4, f) * r_sign(&c_b4, h__);
*ssmin = r_sign(ssmin, &r__1);
/*< RETURN >*/
return 0;
/* End of SLASV2 */
/*< END >*/
} /* slasv2_ */
#ifdef __cplusplus
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -