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 doublereal c_b17 = 1.;
00022
00023 int dsyev_(char *jobz, char *uplo, integer *n, doublereal *a,
00024 integer *lda, doublereal *w, doublereal *work, integer *lwork,
00025 integer *info)
00026 {
00027
00028 integer a_dim1, a_offset, i__1, i__2;
00029 doublereal d__1;
00030
00031
00032 double sqrt(doublereal);
00033
00034
00035 integer nb;
00036 doublereal eps;
00037 integer inde;
00038 doublereal anrm;
00039 integer imax;
00040 doublereal rmin, rmax;
00041 extern int dscal_(integer *, doublereal *, doublereal *,
00042 integer *);
00043 doublereal sigma;
00044 extern logical lsame_(char *, char *);
00045 integer iinfo;
00046 logical lower, wantz;
00047 extern doublereal dlamch_(char *);
00048 integer iscale;
00049 extern int dlascl_(char *, integer *, integer *,
00050 doublereal *, doublereal *, integer *, integer *, doublereal *,
00051 integer *, integer *);
00052 doublereal safmin;
00053 extern integer ilaenv_(integer *, char *, char *, integer *, integer *,
00054 integer *, integer *);
00055 extern int xerbla_(char *, integer *);
00056 doublereal bignum;
00057 integer indtau;
00058 extern int dsterf_(integer *, doublereal *, doublereal *,
00059 integer *);
00060 extern doublereal dlansy_(char *, char *, integer *, doublereal *,
00061 integer *, doublereal *);
00062 integer indwrk;
00063 extern int dorgtr_(char *, integer *, doublereal *,
00064 integer *, doublereal *, doublereal *, integer *, integer *), dsteqr_(char *, integer *, doublereal *, doublereal *,
00065 doublereal *, integer *, doublereal *, integer *),
00066 dsytrd_(char *, integer *, doublereal *, integer *, doublereal *,
00067 doublereal *, doublereal *, doublereal *, integer *, integer *);
00068 integer llwork;
00069 doublereal smlnum;
00070 integer lwkopt;
00071 logical lquery;
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
00156
00157
00158 a_dim1 = *lda;
00159 a_offset = 1 + a_dim1;
00160 a -= a_offset;
00161 --w;
00162 --work;
00163
00164
00165 wantz = lsame_(jobz, "V");
00166 lower = lsame_(uplo, "L");
00167 lquery = *lwork == -1;
00168
00169 *info = 0;
00170 if (! (wantz || lsame_(jobz, "N"))) {
00171 *info = -1;
00172 } else if (! (lower || lsame_(uplo, "U"))) {
00173 *info = -2;
00174 } else if (*n < 0) {
00175 *info = -3;
00176 } else if (*lda < max(1,*n)) {
00177 *info = -5;
00178 }
00179
00180 if (*info == 0) {
00181 nb = ilaenv_(&c__1, "DSYTRD", uplo, n, &c_n1, &c_n1, &c_n1);
00182
00183 i__1 = 1, i__2 = (nb + 2) * *n;
00184 lwkopt = max(i__1,i__2);
00185 work[1] = (doublereal) lwkopt;
00186
00187
00188 i__1 = 1, i__2 = *n * 3 - 1;
00189 if (*lwork < max(i__1,i__2) && ! lquery) {
00190 *info = -8;
00191 }
00192 }
00193
00194 if (*info != 0) {
00195 i__1 = -(*info);
00196 xerbla_("DSYEV ", &i__1);
00197 return 0;
00198 } else if (lquery) {
00199 return 0;
00200 }
00201
00202
00203
00204 if (*n == 0) {
00205 return 0;
00206 }
00207
00208 if (*n == 1) {
00209 w[1] = a[a_dim1 + 1];
00210 work[1] = 2.;
00211 if (wantz) {
00212 a[a_dim1 + 1] = 1.;
00213 }
00214 return 0;
00215 }
00216
00217
00218
00219 safmin = dlamch_("Safe minimum");
00220 eps = dlamch_("Precision");
00221 smlnum = safmin / eps;
00222 bignum = 1. / smlnum;
00223 rmin = sqrt(smlnum);
00224 rmax = sqrt(bignum);
00225
00226
00227
00228 anrm = dlansy_("M", uplo, n, &a[a_offset], lda, &work[1]);
00229 iscale = 0;
00230 if (anrm > 0. && 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 dlascl_(uplo, &c__0, &c__0, &c_b17, &sigma, n, n, &a[a_offset], lda,
00239 info);
00240 }
00241
00242
00243
00244 inde = 1;
00245 indtau = inde + *n;
00246 indwrk = indtau + *n;
00247 llwork = *lwork - indwrk + 1;
00248 dsytrd_(uplo, n, &a[a_offset], lda, &w[1], &work[inde], &work[indtau], &
00249 work[indwrk], &llwork, &iinfo);
00250
00251
00252
00253
00254 if (! wantz) {
00255 dsterf_(n, &w[1], &work[inde], info);
00256 } else {
00257 dorgtr_(uplo, n, &a[a_offset], lda, &work[indtau], &work[indwrk], &
00258 llwork, &iinfo);
00259 dsteqr_(jobz, n, &w[1], &work[inde], &a[a_offset], lda, &work[indtau],
00260 info);
00261 }
00262
00263
00264
00265 if (iscale == 1) {
00266 if (*info == 0) {
00267 imax = *n;
00268 } else {
00269 imax = *info - 1;
00270 }
00271 d__1 = 1. / sigma;
00272 dscal_(&imax, &d__1, &w[1], &c__1);
00273 }
00274
00275
00276
00277 work[1] = (doublereal) lwkopt;
00278
00279 return 0;
00280
00281
00282
00283 }