2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2012,2013, 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.
37 #include <types/simple.h>
40 #include "gmx_lapack.h"
41 #include "lapack_limits.h"
45 F77_FUNC(slarrvx,SLARRVX)(int *n,
62 int z_dim1, z_offset, i__1, i__2, i__3, i__4, i__5, i__6;
74 int wend, iter, temp[1], ktot;
78 int ndone, iinfo, iindr;
82 int zfrom, iindc1, iindc2;
87 int oldien, oldncl, wbegin;
90 int ndepth, inderr, iindwk;
95 int newfrs, newftt, parity;
96 float mgstol, nrminv, rqcorr;
108 z_offset = 1 + z_dim1;
123 iindwk = (*n << 2) + 1;
128 for (i__ = 1; i__ <= i__1; ++i__) {
131 F77_FUNC(slaset,SLASET)("Full", n, m, &c_b5, &c_b5, &z__[z_offset], ldz);
137 for (jblk = 1; jblk <= i__1; ++jblk) {
143 if (iblock[wend + 1] == jblk) {
153 if (ibegin == iend) {
154 z__[ibegin + wbegin * z_dim1] = 1.;
155 isuppz[(wbegin << 1) - 1] = ibegin;
156 isuppz[wbegin * 2] = ibegin;
163 d__1 = .001, d__2 = 1. / (float) in;
164 reltol = (d__1<d__2) ? d__1 : d__2;
165 im = wend - wbegin + 1;
166 F77_FUNC(scopy,SCOPY)(&im, &w[wbegin], &c__1, &work[1], &c__1);
168 for (i__ = 1; i__ <= i__2; ++i__) {
169 work[inderr + i__] = eps * fabs(work[i__]);
170 work[indgap + i__] = work[i__ + 1] - work[i__];
172 work[inderr + im] = eps * fabs(work[im]);
173 d__2 = fabs(work[im]);
174 work[indgap + im] = (d__2>eps) ? d__2 : eps;
180 iwork[iindc1 + 1] = 1;
181 iwork[iindc1 + 2] = im;
196 for (i__ = 1; i__ <= i__2; ++i__) {
198 j = oldcls + (i__ << 1);
199 oldfst = iwork[j - 1];
202 j = wbegin + oldfst - 1;
203 F77_FUNC(scopy,SCOPY)(&in, &z__[ibegin + j * z_dim1], &c__1, &d__[ibegin]
206 F77_FUNC(scopy,SCOPY)(&i__3, &z__[ibegin + (j + 1) * z_dim1], &c__1, &l[
208 F77_FUNC(slaset,SLASET)("Full", &in, &c__2, &c_b5, &c_b5, &z__[ibegin + j
213 for (j = 1; j <= i__3; ++j) {
215 work[indld + j] = tmp;
216 work[indlld + j] = tmp * l[k];
221 p = indexw[wbegin - 1 + oldfst];
222 q = indexw[wbegin - 1 + oldlst];
225 F77_FUNC(slarrbx,SLARRBX)(&in, &d__[ibegin], &l[ibegin], &work[indld + 1], &
226 work[indlld + 1], &p, &q, &reltol, &d__1, &i__3, &
227 work[1], &work[indgap + 1], &work[inderr + 1], &
228 work[indwrk + in], &iwork[iindwk], &iinfo);
232 for (j = oldfst; j <= i__3; ++j) {
233 if (j == oldlst || work[indgap + j] >=
234 reltol * fabs(work[j])) {
238 relgap = work[indgap + j] / fabs(work[j]);
242 minrgp = (minrgp<relgap) ? minrgp : relgap;
246 newsiz = newlst - newfrs + 1;
247 newftt = wbegin + newfrs - 1;
248 nomgs = newsiz == 1 || newsiz > 1 || minrgp < mgstol;
249 if (newsiz > 1 && nomgs) {
251 F77_FUNC(slarrfx,SLARRFX)(&in, &d__[ibegin], &l[ibegin], &work[indld +
252 1], &work[indlld + 1], &newfrs, &newlst, &
253 work[1], &sigma, &z__[ibegin + newftt *
254 z_dim1], &z__[ibegin + (newftt + 1) * z_dim1],
255 &work[indwrk], info);
257 tmp = eps * fabs(sigma);
259 for (k = newfrs; k <= i__4; ++k) {
261 d__1 = work[indgap + k];
262 work[indgap + k] = (d__1>tmp) ? d__1 : tmp;
263 work[inderr + k] += tmp;
266 k = newcls + (nclus << 1);
267 iwork[k - 1] = newfrs;
271 if (minrgp >= mgstol) {
275 work[indwrk] = d__[ibegin];
277 for (k = 1; k <= i__4; ++k) {
278 work[indwrk + k] = d__[ibegin + k] + work[
282 for (k = 1; k <= i__4; ++k) {
283 iwork[iindwk + k - 1] = 1;
286 for (k = newfrs; k <= i__4; ++k) {
287 isuppz[2*(oldien + k) - 1] = 1;
288 isuppz[(oldien + k) * 2] = in;
291 F77_FUNC(sstein,SSTEIN)(&in, &work[indwrk], &work[indld + 1],
292 &newsiz, &work[newfrs], &iwork[iindwk]
293 , temp, &z__[ibegin + newftt * z_dim1]
294 , ldz, &work[indwrk + in], &iwork[
295 iindwk + in], &iwork[iindwk + (in*2)], &iinfo);
306 for (k = newfrs; k <= i__4; ++k) {
311 F77_FUNC(slar1vx,SLAR1VX)(&in, &c__1, &in, &lambda, &d__[ibegin], &
312 l[ibegin], &work[indld + 1], &work[indlld
313 + 1], &w[wbegin + k - 1], &gersch[(oldien
314 << 1) + 1], &z__[ibegin + ktot * z_dim1],
315 &ztz, &mingma, &iwork[iindr + ktot], &
316 isuppz[(ktot << 1) - 1], &work[indwrk]);
319 resid = fabs(mingma) * nrminv;
320 rqcorr = mingma * tmp;
322 gap = work[indgap + k - 1];
324 gap = work[indgap + k];
326 d__1 = work[indgap + k - 1], d__2 = work[
328 gap = (d__1<d__2) ? d__1 : d__2;
331 if (resid > *tol * gap && fabs(rqcorr) > eps * 4. *
333 work[k] = lambda + rqcorr;
342 zfrom = isuppz[(ktot << 1) - 1];
343 zto = isuppz[ktot * 2];
344 i__5 = zto - zfrom + 1;
345 F77_FUNC(sscal,SSCAL)(&i__5, &nrminv, &z__[ibegin + zfrom - 1 +
346 ktot * z_dim1], &c__1);
350 itmp1 = isuppz[(newftt << 1) - 1];
351 itmp2 = isuppz[newftt * 2];
352 ktot = oldien + newlst;
354 for (p = newftt + 1; p <= i__4; ++p) {
356 for (q = newftt; q <= i__5; ++q) {
357 tmp = -F77_FUNC(sdot,SDOT)(&in, &z__[ibegin + p *
358 z_dim1], &c__1, &z__[ibegin + q *
360 F77_FUNC(saxpy,SAXPY)(&in, &tmp, &z__[ibegin + q *
361 z_dim1], &c__1, &z__[ibegin + p *
364 tmp = 1. / F77_FUNC(snrm2,SNRM2)(&in, &z__[ibegin + p *
366 F77_FUNC(sscal,SSCAL)(&in, &tmp, &z__[ibegin + p * z_dim1], &
368 i__5 = itmp1, i__6 = isuppz[(p << 1) - 1];
369 itmp1 = (i__5<i__6) ? i__5 : i__6;
370 i__5 = itmp2, i__6 = isuppz[p * 2];
371 itmp2 = (i__5>i__6) ? i__5 : i__6;
374 for (p = newftt; p <= i__4; ++p) {
375 isuppz[(p << 1) - 1] = itmp1;
376 isuppz[p * 2] = itmp2;
389 for (i__ = wbegin; i__ <= i__2; ++i__) {
390 isuppz[j - 1] += oldien;