3 /* Table of constant values */
5 static doublereal c_b3 = 2.;
6 static doublereal c_b4 = 1.;
8 /* Subroutine */ int dlasv2_(doublereal *f, doublereal *g, doublereal *h__,
9 doublereal *ssmin, doublereal *ssmax, doublereal *snr, doublereal *
10 csr, doublereal *snl, doublereal *csl)
12 /* System generated locals */
15 /* Builtin functions */
16 double sqrt(doublereal), d_sign(doublereal *, doublereal *);
19 doublereal a, d__, l, m, r__, s, t, fa, ga, ha, ft, gt, ht, mm, tt, clt,
25 extern doublereal dlamch_(char *);
29 /* -- LAPACK auxiliary routine (version 3.1) -- */
30 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
33 /* .. Scalar Arguments .. */
39 /* DLASV2 computes the singular value decomposition of a 2-by-2 */
40 /* triangular matrix */
43 /* On return, abs(SSMAX) is the larger singular value, abs(SSMIN) is the */
44 /* smaller singular value, and (CSL,SNL) and (CSR,SNR) are the left and */
45 /* right singular vectors for abs(SSMAX), giving the decomposition */
47 /* [ CSL SNL ] [ F G ] [ CSR -SNR ] = [ SSMAX 0 ] */
48 /* [-SNL CSL ] [ 0 H ] [ SNR CSR ] [ 0 SSMIN ]. */
53 /* F (input) DOUBLE PRECISION */
54 /* The (1,1) element of the 2-by-2 matrix. */
56 /* G (input) DOUBLE PRECISION */
57 /* The (1,2) element of the 2-by-2 matrix. */
59 /* H (input) DOUBLE PRECISION */
60 /* The (2,2) element of the 2-by-2 matrix. */
62 /* SSMIN (output) DOUBLE PRECISION */
63 /* abs(SSMIN) is the smaller singular value. */
65 /* SSMAX (output) DOUBLE PRECISION */
66 /* abs(SSMAX) is the larger singular value. */
68 /* SNL (output) DOUBLE PRECISION */
69 /* CSL (output) DOUBLE PRECISION */
70 /* The vector (CSL, SNL) is a unit left singular vector for the */
71 /* singular value abs(SSMAX). */
73 /* SNR (output) DOUBLE PRECISION */
74 /* CSR (output) DOUBLE PRECISION */
75 /* The vector (CSR, SNR) is a unit right singular vector for the */
76 /* singular value abs(SSMAX). */
81 /* Any input parameter may be aliased with any output parameter. */
83 /* Barring over/underflow and assuming a guard digit in subtraction, all */
84 /* output quantities are correct to within a few units in the last */
87 /* In IEEE arithmetic, the code works correctly if one matrix element is */
90 /* Overflow will not occur unless the largest singular value itself */
91 /* overflows or is within a few ulps of overflow. (On machines with */
92 /* partial overflow, like the Cray, overflow may occur if the largest */
93 /* singular value is within a factor of 2 of overflow.) */
95 /* Underflow is harmless if underflow is gradual. Otherwise, results */
96 /* may correspond to a matrix modified by perturbations of size near */
97 /* the underflow threshold. */
99 /* ===================================================================== */
101 /* .. Parameters .. */
103 /* .. Local Scalars .. */
105 /* .. Intrinsic Functions .. */
107 /* .. External Functions .. */
109 /* .. Executable Statements .. */
116 /* PMAX points to the maximum absolute element of matrix */
117 /* PMAX = 1 if F largest in absolute values */
118 /* PMAX = 2 if G largest in absolute values */
119 /* PMAX = 3 if H largest in absolute values */
139 /* Diagonal matrix */
151 if (fa / ga < dlamch_("EPS")) {
153 /* Case of very large GA */
158 *ssmin = fa / (ga / ha);
160 *ssmin = fa / ga * ha;
175 /* Copes with infinite F or H */
182 /* Note that 0 .le. L .le. 1 */
186 /* Note that abs(M) .le. 1/macheps */
190 /* Note that T .ge. 1 */
196 /* Note that 1 .le. S .le. 1 + 1/macheps */
201 r__ = sqrt(l * l + mm);
204 /* Note that 0 .le. R .le. 1 + 1/macheps */
208 /* Note that 1 .le. A .le. 1 + abs(M) */
214 /* Note that M is very tiny */
217 t = d_sign(&c_b3, &ft) * d_sign(&c_b4, >);
219 t = gt / d_sign(&d__, &ft) + m / t;
222 t = (m / (s + t) + m / (r__ + l)) * (a + 1.);
224 l = sqrt(t * t + 4.);
227 clt = (crt + srt * m) / a;
228 slt = ht / ft * srt / a;
243 /* Correct signs of SSMAX and SSMIN */
246 tsign = d_sign(&c_b4, csr) * d_sign(&c_b4, csl) * d_sign(&c_b4, f);
249 tsign = d_sign(&c_b4, snr) * d_sign(&c_b4, csl) * d_sign(&c_b4, g);
252 tsign = d_sign(&c_b4, snr) * d_sign(&c_b4, snl) * d_sign(&c_b4, h__);
254 *ssmax = d_sign(ssmax, &tsign);
255 d__1 = tsign * d_sign(&c_b4, f) * d_sign(&c_b4, h__);
256 *ssmin = d_sign(ssmin, &d__1);