00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "f2c.h"
00014 #include "blaswrap.h"
00015
00016
00017
00018 static integer c__1 = 1;
00019 static integer c_n1 = -1;
00020 static integer c__0 = 0;
00021 static real c_b18 = 1.f;
00022
00023 int cheev_(char *jobz, char *uplo, integer *n, complex *a,
00024 integer *lda, real *w, complex *work, integer *lwork, real *rwork,
00025 integer *info)
00026 {
00027
00028 integer a_dim1, a_offset, i__1, i__2;
00029 real r__1;
00030
00031
00032 double sqrt(doublereal);
00033
00034
00035 integer nb;
00036 real eps;
00037 integer inde;
00038 real anrm;
00039 integer imax;
00040 real rmin, rmax, sigma;
00041 extern logical lsame_(char *, char *);
00042 integer iinfo;
00043 extern int sscal_(integer *, real *, real *, integer *);
00044 logical lower, wantz;
00045 extern doublereal clanhe_(char *, char *, integer *, complex *, integer *,
00046 real *);
00047 integer iscale;
00048 extern int clascl_(char *, integer *, integer *, real *,
00049 real *, integer *, integer *, complex *, integer *, integer *);
00050 extern doublereal slamch_(char *);
00051 extern int chetrd_(char *, integer *, complex *, integer
00052 *, real *, real *, complex *, complex *, integer *, integer *);
00053 real safmin;
00054 extern integer ilaenv_(integer *, char *, char *, integer *, integer *,
00055 integer *, integer *);
00056 extern int xerbla_(char *, integer *);
00057 real bignum;
00058 integer indtau, indwrk;
00059 extern int csteqr_(char *, integer *, real *, real *,
00060 complex *, integer *, real *, integer *), cungtr_(char *,
00061 integer *, complex *, integer *, complex *, complex *, integer *,
00062 integer *), ssterf_(integer *, real *, real *, integer *);
00063 integer llwork;
00064 real smlnum;
00065 integer lwkopt;
00066 logical lquery;
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 a_dim1 = *lda;
00156 a_offset = 1 + a_dim1;
00157 a -= a_offset;
00158 --w;
00159 --work;
00160 --rwork;
00161
00162
00163 wantz = lsame_(jobz, "V");
00164 lower = lsame_(uplo, "L");
00165 lquery = *lwork == -1;
00166
00167 *info = 0;
00168 if (! (wantz || lsame_(jobz, "N"))) {
00169 *info = -1;
00170 } else if (! (lower || lsame_(uplo, "U"))) {
00171 *info = -2;
00172 } else if (*n < 0) {
00173 *info = -3;
00174 } else if (*lda < max(1,*n)) {
00175 *info = -5;
00176 }
00177
00178 if (*info == 0) {
00179 nb = ilaenv_(&c__1, "CHETRD", uplo, n, &c_n1, &c_n1, &c_n1);
00180
00181 i__1 = 1, i__2 = (nb + 1) * *n;
00182 lwkopt = max(i__1,i__2);
00183 work[1].r = (real) lwkopt, work[1].i = 0.f;
00184
00185
00186 i__1 = 1, i__2 = (*n << 1) - 1;
00187 if (*lwork < max(i__1,i__2) && ! lquery) {
00188 *info = -8;
00189 }
00190 }
00191
00192 if (*info != 0) {
00193 i__1 = -(*info);
00194 xerbla_("CHEEV ", &i__1);
00195 return 0;
00196 } else if (lquery) {
00197 return 0;
00198 }
00199
00200
00201
00202 if (*n == 0) {
00203 return 0;
00204 }
00205
00206 if (*n == 1) {
00207 i__1 = a_dim1 + 1;
00208 w[1] = a[i__1].r;
00209 work[1].r = 1.f, work[1].i = 0.f;
00210 if (wantz) {
00211 i__1 = a_dim1 + 1;
00212 a[i__1].r = 1.f, a[i__1].i = 0.f;
00213 }
00214 return 0;
00215 }
00216
00217
00218
00219 safmin = slamch_("Safe minimum");
00220 eps = slamch_("Precision");
00221 smlnum = safmin / eps;
00222 bignum = 1.f / smlnum;
00223 rmin = sqrt(smlnum);
00224 rmax = sqrt(bignum);
00225
00226
00227
00228 anrm = clanhe_("M", uplo, n, &a[a_offset], lda, &rwork[1]);
00229 iscale = 0;
00230 if (anrm > 0.f && anrm < rmin) {
00231 iscale = 1;
00232 sigma = rmin / anrm;
00233 } else if (anrm > rmax) {
00234 iscale = 1;
00235 sigma = rmax / anrm;
00236 }
00237 if (iscale == 1) {
00238 clascl_(uplo, &c__0, &c__0, &c_b18, &sigma, n, n, &a[a_offset], lda,
00239 info);
00240 }
00241
00242
00243
00244 inde = 1;
00245 indtau = 1;
00246 indwrk = indtau + *n;
00247 llwork = *lwork - indwrk + 1;
00248 chetrd_(uplo, n, &a[a_offset], lda, &w[1], &rwork[inde], &work[indtau], &
00249 work[indwrk], &llwork, &iinfo);
00250
00251
00252
00253
00254 if (! wantz) {
00255 ssterf_(n, &w[1], &rwork[inde], info);
00256 } else {
00257 cungtr_(uplo, n, &a[a_offset], lda, &work[indtau], &work[indwrk], &
00258 llwork, &iinfo);
00259 indwrk = inde + *n;
00260 csteqr_(jobz, n, &w[1], &rwork[inde], &a[a_offset], lda, &rwork[
00261 indwrk], info);
00262 }
00263
00264
00265
00266 if (iscale == 1) {
00267 if (*info == 0) {
00268 imax = *n;
00269 } else {
00270 imax = *info - 1;
00271 }
00272 r__1 = 1.f / sigma;
00273 sscal_(&imax, &r__1, &w[1], &c__1);
00274 }
00275
00276
00277
00278 work[1].r = (real) lwkopt, work[1].i = 0.f;
00279
00280 return 0;
00281
00282
00283
00284 }