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


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:55:46