00001 /* dlaed1.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 00021 /* Subroutine */ int dlaed1_(integer *n, doublereal *d__, doublereal *q, 00022 integer *ldq, integer *indxq, doublereal *rho, integer *cutpnt, 00023 doublereal *work, integer *iwork, integer *info) 00024 { 00025 /* System generated locals */ 00026 integer q_dim1, q_offset, i__1, i__2; 00027 00028 /* Local variables */ 00029 integer i__, k, n1, n2, is, iw, iz, iq2, zpp1, indx, indxc; 00030 extern /* Subroutine */ int dcopy_(integer *, doublereal *, integer *, 00031 doublereal *, integer *); 00032 integer indxp; 00033 extern /* Subroutine */ int dlaed2_(integer *, integer *, integer *, 00034 doublereal *, doublereal *, integer *, integer *, doublereal *, 00035 doublereal *, doublereal *, doublereal *, doublereal *, integer *, 00036 integer *, integer *, integer *, integer *), dlaed3_(integer *, 00037 integer *, integer *, doublereal *, doublereal *, integer *, 00038 doublereal *, doublereal *, doublereal *, integer *, integer *, 00039 doublereal *, doublereal *, integer *); 00040 integer idlmda; 00041 extern /* Subroutine */ int dlamrg_(integer *, integer *, doublereal *, 00042 integer *, integer *, integer *), xerbla_(char *, integer *); 00043 integer coltyp; 00044 00045 00046 /* -- LAPACK routine (version 3.2) -- */ 00047 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ 00048 /* November 2006 */ 00049 00050 /* .. Scalar Arguments .. */ 00051 /* .. */ 00052 /* .. Array Arguments .. */ 00053 /* .. */ 00054 00055 /* Purpose */ 00056 /* ======= */ 00057 00058 /* DLAED1 computes the updated eigensystem of a diagonal */ 00059 /* matrix after modification by a rank-one symmetric matrix. This */ 00060 /* routine is used only for the eigenproblem which requires all */ 00061 /* eigenvalues and eigenvectors of a tridiagonal matrix. DLAED7 handles */ 00062 /* the case in which eigenvalues only or eigenvalues and eigenvectors */ 00063 /* of a full symmetric matrix (which was reduced to tridiagonal form) */ 00064 /* are desired. */ 00065 00066 /* T = Q(in) ( D(in) + RHO * Z*Z' ) Q'(in) = Q(out) * D(out) * Q'(out) */ 00067 00068 /* where Z = Q'u, u is a vector of length N with ones in the */ 00069 /* CUTPNT and CUTPNT + 1 th elements and zeros elsewhere. */ 00070 00071 /* The eigenvectors of the original matrix are stored in Q, and the */ 00072 /* eigenvalues are in D. The algorithm consists of three stages: */ 00073 00074 /* The first stage consists of deflating the size of the problem */ 00075 /* when there are multiple eigenvalues or if there is a zero in */ 00076 /* the Z vector. For each such occurence the dimension of the */ 00077 /* secular equation problem is reduced by one. This stage is */ 00078 /* performed by the routine DLAED2. */ 00079 00080 /* The second stage consists of calculating the updated */ 00081 /* eigenvalues. This is done by finding the roots of the secular */ 00082 /* equation via the routine DLAED4 (as called by DLAED3). */ 00083 /* This routine also calculates the eigenvectors of the current */ 00084 /* problem. */ 00085 00086 /* The final stage consists of computing the updated eigenvectors */ 00087 /* directly using the updated eigenvalues. The eigenvectors for */ 00088 /* the current problem are multiplied with the eigenvectors from */ 00089 /* the overall problem. */ 00090 00091 /* Arguments */ 00092 /* ========= */ 00093 00094 /* N (input) INTEGER */ 00095 /* The dimension of the symmetric tridiagonal matrix. N >= 0. */ 00096 00097 /* D (input/output) DOUBLE PRECISION array, dimension (N) */ 00098 /* On entry, the eigenvalues of the rank-1-perturbed matrix. */ 00099 /* On exit, the eigenvalues of the repaired matrix. */ 00100 00101 /* Q (input/output) DOUBLE PRECISION array, dimension (LDQ,N) */ 00102 /* On entry, the eigenvectors of the rank-1-perturbed matrix. */ 00103 /* On exit, the eigenvectors of the repaired tridiagonal matrix. */ 00104 00105 /* LDQ (input) INTEGER */ 00106 /* The leading dimension of the array Q. LDQ >= max(1,N). */ 00107 00108 /* INDXQ (input/output) INTEGER array, dimension (N) */ 00109 /* On entry, the permutation which separately sorts the two */ 00110 /* subproblems in D into ascending order. */ 00111 /* On exit, the permutation which will reintegrate the */ 00112 /* subproblems back into sorted order, */ 00113 /* i.e. D( INDXQ( I = 1, N ) ) will be in ascending order. */ 00114 00115 /* RHO (input) DOUBLE PRECISION */ 00116 /* The subdiagonal entry used to create the rank-1 modification. */ 00117 00118 /* CUTPNT (input) INTEGER */ 00119 /* The location of the last eigenvalue in the leading sub-matrix. */ 00120 /* min(1,N) <= CUTPNT <= N/2. */ 00121 00122 /* WORK (workspace) DOUBLE PRECISION array, dimension (4*N + N**2) */ 00123 00124 /* IWORK (workspace) INTEGER array, dimension (4*N) */ 00125 00126 /* INFO (output) INTEGER */ 00127 /* = 0: successful exit. */ 00128 /* < 0: if INFO = -i, the i-th argument had an illegal value. */ 00129 /* > 0: if INFO = 1, an eigenvalue did not converge */ 00130 00131 /* Further Details */ 00132 /* =============== */ 00133 00134 /* Based on contributions by */ 00135 /* Jeff Rutter, Computer Science Division, University of California */ 00136 /* at Berkeley, USA */ 00137 /* Modified by Francoise Tisseur, University of Tennessee. */ 00138 00139 /* ===================================================================== */ 00140 00141 /* .. Local Scalars .. */ 00142 /* .. */ 00143 /* .. External Subroutines .. */ 00144 /* .. */ 00145 /* .. Intrinsic Functions .. */ 00146 /* .. */ 00147 /* .. Executable Statements .. */ 00148 00149 /* Test the input parameters. */ 00150 00151 /* Parameter adjustments */ 00152 --d__; 00153 q_dim1 = *ldq; 00154 q_offset = 1 + q_dim1; 00155 q -= q_offset; 00156 --indxq; 00157 --work; 00158 --iwork; 00159 00160 /* Function Body */ 00161 *info = 0; 00162 00163 if (*n < 0) { 00164 *info = -1; 00165 } else if (*ldq < max(1,*n)) { 00166 *info = -4; 00167 } else /* if(complicated condition) */ { 00168 /* Computing MIN */ 00169 i__1 = 1, i__2 = *n / 2; 00170 if (min(i__1,i__2) > *cutpnt || *n / 2 < *cutpnt) { 00171 *info = -7; 00172 } 00173 } 00174 if (*info != 0) { 00175 i__1 = -(*info); 00176 xerbla_("DLAED1", &i__1); 00177 return 0; 00178 } 00179 00180 /* Quick return if possible */ 00181 00182 if (*n == 0) { 00183 return 0; 00184 } 00185 00186 /* The following values are integer pointers which indicate */ 00187 /* the portion of the workspace */ 00188 /* used by a particular array in DLAED2 and DLAED3. */ 00189 00190 iz = 1; 00191 idlmda = iz + *n; 00192 iw = idlmda + *n; 00193 iq2 = iw + *n; 00194 00195 indx = 1; 00196 indxc = indx + *n; 00197 coltyp = indxc + *n; 00198 indxp = coltyp + *n; 00199 00200 00201 /* Form the z-vector which consists of the last row of Q_1 and the */ 00202 /* first row of Q_2. */ 00203 00204 dcopy_(cutpnt, &q[*cutpnt + q_dim1], ldq, &work[iz], &c__1); 00205 zpp1 = *cutpnt + 1; 00206 i__1 = *n - *cutpnt; 00207 dcopy_(&i__1, &q[zpp1 + zpp1 * q_dim1], ldq, &work[iz + *cutpnt], &c__1); 00208 00209 /* Deflate eigenvalues. */ 00210 00211 dlaed2_(&k, n, cutpnt, &d__[1], &q[q_offset], ldq, &indxq[1], rho, &work[ 00212 iz], &work[idlmda], &work[iw], &work[iq2], &iwork[indx], &iwork[ 00213 indxc], &iwork[indxp], &iwork[coltyp], info); 00214 00215 if (*info != 0) { 00216 goto L20; 00217 } 00218 00219 /* Solve Secular Equation. */ 00220 00221 if (k != 0) { 00222 is = (iwork[coltyp] + iwork[coltyp + 1]) * *cutpnt + (iwork[coltyp + 00223 1] + iwork[coltyp + 2]) * (*n - *cutpnt) + iq2; 00224 dlaed3_(&k, n, cutpnt, &d__[1], &q[q_offset], ldq, rho, &work[idlmda], 00225 &work[iq2], &iwork[indxc], &iwork[coltyp], &work[iw], &work[ 00226 is], info); 00227 if (*info != 0) { 00228 goto L20; 00229 } 00230 00231 /* Prepare the INDXQ sorting permutation. */ 00232 00233 n1 = k; 00234 n2 = *n - k; 00235 dlamrg_(&n1, &n2, &d__[1], &c__1, &c_n1, &indxq[1]); 00236 } else { 00237 i__1 = *n; 00238 for (i__ = 1; i__ <= i__1; ++i__) { 00239 indxq[i__] = i__; 00240 /* L10: */ 00241 } 00242 } 00243 00244 L20: 00245 return 0; 00246 00247 /* End of DLAED1 */ 00248 00249 } /* dlaed1_ */