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


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