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