slatdf.c
Go to the documentation of this file.
00001 /* slatdf.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_n1 = -1;
00020 static real c_b23 = 1.f;
00021 static real c_b37 = -1.f;
00022 
00023 /* Subroutine */ int slatdf_(integer *ijob, integer *n, real *z__, integer *
00024         ldz, real *rhs, real *rdsum, real *rdscal, integer *ipiv, integer *
00025         jpiv)
00026 {
00027     /* System generated locals */
00028     integer z_dim1, z_offset, i__1, i__2;
00029     real r__1;
00030 
00031     /* Builtin functions */
00032     double sqrt(doublereal);
00033 
00034     /* Local variables */
00035     integer i__, j, k;
00036     real bm, bp, xm[8], xp[8];
00037     integer info;
00038     real temp;
00039     extern doublereal sdot_(integer *, real *, integer *, real *, integer *);
00040     real work[32];
00041     extern /* Subroutine */ int sscal_(integer *, real *, real *, integer *);
00042     real pmone;
00043     extern doublereal sasum_(integer *, real *, integer *);
00044     real sminu;
00045     integer iwork[8];
00046     extern /* Subroutine */ int scopy_(integer *, real *, integer *, real *, 
00047             integer *), saxpy_(integer *, real *, real *, integer *, real *, 
00048             integer *);
00049     real splus;
00050     extern /* Subroutine */ int sgesc2_(integer *, real *, integer *, real *, 
00051             integer *, integer *, real *), sgecon_(char *, integer *, real *, 
00052             integer *, real *, real *, real *, integer *, integer *), 
00053             slassq_(integer *, real *, integer *, real *, real *), slaswp_(
00054             integer *, real *, integer *, integer *, integer *, integer *, 
00055             integer *);
00056 
00057 
00058 /*  -- LAPACK auxiliary routine (version 3.2) -- */
00059 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00060 /*     November 2006 */
00061 
00062 /*     .. Scalar Arguments .. */
00063 /*     .. */
00064 /*     .. Array Arguments .. */
00065 /*     .. */
00066 
00067 /*  Purpose */
00068 /*  ======= */
00069 
00070 /*  SLATDF uses the LU factorization of the n-by-n matrix Z computed by */
00071 /*  SGETC2 and computes a contribution to the reciprocal Dif-estimate */
00072 /*  by solving Z * x = b for x, and choosing the r.h.s. b such that */
00073 /*  the norm of x is as large as possible. On entry RHS = b holds the */
00074 /*  contribution from earlier solved sub-systems, and on return RHS = x. */
00075 
00076 /*  The factorization of Z returned by SGETC2 has the form Z = P*L*U*Q, */
00077 /*  where P and Q are permutation matrices. L is lower triangular with */
00078 /*  unit diagonal elements and U is upper triangular. */
00079 
00080 /*  Arguments */
00081 /*  ========= */
00082 
00083 /*  IJOB    (input) INTEGER */
00084 /*          IJOB = 2: First compute an approximative null-vector e */
00085 /*              of Z using SGECON, e is normalized and solve for */
00086 /*              Zx = +-e - f with the sign giving the greater value */
00087 /*              of 2-norm(x). About 5 times as expensive as Default. */
00088 /*          IJOB .ne. 2: Local look ahead strategy where all entries of */
00089 /*              the r.h.s. b is choosen as either +1 or -1 (Default). */
00090 
00091 /*  N       (input) INTEGER */
00092 /*          The number of columns of the matrix Z. */
00093 
00094 /*  Z       (input) REAL array, dimension (LDZ, N) */
00095 /*          On entry, the LU part of the factorization of the n-by-n */
00096 /*          matrix Z computed by SGETC2:  Z = P * L * U * Q */
00097 
00098 /*  LDZ     (input) INTEGER */
00099 /*          The leading dimension of the array Z.  LDA >= max(1, N). */
00100 
00101 /*  RHS     (input/output) REAL array, dimension N. */
00102 /*          On entry, RHS contains contributions from other subsystems. */
00103 /*          On exit, RHS contains the solution of the subsystem with */
00104 /*          entries acoording to the value of IJOB (see above). */
00105 
00106 /*  RDSUM   (input/output) REAL */
00107 /*          On entry, the sum of squares of computed contributions to */
00108 /*          the Dif-estimate under computation by STGSYL, where the */
00109 /*          scaling factor RDSCAL (see below) has been factored out. */
00110 /*          On exit, the corresponding sum of squares updated with the */
00111 /*          contributions from the current sub-system. */
00112 /*          If TRANS = 'T' RDSUM is not touched. */
00113 /*          NOTE: RDSUM only makes sense when STGSY2 is called by STGSYL. */
00114 
00115 /*  RDSCAL  (input/output) REAL */
00116 /*          On entry, scaling factor used to prevent overflow in RDSUM. */
00117 /*          On exit, RDSCAL is updated w.r.t. the current contributions */
00118 /*          in RDSUM. */
00119 /*          If TRANS = 'T', RDSCAL is not touched. */
00120 /*          NOTE: RDSCAL only makes sense when STGSY2 is called by */
00121 /*                STGSYL. */
00122 
00123 /*  IPIV    (input) INTEGER array, dimension (N). */
00124 /*          The pivot indices; for 1 <= i <= N, row i of the */
00125 /*          matrix has been interchanged with row IPIV(i). */
00126 
00127 /*  JPIV    (input) INTEGER array, dimension (N). */
00128 /*          The pivot indices; for 1 <= j <= N, column j of the */
00129 /*          matrix has been interchanged with column JPIV(j). */
00130 
00131 /*  Further Details */
00132 /*  =============== */
00133 
00134 /*  Based on contributions by */
00135 /*     Bo Kagstrom and Peter Poromaa, Department of Computing Science, */
00136 /*     Umea University, S-901 87 Umea, Sweden. */
00137 
00138 /*  This routine is a further developed implementation of algorithm */
00139 /*  BSOLVE in [1] using complete pivoting in the LU factorization. */
00140 
00141 /*  [1] Bo Kagstrom and Lars Westin, */
00142 /*      Generalized Schur Methods with Condition Estimators for */
00143 /*      Solving the Generalized Sylvester Equation, IEEE Transactions */
00144 /*      on Automatic Control, Vol. 34, No. 7, July 1989, pp 745-751. */
00145 
00146 /*  [2] Peter Poromaa, */
00147 /*      On Efficient and Robust Estimators for the Separation */
00148 /*      between two Regular Matrix Pairs with Applications in */
00149 /*      Condition Estimation. Report IMINF-95.05, Departement of */
00150 /*      Computing Science, Umea University, S-901 87 Umea, Sweden, 1995. */
00151 
00152 /*  ===================================================================== */
00153 
00154 /*     .. Parameters .. */
00155 /*     .. */
00156 /*     .. Local Scalars .. */
00157 /*     .. */
00158 /*     .. Local Arrays .. */
00159 /*     .. */
00160 /*     .. External Subroutines .. */
00161 /*     .. */
00162 /*     .. External Functions .. */
00163 /*     .. */
00164 /*     .. Intrinsic Functions .. */
00165 /*     .. */
00166 /*     .. Executable Statements .. */
00167 
00168     /* Parameter adjustments */
00169     z_dim1 = *ldz;
00170     z_offset = 1 + z_dim1;
00171     z__ -= z_offset;
00172     --rhs;
00173     --ipiv;
00174     --jpiv;
00175 
00176     /* Function Body */
00177     if (*ijob != 2) {
00178 
00179 /*        Apply permutations IPIV to RHS */
00180 
00181         i__1 = *n - 1;
00182         slaswp_(&c__1, &rhs[1], ldz, &c__1, &i__1, &ipiv[1], &c__1);
00183 
00184 /*        Solve for L-part choosing RHS either to +1 or -1. */
00185 
00186         pmone = -1.f;
00187 
00188         i__1 = *n - 1;
00189         for (j = 1; j <= i__1; ++j) {
00190             bp = rhs[j] + 1.f;
00191             bm = rhs[j] - 1.f;
00192             splus = 1.f;
00193 
00194 /*           Look-ahead for L-part RHS(1:N-1) = + or -1, SPLUS and */
00195 /*           SMIN computed more efficiently than in BSOLVE [1]. */
00196 
00197             i__2 = *n - j;
00198             splus += sdot_(&i__2, &z__[j + 1 + j * z_dim1], &c__1, &z__[j + 1 
00199                     + j * z_dim1], &c__1);
00200             i__2 = *n - j;
00201             sminu = sdot_(&i__2, &z__[j + 1 + j * z_dim1], &c__1, &rhs[j + 1], 
00202                      &c__1);
00203             splus *= rhs[j];
00204             if (splus > sminu) {
00205                 rhs[j] = bp;
00206             } else if (sminu > splus) {
00207                 rhs[j] = bm;
00208             } else {
00209 
00210 /*              In this case the updating sums are equal and we can */
00211 /*              choose RHS(J) +1 or -1. The first time this happens */
00212 /*              we choose -1, thereafter +1. This is a simple way to */
00213 /*              get good estimates of matrices like Byers well-known */
00214 /*              example (see [1]). (Not done in BSOLVE.) */
00215 
00216                 rhs[j] += pmone;
00217                 pmone = 1.f;
00218             }
00219 
00220 /*           Compute the remaining r.h.s. */
00221 
00222             temp = -rhs[j];
00223             i__2 = *n - j;
00224             saxpy_(&i__2, &temp, &z__[j + 1 + j * z_dim1], &c__1, &rhs[j + 1], 
00225                      &c__1);
00226 
00227 /* L10: */
00228         }
00229 
00230 /*        Solve for U-part, look-ahead for RHS(N) = +-1. This is not done */
00231 /*        in BSOLVE and will hopefully give us a better estimate because */
00232 /*        any ill-conditioning of the original matrix is transfered to U */
00233 /*        and not to L. U(N, N) is an approximation to sigma_min(LU). */
00234 
00235         i__1 = *n - 1;
00236         scopy_(&i__1, &rhs[1], &c__1, xp, &c__1);
00237         xp[*n - 1] = rhs[*n] + 1.f;
00238         rhs[*n] += -1.f;
00239         splus = 0.f;
00240         sminu = 0.f;
00241         for (i__ = *n; i__ >= 1; --i__) {
00242             temp = 1.f / z__[i__ + i__ * z_dim1];
00243             xp[i__ - 1] *= temp;
00244             rhs[i__] *= temp;
00245             i__1 = *n;
00246             for (k = i__ + 1; k <= i__1; ++k) {
00247                 xp[i__ - 1] -= xp[k - 1] * (z__[i__ + k * z_dim1] * temp);
00248                 rhs[i__] -= rhs[k] * (z__[i__ + k * z_dim1] * temp);
00249 /* L20: */
00250             }
00251             splus += (r__1 = xp[i__ - 1], dabs(r__1));
00252             sminu += (r__1 = rhs[i__], dabs(r__1));
00253 /* L30: */
00254         }
00255         if (splus > sminu) {
00256             scopy_(n, xp, &c__1, &rhs[1], &c__1);
00257         }
00258 
00259 /*        Apply the permutations JPIV to the computed solution (RHS) */
00260 
00261         i__1 = *n - 1;
00262         slaswp_(&c__1, &rhs[1], ldz, &c__1, &i__1, &jpiv[1], &c_n1);
00263 
00264 /*        Compute the sum of squares */
00265 
00266         slassq_(n, &rhs[1], &c__1, rdscal, rdsum);
00267 
00268     } else {
00269 
00270 /*        IJOB = 2, Compute approximate nullvector XM of Z */
00271 
00272         sgecon_("I", n, &z__[z_offset], ldz, &c_b23, &temp, work, iwork, &
00273                 info);
00274         scopy_(n, &work[*n], &c__1, xm, &c__1);
00275 
00276 /*        Compute RHS */
00277 
00278         i__1 = *n - 1;
00279         slaswp_(&c__1, xm, ldz, &c__1, &i__1, &ipiv[1], &c_n1);
00280         temp = 1.f / sqrt(sdot_(n, xm, &c__1, xm, &c__1));
00281         sscal_(n, &temp, xm, &c__1);
00282         scopy_(n, xm, &c__1, xp, &c__1);
00283         saxpy_(n, &c_b23, &rhs[1], &c__1, xp, &c__1);
00284         saxpy_(n, &c_b37, xm, &c__1, &rhs[1], &c__1);
00285         sgesc2_(n, &z__[z_offset], ldz, &rhs[1], &ipiv[1], &jpiv[1], &temp);
00286         sgesc2_(n, &z__[z_offset], ldz, xp, &ipiv[1], &jpiv[1], &temp);
00287         if (sasum_(n, xp, &c__1) > sasum_(n, &rhs[1], &c__1)) {
00288             scopy_(n, xp, &c__1, &rhs[1], &c__1);
00289         }
00290 
00291 /*        Compute the sum of squares */
00292 
00293         slassq_(n, &rhs[1], &c__1, rdscal, rdsum);
00294 
00295     }
00296 
00297     return 0;
00298 
00299 /*     End of SLATDF */
00300 
00301 } /* slatdf_ */


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