00001 /* sspgv.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 00020 /* Subroutine */ int sspgv_(integer *itype, char *jobz, char *uplo, integer * 00021 n, real *ap, real *bp, real *w, real *z__, integer *ldz, real *work, 00022 integer *info) 00023 { 00024 /* System generated locals */ 00025 integer z_dim1, z_offset, i__1; 00026 00027 /* Local variables */ 00028 integer j, neig; 00029 extern logical lsame_(char *, char *); 00030 char trans[1]; 00031 logical upper; 00032 extern /* Subroutine */ int sspev_(char *, char *, integer *, real *, 00033 real *, real *, integer *, real *, integer *); 00034 logical wantz; 00035 extern /* Subroutine */ int stpmv_(char *, char *, char *, integer *, 00036 real *, real *, integer *), stpsv_(char *, 00037 char *, char *, integer *, real *, real *, integer *), xerbla_(char *, integer *), spptrf_(char 00038 *, integer *, real *, integer *), sspgst_(integer *, char 00039 *, integer *, real *, real *, integer *); 00040 00041 00042 /* -- LAPACK driver routine (version 3.2) -- */ 00043 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ 00044 /* November 2006 */ 00045 00046 /* .. Scalar Arguments .. */ 00047 /* .. */ 00048 /* .. Array Arguments .. */ 00049 /* .. */ 00050 00051 /* Purpose */ 00052 /* ======= */ 00053 00054 /* SSPGV computes all the eigenvalues and, optionally, the eigenvectors */ 00055 /* of a real generalized symmetric-definite eigenproblem, of the form */ 00056 /* A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. */ 00057 /* Here A and B are assumed to be symmetric, stored in packed format, */ 00058 /* and B is also positive definite. */ 00059 00060 /* Arguments */ 00061 /* ========= */ 00062 00063 /* ITYPE (input) INTEGER */ 00064 /* Specifies the problem type to be solved: */ 00065 /* = 1: A*x = (lambda)*B*x */ 00066 /* = 2: A*B*x = (lambda)*x */ 00067 /* = 3: B*A*x = (lambda)*x */ 00068 00069 /* JOBZ (input) CHARACTER*1 */ 00070 /* = 'N': Compute eigenvalues only; */ 00071 /* = 'V': Compute eigenvalues and eigenvectors. */ 00072 00073 /* UPLO (input) CHARACTER*1 */ 00074 /* = 'U': Upper triangles of A and B are stored; */ 00075 /* = 'L': Lower triangles of A and B are stored. */ 00076 00077 /* N (input) INTEGER */ 00078 /* The order of the matrices A and B. N >= 0. */ 00079 00080 /* AP (input/output) REAL array, dimension */ 00081 /* (N*(N+1)/2) */ 00082 /* On entry, the upper or lower triangle of the symmetric matrix */ 00083 /* A, packed columnwise in a linear array. The j-th column of A */ 00084 /* is stored in the array AP as follows: */ 00085 /* if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j; */ 00086 /* if UPLO = 'L', AP(i + (j-1)*(2*n-j)/2) = A(i,j) for j<=i<=n. */ 00087 00088 /* On exit, the contents of AP are destroyed. */ 00089 00090 /* BP (input/output) REAL array, dimension (N*(N+1)/2) */ 00091 /* On entry, the upper or lower triangle of the symmetric matrix */ 00092 /* B, packed columnwise in a linear array. The j-th column of B */ 00093 /* is stored in the array BP as follows: */ 00094 /* if UPLO = 'U', BP(i + (j-1)*j/2) = B(i,j) for 1<=i<=j; */ 00095 /* if UPLO = 'L', BP(i + (j-1)*(2*n-j)/2) = B(i,j) for j<=i<=n. */ 00096 00097 /* On exit, the triangular factor U or L from the Cholesky */ 00098 /* factorization B = U**T*U or B = L*L**T, in the same storage */ 00099 /* format as B. */ 00100 00101 /* W (output) REAL array, dimension (N) */ 00102 /* If INFO = 0, the eigenvalues in ascending order. */ 00103 00104 /* Z (output) REAL array, dimension (LDZ, N) */ 00105 /* If JOBZ = 'V', then if INFO = 0, Z contains the matrix Z of */ 00106 /* eigenvectors. The eigenvectors are normalized as follows: */ 00107 /* if ITYPE = 1 or 2, Z**T*B*Z = I; */ 00108 /* if ITYPE = 3, Z**T*inv(B)*Z = I. */ 00109 /* If JOBZ = 'N', then Z is not referenced. */ 00110 00111 /* LDZ (input) INTEGER */ 00112 /* The leading dimension of the array Z. LDZ >= 1, and if */ 00113 /* JOBZ = 'V', LDZ >= max(1,N). */ 00114 00115 /* WORK (workspace) REAL array, dimension (3*N) */ 00116 00117 /* INFO (output) INTEGER */ 00118 /* = 0: successful exit */ 00119 /* < 0: if INFO = -i, the i-th argument had an illegal value */ 00120 /* > 0: SPPTRF or SSPEV returned an error code: */ 00121 /* <= N: if INFO = i, SSPEV failed to converge; */ 00122 /* i off-diagonal elements of an intermediate */ 00123 /* tridiagonal form did not converge to zero. */ 00124 /* > N: if INFO = n + i, for 1 <= i <= n, then the leading */ 00125 /* minor of order i of B is not positive definite. */ 00126 /* The factorization of B could not be completed and */ 00127 /* no eigenvalues or eigenvectors were computed. */ 00128 00129 /* ===================================================================== */ 00130 00131 /* .. Local Scalars .. */ 00132 /* .. */ 00133 /* .. External Functions .. */ 00134 /* .. */ 00135 /* .. External Subroutines .. */ 00136 /* .. */ 00137 /* .. Executable Statements .. */ 00138 00139 /* Test the input parameters. */ 00140 00141 /* Parameter adjustments */ 00142 --ap; 00143 --bp; 00144 --w; 00145 z_dim1 = *ldz; 00146 z_offset = 1 + z_dim1; 00147 z__ -= z_offset; 00148 --work; 00149 00150 /* Function Body */ 00151 wantz = lsame_(jobz, "V"); 00152 upper = lsame_(uplo, "U"); 00153 00154 *info = 0; 00155 if (*itype < 1 || *itype > 3) { 00156 *info = -1; 00157 } else if (! (wantz || lsame_(jobz, "N"))) { 00158 *info = -2; 00159 } else if (! (upper || lsame_(uplo, "L"))) { 00160 *info = -3; 00161 } else if (*n < 0) { 00162 *info = -4; 00163 } else if (*ldz < 1 || wantz && *ldz < *n) { 00164 *info = -9; 00165 } 00166 if (*info != 0) { 00167 i__1 = -(*info); 00168 xerbla_("SSPGV ", &i__1); 00169 return 0; 00170 } 00171 00172 /* Quick return if possible */ 00173 00174 if (*n == 0) { 00175 return 0; 00176 } 00177 00178 /* Form a Cholesky factorization of B. */ 00179 00180 spptrf_(uplo, n, &bp[1], info); 00181 if (*info != 0) { 00182 *info = *n + *info; 00183 return 0; 00184 } 00185 00186 /* Transform problem to standard eigenvalue problem and solve. */ 00187 00188 sspgst_(itype, uplo, n, &ap[1], &bp[1], info); 00189 sspev_(jobz, uplo, n, &ap[1], &w[1], &z__[z_offset], ldz, &work[1], info); 00190 00191 if (wantz) { 00192 00193 /* Backtransform eigenvectors to the original problem. */ 00194 00195 neig = *n; 00196 if (*info > 0) { 00197 neig = *info - 1; 00198 } 00199 if (*itype == 1 || *itype == 2) { 00200 00201 /* For A*x=(lambda)*B*x and A*B*x=(lambda)*x; */ 00202 /* backtransform eigenvectors: x = inv(L)'*y or inv(U)*y */ 00203 00204 if (upper) { 00205 *(unsigned char *)trans = 'N'; 00206 } else { 00207 *(unsigned char *)trans = 'T'; 00208 } 00209 00210 i__1 = neig; 00211 for (j = 1; j <= i__1; ++j) { 00212 stpsv_(uplo, trans, "Non-unit", n, &bp[1], &z__[j * z_dim1 + 00213 1], &c__1); 00214 /* L10: */ 00215 } 00216 00217 } else if (*itype == 3) { 00218 00219 /* For B*A*x=(lambda)*x; */ 00220 /* backtransform eigenvectors: x = L*y or U'*y */ 00221 00222 if (upper) { 00223 *(unsigned char *)trans = 'T'; 00224 } else { 00225 *(unsigned char *)trans = 'N'; 00226 } 00227 00228 i__1 = neig; 00229 for (j = 1; j <= i__1; ++j) { 00230 stpmv_(uplo, trans, "Non-unit", n, &bp[1], &z__[j * z_dim1 + 00231 1], &c__1); 00232 /* L20: */ 00233 } 00234 } 00235 } 00236 return 0; 00237 00238 /* End of SSPGV */ 00239 00240 } /* sspgv_ */