slaexc.c
Go to the documentation of this file.
00001 /* slaexc.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__1 = 1;
00019 static integer c__4 = 4;
00020 static logical c_false = FALSE_;
00021 static integer c_n1 = -1;
00022 static integer c__2 = 2;
00023 static integer c__3 = 3;
00024 
00025 /* Subroutine */ int slaexc_(logical *wantq, integer *n, real *t, integer *
00026         ldt, real *q, integer *ldq, integer *j1, integer *n1, integer *n2, 
00027         real *work, integer *info)
00028 {
00029     /* System generated locals */
00030     integer q_dim1, q_offset, t_dim1, t_offset, i__1;
00031     real r__1, r__2, r__3;
00032 
00033     /* Local variables */
00034     real d__[16]        /* was [4][4] */;
00035     integer k;
00036     real u[3], x[4]     /* was [2][2] */;
00037     integer j2, j3, j4;
00038     real u1[3], u2[3];
00039     integer nd;
00040     real cs, t11, t22, t33, sn, wi1, wi2, wr1, wr2, eps, tau, tau1, tau2;
00041     integer ierr;
00042     real temp;
00043     extern /* Subroutine */ int srot_(integer *, real *, integer *, real *, 
00044             integer *, real *, real *);
00045     real scale, dnorm, xnorm;
00046     extern /* Subroutine */ int slanv2_(real *, real *, real *, real *, real *
00047 , real *, real *, real *, real *, real *), slasy2_(logical *, 
00048             logical *, integer *, integer *, integer *, real *, integer *, 
00049             real *, integer *, real *, integer *, real *, real *, integer *, 
00050             real *, integer *);
00051     extern doublereal slamch_(char *), slange_(char *, integer *, 
00052             integer *, real *, integer *, real *);
00053     extern /* Subroutine */ int slarfg_(integer *, real *, real *, integer *, 
00054             real *), slacpy_(char *, integer *, integer *, real *, integer *, 
00055             real *, integer *), slartg_(real *, real *, real *, real *
00056 , real *);
00057     real thresh;
00058     extern /* Subroutine */ int slarfx_(char *, integer *, integer *, real *, 
00059             real *, real *, integer *, real *);
00060     real smlnum;
00061 
00062 
00063 /*  -- LAPACK auxiliary routine (version 3.2) -- */
00064 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00065 /*     November 2006 */
00066 
00067 /*     .. Scalar Arguments .. */
00068 /*     .. */
00069 /*     .. Array Arguments .. */
00070 /*     .. */
00071 
00072 /*  Purpose */
00073 /*  ======= */
00074 
00075 /*  SLAEXC swaps adjacent diagonal blocks T11 and T22 of order 1 or 2 in */
00076 /*  an upper quasi-triangular matrix T by an orthogonal similarity */
00077 /*  transformation. */
00078 
00079 /*  T must be in Schur canonical form, that is, block upper triangular */
00080 /*  with 1-by-1 and 2-by-2 diagonal blocks; each 2-by-2 diagonal block */
00081 /*  has its diagonal elemnts equal and its off-diagonal elements of */
00082 /*  opposite sign. */
00083 
00084 /*  Arguments */
00085 /*  ========= */
00086 
00087 /*  WANTQ   (input) LOGICAL */
00088 /*          = .TRUE. : accumulate the transformation in the matrix Q; */
00089 /*          = .FALSE.: do not accumulate the transformation. */
00090 
00091 /*  N       (input) INTEGER */
00092 /*          The order of the matrix T. N >= 0. */
00093 
00094 /*  T       (input/output) REAL array, dimension (LDT,N) */
00095 /*          On entry, the upper quasi-triangular matrix T, in Schur */
00096 /*          canonical form. */
00097 /*          On exit, the updated matrix T, again in Schur canonical form. */
00098 
00099 /*  LDT     (input)  INTEGER */
00100 /*          The leading dimension of the array T. LDT >= max(1,N). */
00101 
00102 /*  Q       (input/output) REAL array, dimension (LDQ,N) */
00103 /*          On entry, if WANTQ is .TRUE., the orthogonal matrix Q. */
00104 /*          On exit, if WANTQ is .TRUE., the updated matrix Q. */
00105 /*          If WANTQ is .FALSE., Q is not referenced. */
00106 
00107 /*  LDQ     (input) INTEGER */
00108 /*          The leading dimension of the array Q. */
00109 /*          LDQ >= 1; and if WANTQ is .TRUE., LDQ >= N. */
00110 
00111 /*  J1      (input) INTEGER */
00112 /*          The index of the first row of the first block T11. */
00113 
00114 /*  N1      (input) INTEGER */
00115 /*          The order of the first block T11. N1 = 0, 1 or 2. */
00116 
00117 /*  N2      (input) INTEGER */
00118 /*          The order of the second block T22. N2 = 0, 1 or 2. */
00119 
00120 /*  WORK    (workspace) REAL array, dimension (N) */
00121 
00122 /*  INFO    (output) INTEGER */
00123 /*          = 0: successful exit */
00124 /*          = 1: the transformed matrix T would be too far from Schur */
00125 /*               form; the blocks are not swapped and T and Q are */
00126 /*               unchanged. */
00127 
00128 /*  ===================================================================== */
00129 
00130 /*     .. Parameters .. */
00131 /*     .. */
00132 /*     .. Local Scalars .. */
00133 /*     .. */
00134 /*     .. Local Arrays .. */
00135 /*     .. */
00136 /*     .. External Functions .. */
00137 /*     .. */
00138 /*     .. External Subroutines .. */
00139 /*     .. */
00140 /*     .. Intrinsic Functions .. */
00141 /*     .. */
00142 /*     .. Executable Statements .. */
00143 
00144     /* Parameter adjustments */
00145     t_dim1 = *ldt;
00146     t_offset = 1 + t_dim1;
00147     t -= t_offset;
00148     q_dim1 = *ldq;
00149     q_offset = 1 + q_dim1;
00150     q -= q_offset;
00151     --work;
00152 
00153     /* Function Body */
00154     *info = 0;
00155 
00156 /*     Quick return if possible */
00157 
00158     if (*n == 0 || *n1 == 0 || *n2 == 0) {
00159         return 0;
00160     }
00161     if (*j1 + *n1 > *n) {
00162         return 0;
00163     }
00164 
00165     j2 = *j1 + 1;
00166     j3 = *j1 + 2;
00167     j4 = *j1 + 3;
00168 
00169     if (*n1 == 1 && *n2 == 1) {
00170 
00171 /*        Swap two 1-by-1 blocks. */
00172 
00173         t11 = t[*j1 + *j1 * t_dim1];
00174         t22 = t[j2 + j2 * t_dim1];
00175 
00176 /*        Determine the transformation to perform the interchange. */
00177 
00178         r__1 = t22 - t11;
00179         slartg_(&t[*j1 + j2 * t_dim1], &r__1, &cs, &sn, &temp);
00180 
00181 /*        Apply transformation to the matrix T. */
00182 
00183         if (j3 <= *n) {
00184             i__1 = *n - *j1 - 1;
00185             srot_(&i__1, &t[*j1 + j3 * t_dim1], ldt, &t[j2 + j3 * t_dim1], 
00186                     ldt, &cs, &sn);
00187         }
00188         i__1 = *j1 - 1;
00189         srot_(&i__1, &t[*j1 * t_dim1 + 1], &c__1, &t[j2 * t_dim1 + 1], &c__1, 
00190                 &cs, &sn);
00191 
00192         t[*j1 + *j1 * t_dim1] = t22;
00193         t[j2 + j2 * t_dim1] = t11;
00194 
00195         if (*wantq) {
00196 
00197 /*           Accumulate transformation in the matrix Q. */
00198 
00199             srot_(n, &q[*j1 * q_dim1 + 1], &c__1, &q[j2 * q_dim1 + 1], &c__1, 
00200                     &cs, &sn);
00201         }
00202 
00203     } else {
00204 
00205 /*        Swapping involves at least one 2-by-2 block. */
00206 
00207 /*        Copy the diagonal block of order N1+N2 to the local array D */
00208 /*        and compute its norm. */
00209 
00210         nd = *n1 + *n2;
00211         slacpy_("Full", &nd, &nd, &t[*j1 + *j1 * t_dim1], ldt, d__, &c__4);
00212         dnorm = slange_("Max", &nd, &nd, d__, &c__4, &work[1]);
00213 
00214 /*        Compute machine-dependent threshold for test for accepting */
00215 /*        swap. */
00216 
00217         eps = slamch_("P");
00218         smlnum = slamch_("S") / eps;
00219 /* Computing MAX */
00220         r__1 = eps * 10.f * dnorm;
00221         thresh = dmax(r__1,smlnum);
00222 
00223 /*        Solve T11*X - X*T22 = scale*T12 for X. */
00224 
00225         slasy2_(&c_false, &c_false, &c_n1, n1, n2, d__, &c__4, &d__[*n1 + 1 + 
00226                 (*n1 + 1 << 2) - 5], &c__4, &d__[(*n1 + 1 << 2) - 4], &c__4, &
00227                 scale, x, &c__2, &xnorm, &ierr);
00228 
00229 /*        Swap the adjacent diagonal blocks. */
00230 
00231         k = *n1 + *n1 + *n2 - 3;
00232         switch (k) {
00233             case 1:  goto L10;
00234             case 2:  goto L20;
00235             case 3:  goto L30;
00236         }
00237 
00238 L10:
00239 
00240 /*        N1 = 1, N2 = 2: generate elementary reflector H so that: */
00241 
00242 /*        ( scale, X11, X12 ) H = ( 0, 0, * ) */
00243 
00244         u[0] = scale;
00245         u[1] = x[0];
00246         u[2] = x[2];
00247         slarfg_(&c__3, &u[2], u, &c__1, &tau);
00248         u[2] = 1.f;
00249         t11 = t[*j1 + *j1 * t_dim1];
00250 
00251 /*        Perform swap provisionally on diagonal block in D. */
00252 
00253         slarfx_("L", &c__3, &c__3, u, &tau, d__, &c__4, &work[1]);
00254         slarfx_("R", &c__3, &c__3, u, &tau, d__, &c__4, &work[1]);
00255 
00256 /*        Test whether to reject swap. */
00257 
00258 /* Computing MAX */
00259         r__2 = dabs(d__[2]), r__3 = dabs(d__[6]), r__2 = max(r__2,r__3), r__3 
00260                 = (r__1 = d__[10] - t11, dabs(r__1));
00261         if (dmax(r__2,r__3) > thresh) {
00262             goto L50;
00263         }
00264 
00265 /*        Accept swap: apply transformation to the entire matrix T. */
00266 
00267         i__1 = *n - *j1 + 1;
00268         slarfx_("L", &c__3, &i__1, u, &tau, &t[*j1 + *j1 * t_dim1], ldt, &
00269                 work[1]);
00270         slarfx_("R", &j2, &c__3, u, &tau, &t[*j1 * t_dim1 + 1], ldt, &work[1]);
00271 
00272         t[j3 + *j1 * t_dim1] = 0.f;
00273         t[j3 + j2 * t_dim1] = 0.f;
00274         t[j3 + j3 * t_dim1] = t11;
00275 
00276         if (*wantq) {
00277 
00278 /*           Accumulate transformation in the matrix Q. */
00279 
00280             slarfx_("R", n, &c__3, u, &tau, &q[*j1 * q_dim1 + 1], ldq, &work[
00281                     1]);
00282         }
00283         goto L40;
00284 
00285 L20:
00286 
00287 /*        N1 = 2, N2 = 1: generate elementary reflector H so that: */
00288 
00289 /*        H (  -X11 ) = ( * ) */
00290 /*          (  -X21 ) = ( 0 ) */
00291 /*          ( scale ) = ( 0 ) */
00292 
00293         u[0] = -x[0];
00294         u[1] = -x[1];
00295         u[2] = scale;
00296         slarfg_(&c__3, u, &u[1], &c__1, &tau);
00297         u[0] = 1.f;
00298         t33 = t[j3 + j3 * t_dim1];
00299 
00300 /*        Perform swap provisionally on diagonal block in D. */
00301 
00302         slarfx_("L", &c__3, &c__3, u, &tau, d__, &c__4, &work[1]);
00303         slarfx_("R", &c__3, &c__3, u, &tau, d__, &c__4, &work[1]);
00304 
00305 /*        Test whether to reject swap. */
00306 
00307 /* Computing MAX */
00308         r__2 = dabs(d__[1]), r__3 = dabs(d__[2]), r__2 = max(r__2,r__3), r__3 
00309                 = (r__1 = d__[0] - t33, dabs(r__1));
00310         if (dmax(r__2,r__3) > thresh) {
00311             goto L50;
00312         }
00313 
00314 /*        Accept swap: apply transformation to the entire matrix T. */
00315 
00316         slarfx_("R", &j3, &c__3, u, &tau, &t[*j1 * t_dim1 + 1], ldt, &work[1]);
00317         i__1 = *n - *j1;
00318         slarfx_("L", &c__3, &i__1, u, &tau, &t[*j1 + j2 * t_dim1], ldt, &work[
00319                 1]);
00320 
00321         t[*j1 + *j1 * t_dim1] = t33;
00322         t[j2 + *j1 * t_dim1] = 0.f;
00323         t[j3 + *j1 * t_dim1] = 0.f;
00324 
00325         if (*wantq) {
00326 
00327 /*           Accumulate transformation in the matrix Q. */
00328 
00329             slarfx_("R", n, &c__3, u, &tau, &q[*j1 * q_dim1 + 1], ldq, &work[
00330                     1]);
00331         }
00332         goto L40;
00333 
00334 L30:
00335 
00336 /*        N1 = 2, N2 = 2: generate elementary reflectors H(1) and H(2) so */
00337 /*        that: */
00338 
00339 /*        H(2) H(1) (  -X11  -X12 ) = (  *  * ) */
00340 /*                  (  -X21  -X22 )   (  0  * ) */
00341 /*                  ( scale    0  )   (  0  0 ) */
00342 /*                  (    0  scale )   (  0  0 ) */
00343 
00344         u1[0] = -x[0];
00345         u1[1] = -x[1];
00346         u1[2] = scale;
00347         slarfg_(&c__3, u1, &u1[1], &c__1, &tau1);
00348         u1[0] = 1.f;
00349 
00350         temp = -tau1 * (x[2] + u1[1] * x[3]);
00351         u2[0] = -temp * u1[1] - x[3];
00352         u2[1] = -temp * u1[2];
00353         u2[2] = scale;
00354         slarfg_(&c__3, u2, &u2[1], &c__1, &tau2);
00355         u2[0] = 1.f;
00356 
00357 /*        Perform swap provisionally on diagonal block in D. */
00358 
00359         slarfx_("L", &c__3, &c__4, u1, &tau1, d__, &c__4, &work[1])
00360                 ;
00361         slarfx_("R", &c__4, &c__3, u1, &tau1, d__, &c__4, &work[1])
00362                 ;
00363         slarfx_("L", &c__3, &c__4, u2, &tau2, &d__[1], &c__4, &work[1]);
00364         slarfx_("R", &c__4, &c__3, u2, &tau2, &d__[4], &c__4, &work[1]);
00365 
00366 /*        Test whether to reject swap. */
00367 
00368 /* Computing MAX */
00369         r__1 = dabs(d__[2]), r__2 = dabs(d__[6]), r__1 = max(r__1,r__2), r__2 
00370                 = dabs(d__[3]), r__1 = max(r__1,r__2), r__2 = dabs(d__[7]);
00371         if (dmax(r__1,r__2) > thresh) {
00372             goto L50;
00373         }
00374 
00375 /*        Accept swap: apply transformation to the entire matrix T. */
00376 
00377         i__1 = *n - *j1 + 1;
00378         slarfx_("L", &c__3, &i__1, u1, &tau1, &t[*j1 + *j1 * t_dim1], ldt, &
00379                 work[1]);
00380         slarfx_("R", &j4, &c__3, u1, &tau1, &t[*j1 * t_dim1 + 1], ldt, &work[
00381                 1]);
00382         i__1 = *n - *j1 + 1;
00383         slarfx_("L", &c__3, &i__1, u2, &tau2, &t[j2 + *j1 * t_dim1], ldt, &
00384                 work[1]);
00385         slarfx_("R", &j4, &c__3, u2, &tau2, &t[j2 * t_dim1 + 1], ldt, &work[1]
00386 );
00387 
00388         t[j3 + *j1 * t_dim1] = 0.f;
00389         t[j3 + j2 * t_dim1] = 0.f;
00390         t[j4 + *j1 * t_dim1] = 0.f;
00391         t[j4 + j2 * t_dim1] = 0.f;
00392 
00393         if (*wantq) {
00394 
00395 /*           Accumulate transformation in the matrix Q. */
00396 
00397             slarfx_("R", n, &c__3, u1, &tau1, &q[*j1 * q_dim1 + 1], ldq, &
00398                     work[1]);
00399             slarfx_("R", n, &c__3, u2, &tau2, &q[j2 * q_dim1 + 1], ldq, &work[
00400                     1]);
00401         }
00402 
00403 L40:
00404 
00405         if (*n2 == 2) {
00406 
00407 /*           Standardize new 2-by-2 block T11 */
00408 
00409             slanv2_(&t[*j1 + *j1 * t_dim1], &t[*j1 + j2 * t_dim1], &t[j2 + *
00410                     j1 * t_dim1], &t[j2 + j2 * t_dim1], &wr1, &wi1, &wr2, &
00411                     wi2, &cs, &sn);
00412             i__1 = *n - *j1 - 1;
00413             srot_(&i__1, &t[*j1 + (*j1 + 2) * t_dim1], ldt, &t[j2 + (*j1 + 2) 
00414                     * t_dim1], ldt, &cs, &sn);
00415             i__1 = *j1 - 1;
00416             srot_(&i__1, &t[*j1 * t_dim1 + 1], &c__1, &t[j2 * t_dim1 + 1], &
00417                     c__1, &cs, &sn);
00418             if (*wantq) {
00419                 srot_(n, &q[*j1 * q_dim1 + 1], &c__1, &q[j2 * q_dim1 + 1], &
00420                         c__1, &cs, &sn);
00421             }
00422         }
00423 
00424         if (*n1 == 2) {
00425 
00426 /*           Standardize new 2-by-2 block T22 */
00427 
00428             j3 = *j1 + *n2;
00429             j4 = j3 + 1;
00430             slanv2_(&t[j3 + j3 * t_dim1], &t[j3 + j4 * t_dim1], &t[j4 + j3 * 
00431                     t_dim1], &t[j4 + j4 * t_dim1], &wr1, &wi1, &wr2, &wi2, &
00432                     cs, &sn);
00433             if (j3 + 2 <= *n) {
00434                 i__1 = *n - j3 - 1;
00435                 srot_(&i__1, &t[j3 + (j3 + 2) * t_dim1], ldt, &t[j4 + (j3 + 2)
00436                          * t_dim1], ldt, &cs, &sn);
00437             }
00438             i__1 = j3 - 1;
00439             srot_(&i__1, &t[j3 * t_dim1 + 1], &c__1, &t[j4 * t_dim1 + 1], &
00440                     c__1, &cs, &sn);
00441             if (*wantq) {
00442                 srot_(n, &q[j3 * q_dim1 + 1], &c__1, &q[j4 * q_dim1 + 1], &
00443                         c__1, &cs, &sn);
00444             }
00445         }
00446 
00447     }
00448     return 0;
00449 
00450 /*     Exit with INFO = 1 if swap was rejected. */
00451 
00452 L50:
00453     *info = 1;
00454     return 0;
00455 
00456 /*     End of SLAEXC */
00457 
00458 } /* slaexc_ */


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