2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2012, by the GROMACS development team, led by
5 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
6 * others, as listed in the AUTHORS file in the top-level source
7 * directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
38 #include "gmx_lapack.h"
39 #include "lapack_limits.h"
42 F77_FUNC(dsyevr,DSYEVR)(const char *jobz, const char *range, const char *uplo, int *n,
43 double *a, int *lda, double *vl, double *vu, int *
44 il, int *iu, double *abstol, int *m, double *w,
45 double *z__, int *ldz, int *isuppz, double *work,
46 int *lwork, int *iwork, int *liwork, int *info)
48 /* System generated locals */
49 int a_dim1, a_offset, z_dim1, z_offset, i__1, i__2;
55 double eps, vll, vuu, tmp1;
60 int itmp1, inddd, indee;
67 int iscale, ieeeok, indibl, indifl;
70 double abstll, bignum;
78 double posinf,neginf,negzro,newzro;
83 /* Parameter adjustments */
85 a_offset = 1 + a_dim1;
89 z_offset = 1 + z_dim1;
95 /* Check for IEEE-compliant FP */
100 neginf = -fone/fzero;
103 negzro = fone/(neginf+fone);
106 neginf = fone/negzro;
109 newzro = negzro + fzero;
112 posinf = fone /newzro;
115 neginf = neginf*posinf;
118 posinf = posinf*posinf;
122 lower = (*uplo=='L' || *uplo=='l');
123 wantz = (*jobz=='V' || *jobz=='v');
124 alleig = (*range=='A' || *range=='a');
125 valeig = (*range=='V' || *range=='v');
126 indeig = (*range=='I' || *range=='i');
129 lquery = *lwork == -1 || *liwork == -1;
145 if (! (wantz || (*jobz=='N' || *jobz=='n'))) {
147 } else if (! (alleig || valeig || indeig)) {
149 } else if (! (lower || (*uplo=='U' || *uplo=='u'))) {
153 } else if (*lda < ((*n>1) ? *n : 1) ) {
157 if (*n > 0 && *vu <= *vl) {
161 if (*il < 1 || *il > ((*n>1) ? *n : 1)) {
163 } else if (*iu < ((*n<*il) ? *n : *il) || *iu > *n) {
169 if (*ldz < 1 || (wantz && *ldz < *n)) {
171 } else if (*lwork < lwmin && ! lquery) {
173 } else if (*liwork < liwmin && ! lquery) {
181 i__1 = (nb + 1) * *n;
182 lwkopt = (i__1>lwmin) ? i__1 : lwmin;
183 work[1] = (double) lwkopt;
199 if (alleig || indeig) {
201 w[1] = a[a_dim1 + 1];
203 if (*vl < a[a_dim1 + 1] && *vu >= a[a_dim1 + 1]) {
205 w[1] = a[a_dim1 + 1];
209 z__[z_dim1 + 1] = 1.;
213 minval = GMX_DOUBLE_MIN;
214 safmin = minval*(1.0+GMX_DOUBLE_EPS);
215 eps = GMX_DOUBLE_EPS;
217 smlnum = safmin / eps;
218 bignum = 1. / smlnum;
221 d__1 = sqrt(bignum), d__2 = 1. / sqrt(sqrt(safmin));
222 rmax = (d__1<d__2) ? d__1 : d__2;
228 anrm = F77_FUNC(dlansy,DLANSY)("M", uplo, n, &a[a_offset], lda, &work[1]);
229 if (anrm > 0. && anrm < rmin) {
232 } else if (anrm > rmax) {
239 for (j = 1; j <= i__1; ++j) {
241 F77_FUNC(dscal,DSCAL)(&i__2, &sigma, &a[j + j * a_dim1], &c__1);
245 for (j = 1; j <= i__1; ++j) {
246 F77_FUNC(dscal,DSCAL)(&j, &sigma, &a[j * a_dim1 + 1], &c__1);
251 abstll = *abstol * sigma;
266 llwork = *lwork - indwk + 1;
267 F77_FUNC(dsytrd,DSYTRD)(uplo, n, &a[a_offset], lda, &work[indd], &work[inde], &work[
268 indtau], &work[indwk], &llwork, &iinfo);
271 F77_FUNC(dcopy,DCOPY)(&i__1, &work[inde], &c__1, &work[indee], &c__1);
272 F77_FUNC(dcopy,DCOPY)(n, &work[indd], &c__1, &work[inddd], &c__1);
274 F77_FUNC(dstegr,DSTEGR)(jobz, range, n, &work[inddd], &work[indee], vl, vu, il, iu,
275 abstol, m, &w[1], &z__[z_offset], ldz, &isuppz[1],
276 &work[indwk], lwork, &iwork[1], liwork, info);
277 if (wantz && *info == 0) {
279 llwrkn = *lwork - indwkn + 1;
280 F77_FUNC(dormtr,DORMTR)("L", uplo, "N", n, m, &a[a_offset], lda, &work[indtau]
281 , &z__[z_offset], ldz, &work[indwkn], &llwrkn, &iinfo);
294 F77_FUNC(dscal,DSCAL)(&imax, &d__1, &w[1], &c__1);
300 for (j = 1; j <= i__1; ++j) {
304 for (jj = j + 1; jj <= i__2; ++jj) {
312 itmp1 = iwork[indibl + i__ - 1];
314 iwork[indibl + i__ - 1] = iwork[indibl + j - 1];
316 iwork[indibl + j - 1] = itmp1;
317 F77_FUNC(dswap,DSWAP)(n, &z__[i__ * z_dim1 + 1], &c__1, &z__[j * z_dim1 + 1],
323 work[1] = (double) lwkopt;