slagv2.c
Go to the documentation of this file.
00001 /* slagv2.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 integer c__2 = 2;
00019 static integer c__1 = 1;
00020 
00021 /* Subroutine */ int slagv2_(real *a, integer *lda, real *b, integer *ldb, 
00022         real *alphar, real *alphai, real *beta, real *csl, real *snl, real *
00023         csr, real *snr)
00024 {
00025     /* System generated locals */
00026     integer a_dim1, a_offset, b_dim1, b_offset;
00027     real r__1, r__2, r__3, r__4, r__5, r__6;
00028 
00029     /* Local variables */
00030     real r__, t, h1, h2, h3, wi, qq, rr, wr1, wr2, ulp;
00031     extern /* Subroutine */ int srot_(integer *, real *, integer *, real *, 
00032             integer *, real *, real *), slag2_(real *, integer *, real *, 
00033             integer *, real *, real *, real *, real *, real *, real *);
00034     real anorm, bnorm, scale1, scale2;
00035     extern /* Subroutine */ int slasv2_(real *, real *, real *, real *, real *
00036 , real *, real *, real *, real *);
00037     extern doublereal slapy2_(real *, real *);
00038     real ascale, bscale;
00039     extern doublereal slamch_(char *);
00040     real safmin;
00041     extern /* Subroutine */ int slartg_(real *, real *, real *, real *, real *
00042 );
00043 
00044 
00045 /*  -- LAPACK auxiliary routine (version 3.2) -- */
00046 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00047 /*     November 2006 */
00048 
00049 /*     .. Scalar Arguments .. */
00050 /*     .. */
00051 /*     .. Array Arguments .. */
00052 /*     .. */
00053 
00054 /*  Purpose */
00055 /*  ======= */
00056 
00057 /*  SLAGV2 computes the Generalized Schur factorization of a real 2-by-2 */
00058 /*  matrix pencil (A,B) where B is upper triangular. This routine */
00059 /*  computes orthogonal (rotation) matrices given by CSL, SNL and CSR, */
00060 /*  SNR such that */
00061 
00062 /*  1) if the pencil (A,B) has two real eigenvalues (include 0/0 or 1/0 */
00063 /*     types), then */
00064 
00065 /*     [ a11 a12 ] := [  CSL  SNL ] [ a11 a12 ] [  CSR -SNR ] */
00066 /*     [  0  a22 ]    [ -SNL  CSL ] [ a21 a22 ] [  SNR  CSR ] */
00067 
00068 /*     [ b11 b12 ] := [  CSL  SNL ] [ b11 b12 ] [  CSR -SNR ] */
00069 /*     [  0  b22 ]    [ -SNL  CSL ] [  0  b22 ] [  SNR  CSR ], */
00070 
00071 /*  2) if the pencil (A,B) has a pair of complex conjugate eigenvalues, */
00072 /*     then */
00073 
00074 /*     [ a11 a12 ] := [  CSL  SNL ] [ a11 a12 ] [  CSR -SNR ] */
00075 /*     [ a21 a22 ]    [ -SNL  CSL ] [ a21 a22 ] [  SNR  CSR ] */
00076 
00077 /*     [ b11  0  ] := [  CSL  SNL ] [ b11 b12 ] [  CSR -SNR ] */
00078 /*     [  0  b22 ]    [ -SNL  CSL ] [  0  b22 ] [  SNR  CSR ] */
00079 
00080 /*     where b11 >= b22 > 0. */
00081 
00082 
00083 /*  Arguments */
00084 /*  ========= */
00085 
00086 /*  A       (input/output) REAL array, dimension (LDA, 2) */
00087 /*          On entry, the 2 x 2 matrix A. */
00088 /*          On exit, A is overwritten by the ``A-part'' of the */
00089 /*          generalized Schur form. */
00090 
00091 /*  LDA     (input) INTEGER */
00092 /*          THe leading dimension of the array A.  LDA >= 2. */
00093 
00094 /*  B       (input/output) REAL array, dimension (LDB, 2) */
00095 /*          On entry, the upper triangular 2 x 2 matrix B. */
00096 /*          On exit, B is overwritten by the ``B-part'' of the */
00097 /*          generalized Schur form. */
00098 
00099 /*  LDB     (input) INTEGER */
00100 /*          THe leading dimension of the array B.  LDB >= 2. */
00101 
00102 /*  ALPHAR  (output) REAL array, dimension (2) */
00103 /*  ALPHAI  (output) REAL array, dimension (2) */
00104 /*  BETA    (output) REAL array, dimension (2) */
00105 /*          (ALPHAR(k)+i*ALPHAI(k))/BETA(k) are the eigenvalues of the */
00106 /*          pencil (A,B), k=1,2, i = sqrt(-1).  Note that BETA(k) may */
00107 /*          be zero. */
00108 
00109 /*  CSL     (output) REAL */
00110 /*          The cosine of the left rotation matrix. */
00111 
00112 /*  SNL     (output) REAL */
00113 /*          The sine of the left rotation matrix. */
00114 
00115 /*  CSR     (output) REAL */
00116 /*          The cosine of the right rotation matrix. */
00117 
00118 /*  SNR     (output) REAL */
00119 /*          The sine of the right rotation matrix. */
00120 
00121 /*  Further Details */
00122 /*  =============== */
00123 
00124 /*  Based on contributions by */
00125 /*     Mark Fahey, Department of Mathematics, Univ. of Kentucky, USA */
00126 
00127 /*  ===================================================================== */
00128 
00129 /*     .. Parameters .. */
00130 /*     .. */
00131 /*     .. Local Scalars .. */
00132 /*     .. */
00133 /*     .. External Subroutines .. */
00134 /*     .. */
00135 /*     .. External Functions .. */
00136 /*     .. */
00137 /*     .. Intrinsic Functions .. */
00138 /*     .. */
00139 /*     .. Executable Statements .. */
00140 
00141     /* Parameter adjustments */
00142     a_dim1 = *lda;
00143     a_offset = 1 + a_dim1;
00144     a -= a_offset;
00145     b_dim1 = *ldb;
00146     b_offset = 1 + b_dim1;
00147     b -= b_offset;
00148     --alphar;
00149     --alphai;
00150     --beta;
00151 
00152     /* Function Body */
00153     safmin = slamch_("S");
00154     ulp = slamch_("P");
00155 
00156 /*     Scale A */
00157 
00158 /* Computing MAX */
00159     r__5 = (r__1 = a[a_dim1 + 1], dabs(r__1)) + (r__2 = a[a_dim1 + 2], dabs(
00160             r__2)), r__6 = (r__3 = a[(a_dim1 << 1) + 1], dabs(r__3)) + (r__4 =
00161              a[(a_dim1 << 1) + 2], dabs(r__4)), r__5 = max(r__5,r__6);
00162     anorm = dmax(r__5,safmin);
00163     ascale = 1.f / anorm;
00164     a[a_dim1 + 1] = ascale * a[a_dim1 + 1];
00165     a[(a_dim1 << 1) + 1] = ascale * a[(a_dim1 << 1) + 1];
00166     a[a_dim1 + 2] = ascale * a[a_dim1 + 2];
00167     a[(a_dim1 << 1) + 2] = ascale * a[(a_dim1 << 1) + 2];
00168 
00169 /*     Scale B */
00170 
00171 /* Computing MAX */
00172     r__4 = (r__3 = b[b_dim1 + 1], dabs(r__3)), r__5 = (r__1 = b[(b_dim1 << 1) 
00173             + 1], dabs(r__1)) + (r__2 = b[(b_dim1 << 1) + 2], dabs(r__2)), 
00174             r__4 = max(r__4,r__5);
00175     bnorm = dmax(r__4,safmin);
00176     bscale = 1.f / bnorm;
00177     b[b_dim1 + 1] = bscale * b[b_dim1 + 1];
00178     b[(b_dim1 << 1) + 1] = bscale * b[(b_dim1 << 1) + 1];
00179     b[(b_dim1 << 1) + 2] = bscale * b[(b_dim1 << 1) + 2];
00180 
00181 /*     Check if A can be deflated */
00182 
00183     if ((r__1 = a[a_dim1 + 2], dabs(r__1)) <= ulp) {
00184         *csl = 1.f;
00185         *snl = 0.f;
00186         *csr = 1.f;
00187         *snr = 0.f;
00188         a[a_dim1 + 2] = 0.f;
00189         b[b_dim1 + 2] = 0.f;
00190 
00191 /*     Check if B is singular */
00192 
00193     } else if ((r__1 = b[b_dim1 + 1], dabs(r__1)) <= ulp) {
00194         slartg_(&a[a_dim1 + 1], &a[a_dim1 + 2], csl, snl, &r__);
00195         *csr = 1.f;
00196         *snr = 0.f;
00197         srot_(&c__2, &a[a_dim1 + 1], lda, &a[a_dim1 + 2], lda, csl, snl);
00198         srot_(&c__2, &b[b_dim1 + 1], ldb, &b[b_dim1 + 2], ldb, csl, snl);
00199         a[a_dim1 + 2] = 0.f;
00200         b[b_dim1 + 1] = 0.f;
00201         b[b_dim1 + 2] = 0.f;
00202 
00203     } else if ((r__1 = b[(b_dim1 << 1) + 2], dabs(r__1)) <= ulp) {
00204         slartg_(&a[(a_dim1 << 1) + 2], &a[a_dim1 + 2], csr, snr, &t);
00205         *snr = -(*snr);
00206         srot_(&c__2, &a[a_dim1 + 1], &c__1, &a[(a_dim1 << 1) + 1], &c__1, csr, 
00207                  snr);
00208         srot_(&c__2, &b[b_dim1 + 1], &c__1, &b[(b_dim1 << 1) + 1], &c__1, csr, 
00209                  snr);
00210         *csl = 1.f;
00211         *snl = 0.f;
00212         a[a_dim1 + 2] = 0.f;
00213         b[b_dim1 + 2] = 0.f;
00214         b[(b_dim1 << 1) + 2] = 0.f;
00215 
00216     } else {
00217 
00218 /*        B is nonsingular, first compute the eigenvalues of (A,B) */
00219 
00220         slag2_(&a[a_offset], lda, &b[b_offset], ldb, &safmin, &scale1, &
00221                 scale2, &wr1, &wr2, &wi);
00222 
00223         if (wi == 0.f) {
00224 
00225 /*           two real eigenvalues, compute s*A-w*B */
00226 
00227             h1 = scale1 * a[a_dim1 + 1] - wr1 * b[b_dim1 + 1];
00228             h2 = scale1 * a[(a_dim1 << 1) + 1] - wr1 * b[(b_dim1 << 1) + 1];
00229             h3 = scale1 * a[(a_dim1 << 1) + 2] - wr1 * b[(b_dim1 << 1) + 2];
00230 
00231             rr = slapy2_(&h1, &h2);
00232             r__1 = scale1 * a[a_dim1 + 2];
00233             qq = slapy2_(&r__1, &h3);
00234 
00235             if (rr > qq) {
00236 
00237 /*              find right rotation matrix to zero 1,1 element of */
00238 /*              (sA - wB) */
00239 
00240                 slartg_(&h2, &h1, csr, snr, &t);
00241 
00242             } else {
00243 
00244 /*              find right rotation matrix to zero 2,1 element of */
00245 /*              (sA - wB) */
00246 
00247                 r__1 = scale1 * a[a_dim1 + 2];
00248                 slartg_(&h3, &r__1, csr, snr, &t);
00249 
00250             }
00251 
00252             *snr = -(*snr);
00253             srot_(&c__2, &a[a_dim1 + 1], &c__1, &a[(a_dim1 << 1) + 1], &c__1, 
00254                     csr, snr);
00255             srot_(&c__2, &b[b_dim1 + 1], &c__1, &b[(b_dim1 << 1) + 1], &c__1, 
00256                     csr, snr);
00257 
00258 /*           compute inf norms of A and B */
00259 
00260 /* Computing MAX */
00261             r__5 = (r__1 = a[a_dim1 + 1], dabs(r__1)) + (r__2 = a[(a_dim1 << 
00262                     1) + 1], dabs(r__2)), r__6 = (r__3 = a[a_dim1 + 2], dabs(
00263                     r__3)) + (r__4 = a[(a_dim1 << 1) + 2], dabs(r__4));
00264             h1 = dmax(r__5,r__6);
00265 /* Computing MAX */
00266             r__5 = (r__1 = b[b_dim1 + 1], dabs(r__1)) + (r__2 = b[(b_dim1 << 
00267                     1) + 1], dabs(r__2)), r__6 = (r__3 = b[b_dim1 + 2], dabs(
00268                     r__3)) + (r__4 = b[(b_dim1 << 1) + 2], dabs(r__4));
00269             h2 = dmax(r__5,r__6);
00270 
00271             if (scale1 * h1 >= dabs(wr1) * h2) {
00272 
00273 /*              find left rotation matrix Q to zero out B(2,1) */
00274 
00275                 slartg_(&b[b_dim1 + 1], &b[b_dim1 + 2], csl, snl, &r__);
00276 
00277             } else {
00278 
00279 /*              find left rotation matrix Q to zero out A(2,1) */
00280 
00281                 slartg_(&a[a_dim1 + 1], &a[a_dim1 + 2], csl, snl, &r__);
00282 
00283             }
00284 
00285             srot_(&c__2, &a[a_dim1 + 1], lda, &a[a_dim1 + 2], lda, csl, snl);
00286             srot_(&c__2, &b[b_dim1 + 1], ldb, &b[b_dim1 + 2], ldb, csl, snl);
00287 
00288             a[a_dim1 + 2] = 0.f;
00289             b[b_dim1 + 2] = 0.f;
00290 
00291         } else {
00292 
00293 /*           a pair of complex conjugate eigenvalues */
00294 /*           first compute the SVD of the matrix B */
00295 
00296             slasv2_(&b[b_dim1 + 1], &b[(b_dim1 << 1) + 1], &b[(b_dim1 << 1) + 
00297                     2], &r__, &t, snr, csr, snl, csl);
00298 
00299 /*           Form (A,B) := Q(A,B)Z' where Q is left rotation matrix and */
00300 /*           Z is right rotation matrix computed from SLASV2 */
00301 
00302             srot_(&c__2, &a[a_dim1 + 1], lda, &a[a_dim1 + 2], lda, csl, snl);
00303             srot_(&c__2, &b[b_dim1 + 1], ldb, &b[b_dim1 + 2], ldb, csl, snl);
00304             srot_(&c__2, &a[a_dim1 + 1], &c__1, &a[(a_dim1 << 1) + 1], &c__1, 
00305                     csr, snr);
00306             srot_(&c__2, &b[b_dim1 + 1], &c__1, &b[(b_dim1 << 1) + 1], &c__1, 
00307                     csr, snr);
00308 
00309             b[b_dim1 + 2] = 0.f;
00310             b[(b_dim1 << 1) + 1] = 0.f;
00311 
00312         }
00313 
00314     }
00315 
00316 /*     Unscaling */
00317 
00318     a[a_dim1 + 1] = anorm * a[a_dim1 + 1];
00319     a[a_dim1 + 2] = anorm * a[a_dim1 + 2];
00320     a[(a_dim1 << 1) + 1] = anorm * a[(a_dim1 << 1) + 1];
00321     a[(a_dim1 << 1) + 2] = anorm * a[(a_dim1 << 1) + 2];
00322     b[b_dim1 + 1] = bnorm * b[b_dim1 + 1];
00323     b[b_dim1 + 2] = bnorm * b[b_dim1 + 2];
00324     b[(b_dim1 << 1) + 1] = bnorm * b[(b_dim1 << 1) + 1];
00325     b[(b_dim1 << 1) + 2] = bnorm * b[(b_dim1 << 1) + 2];
00326 
00327     if (wi == 0.f) {
00328         alphar[1] = a[a_dim1 + 1];
00329         alphar[2] = a[(a_dim1 << 1) + 2];
00330         alphai[1] = 0.f;
00331         alphai[2] = 0.f;
00332         beta[1] = b[b_dim1 + 1];
00333         beta[2] = b[(b_dim1 << 1) + 2];
00334     } else {
00335         alphar[1] = anorm * wr1 / scale1 / bnorm;
00336         alphai[1] = anorm * wi / scale1 / bnorm;
00337         alphar[2] = alphar[1];
00338         alphai[2] = -alphai[1];
00339         beta[1] = 1.f;
00340         beta[2] = 1.f;
00341     }
00342 
00343     return 0;
00344 
00345 /*     End of SLAGV2 */
00346 
00347 } /* slagv2_ */


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