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 doublereal c_b11 = 1.;
00019 static integer c__1 = 1;
00020
00021 int dsbev_(char *jobz, char *uplo, integer *n, integer *kd,
00022 doublereal *ab, integer *ldab, doublereal *w, doublereal *z__,
00023 integer *ldz, doublereal *work, integer *info)
00024 {
00025
00026 integer ab_dim1, ab_offset, z_dim1, z_offset, i__1;
00027 doublereal d__1;
00028
00029
00030 double sqrt(doublereal);
00031
00032
00033 doublereal eps;
00034 integer inde;
00035 doublereal anrm;
00036 integer imax;
00037 doublereal rmin, rmax;
00038 extern int dscal_(integer *, doublereal *, doublereal *,
00039 integer *);
00040 doublereal sigma;
00041 extern logical lsame_(char *, char *);
00042 integer iinfo;
00043 logical lower, wantz;
00044 extern doublereal dlamch_(char *);
00045 integer iscale;
00046 extern int dlascl_(char *, integer *, integer *,
00047 doublereal *, doublereal *, integer *, integer *, doublereal *,
00048 integer *, integer *);
00049 extern doublereal dlansb_(char *, char *, integer *, integer *,
00050 doublereal *, integer *, doublereal *);
00051 doublereal safmin;
00052 extern int xerbla_(char *, integer *);
00053 doublereal bignum;
00054 extern int dsbtrd_(char *, char *, integer *, integer *,
00055 doublereal *, integer *, doublereal *, doublereal *, doublereal *,
00056 integer *, doublereal *, integer *), dsterf_(
00057 integer *, doublereal *, doublereal *, integer *);
00058 integer indwrk;
00059 extern int dsteqr_(char *, integer *, doublereal *,
00060 doublereal *, doublereal *, integer *, doublereal *, integer *);
00061 doublereal smlnum;
00062
00063
00064
00065
00066
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 ab_dim1 = *ldab;
00155 ab_offset = 1 + ab_dim1;
00156 ab -= ab_offset;
00157 --w;
00158 z_dim1 = *ldz;
00159 z_offset = 1 + z_dim1;
00160 z__ -= z_offset;
00161 --work;
00162
00163
00164 wantz = lsame_(jobz, "V");
00165 lower = lsame_(uplo, "L");
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 (*kd < 0) {
00175 *info = -4;
00176 } else if (*ldab < *kd + 1) {
00177 *info = -6;
00178 } else if (*ldz < 1 || wantz && *ldz < *n) {
00179 *info = -9;
00180 }
00181
00182 if (*info != 0) {
00183 i__1 = -(*info);
00184 xerbla_("DSBEV ", &i__1);
00185 return 0;
00186 }
00187
00188
00189
00190 if (*n == 0) {
00191 return 0;
00192 }
00193
00194 if (*n == 1) {
00195 if (lower) {
00196 w[1] = ab[ab_dim1 + 1];
00197 } else {
00198 w[1] = ab[*kd + 1 + ab_dim1];
00199 }
00200 if (wantz) {
00201 z__[z_dim1 + 1] = 1.;
00202 }
00203 return 0;
00204 }
00205
00206
00207
00208 safmin = dlamch_("Safe minimum");
00209 eps = dlamch_("Precision");
00210 smlnum = safmin / eps;
00211 bignum = 1. / smlnum;
00212 rmin = sqrt(smlnum);
00213 rmax = sqrt(bignum);
00214
00215
00216
00217 anrm = dlansb_("M", uplo, n, kd, &ab[ab_offset], ldab, &work[1]);
00218 iscale = 0;
00219 if (anrm > 0. && anrm < rmin) {
00220 iscale = 1;
00221 sigma = rmin / anrm;
00222 } else if (anrm > rmax) {
00223 iscale = 1;
00224 sigma = rmax / anrm;
00225 }
00226 if (iscale == 1) {
00227 if (lower) {
00228 dlascl_("B", kd, kd, &c_b11, &sigma, n, n, &ab[ab_offset], ldab,
00229 info);
00230 } else {
00231 dlascl_("Q", kd, kd, &c_b11, &sigma, n, n, &ab[ab_offset], ldab,
00232 info);
00233 }
00234 }
00235
00236
00237
00238 inde = 1;
00239 indwrk = inde + *n;
00240 dsbtrd_(jobz, uplo, n, kd, &ab[ab_offset], ldab, &w[1], &work[inde], &z__[
00241 z_offset], ldz, &work[indwrk], &iinfo);
00242
00243
00244
00245 if (! wantz) {
00246 dsterf_(n, &w[1], &work[inde], info);
00247 } else {
00248 dsteqr_(jobz, n, &w[1], &work[inde], &z__[z_offset], ldz, &work[
00249 indwrk], info);
00250 }
00251
00252
00253
00254 if (iscale == 1) {
00255 if (*info == 0) {
00256 imax = *n;
00257 } else {
00258 imax = *info - 1;
00259 }
00260 d__1 = 1. / sigma;
00261 dscal_(&imax, &d__1, &w[1], &c__1);
00262 }
00263
00264 return 0;
00265
00266
00267
00268 }