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.
36 #include "gmx_lapack.h"
37 #include "lapack_limits.h"
39 #include <types/simple.h>
42 #pragma warning(disable: 4723) /*division by zero - is used on purpose here*/
46 F77_FUNC(slasq2,SLASQ2)(int *n,
62 float dmin__, emin, emax;
64 float qmin, temp, qmax, zmax;
66 float desig, trace, sigma;
70 float oldemn, safmin, minval;
71 float posinf,neginf,negzro,newzro;
79 minval = GMX_FLOAT_MIN;
80 safmin = minval*(1.0+eps);
100 if (z__[2] < 0. || z__[3] < 0.) {
103 } else if (z__[3] > z__[1]) {
108 z__[5] = z__[1] + z__[2] + z__[3];
109 if (z__[2] > z__[3] * tol2) {
110 t = (z__[1] - z__[3] + z__[2]) * .5;
111 s = z__[3] * (z__[2] / t);
113 s = z__[3] * (z__[2] / (t * (sqrt(s / t + 1.) + 1.)));
115 s = z__[3] * (z__[2] / (t + sqrt(t) * sqrt(t + s)));
117 t = z__[1] + (s + z__[2]);
118 z__[3] *= z__[1] / t;
122 z__[6] = z__[2] + z__[1];
133 for (k = 1; k <= i__1; k += 2) {
137 } else if (z__[k + 1] < 0.) {
143 d__1 = qmax, d__2 = z__[k];
144 qmax = (d__1>d__2) ? d__1 : d__2;
145 d__1 = emin, d__2 = z__[k + 1];
146 emin = (d__1<d__2) ? d__1 : d__2;
147 d__1 = (qmax>zmax) ? qmax : zmax;
149 zmax = (d__1>d__2) ? d__1 : d__2;
151 if (z__[(*n << 1) - 1] < 0.) {
152 *info = -((*n << 1) + 199);
155 d__ += z__[(*n << 1) - 1];
156 d__1 = qmax, d__2 = z__[(*n << 1) - 1];
157 qmax = (d__1>d__2) ? d__1 : d__2;
158 zmax = (qmax>zmax) ? qmax : zmax;
160 if (fabs(e)<GMX_FLOAT_MIN) {
162 for (k = 2; k <= i__1; ++k) {
163 z__[k] = z__[(k << 1) - 1];
165 F77_FUNC(slasrt,SLASRT)("D", n, &z__[1], &iinfo);
166 z__[(*n << 1) - 1] = d__;
172 if (fabs(trace)<GMX_FLOAT_MIN) {
173 z__[(*n << 1) - 1] = 0.;
184 negzro = one/(neginf+one);
185 if(fabs(negzro)>GMX_FLOAT_MIN)
190 newzro = negzro + zero;
191 if(fabs(newzro-zero)>GMX_FLOAT_MIN)
193 posinf = one /newzro;
196 neginf = neginf*posinf;
199 posinf = posinf*posinf;
203 for (k = *n << 1; k >= 2; k += -2) {
205 z__[(k << 1) - 1] = z__[k];
206 z__[(k << 1) - 2] = 0.;
207 z__[(k << 1) - 3] = z__[k - 1];
213 if (z__[(i0 << 2) - 3] * 1.5 < z__[(n0 << 2) - 3]) {
215 i__1 = 2*(i0 + n0 - 1);
216 for (i4 = i0 << 2; i4 <= i__1; i4 += 4) {
218 z__[i4 - 3] = z__[ipn4 - i4 - 3];
219 z__[ipn4 - i4 - 3] = temp;
221 z__[i4 - 1] = z__[ipn4 - i4 - 5];
222 z__[ipn4 - i4 - 5] = temp;
228 for (k = 1; k <= 2; ++k) {
230 d__ = z__[(n0 << 2) + pp - 3];
231 i__1 = (i0 << 2) + pp;
232 for (i4 = 4*(n0 - 1) + pp; i4 >= i__1; i4 += -4) {
233 if (z__[i4 - 1] <= tol2 * d__) {
237 d__ = z__[i4 - 3] * (d__ / (d__ + z__[i4 - 1]));
241 emin = z__[(i0 << 2) + pp + 1];
242 d__ = z__[(i0 << 2) + pp - 3];
243 i__1 = 4*(n0 - 1) + pp;
244 for (i4 = (i0 << 2) + pp; i4 <= i__1; i4 += 4) {
245 z__[i4 - (pp << 1) - 2] = d__ + z__[i4 - 1];
246 if (z__[i4 - 1] <= tol2 * d__) {
248 z__[i4 - (pp << 1) - 2] = d__;
249 z__[i4 - (pp << 1)] = 0.;
251 } else if (safmin * z__[i4 + 1] < z__[i4 - (pp << 1) - 2] &&
252 safmin * z__[i4 - (pp << 1) - 2] < z__[i4 + 1]) {
253 temp = z__[i4 + 1] / z__[i4 - (pp << 1) - 2];
254 z__[i4 - (pp << 1)] = z__[i4 - 1] * temp;
257 z__[i4 - (pp << 1)] = z__[i4 + 1] * (z__[i4 - 1] / z__[i4 - (
259 d__ = z__[i4 + 1] * (d__ / z__[i4 - (pp << 1) - 2]);
261 d__1 = emin, d__2 = z__[i4 - (pp << 1)];
262 emin = (d__1<d__2) ? d__1 : d__2;
264 z__[(n0 << 2) - pp - 2] = d__;
267 qmax = z__[(i0 << 2) - pp - 2];
268 i__1 = (n0 << 2) - pp - 2;
269 for (i4 = (i0 << 2) - pp + 2; i4 <= i__1; i4 += 4) {
270 d__1 = qmax, d__2 = z__[i4];
271 qmax = (d__1>d__2) ? d__1 : d__2;
282 for (iwhila = 1; iwhila <= i__1; ++iwhila) {
291 sigma = -z__[(n0 << 2) - 1];
300 emin = fabs(z__[(n0 << 2) - 5]);
304 qmin = z__[(n0 << 2) - 3];
306 for (i4 = n0 << 2; i4 >= 8; i4 += -4) {
307 if (z__[i4 - 5] <= 0.) {
310 if (qmin >= emax * 4.) {
311 d__1 = qmin, d__2 = z__[i4 - 3];
312 qmin = (d__1<d__2) ? d__1 : d__2;
313 d__1 = emax, d__2 = z__[i4 - 5];
314 emax = (d__1>d__2) ? d__1 : d__2;
316 d__1 = qmax, d__2 = z__[i4 - 7] + z__[i4 - 5];
317 qmax = (d__1>d__2) ? d__1 : d__2;
318 d__1 = emin, d__2 = z__[i4 - 5];
319 emin = (d__1<d__2) ? d__1 : d__2;
328 dee = z__[(i0 << 2) - 3];
331 i__2 = (n0 << 2) - 3;
332 for (i4 = (i0 << 2) - 3; i4 <= i__2; i4 += 4) {
333 dee = z__[i4] * (dee / (dee + z__[i4 - 2]));
339 if (2*(kmin - i0) < n0 - kmin && deemin <= z__[(n0 << 2) - 3] *
343 i__2 = 2*(i0 + n0 - 1);
344 for (i4 = i0 << 2; i4 <= i__2; i4 += 4) {
346 z__[i4 - 3] = z__[ipn4 - i4 - 3];
347 z__[ipn4 - i4 - 3] = temp;
349 z__[i4 - 2] = z__[ipn4 - i4 - 2];
350 z__[ipn4 - i4 - 2] = temp;
352 z__[i4 - 1] = z__[ipn4 - i4 - 5];
353 z__[ipn4 - i4 - 5] = temp;
355 z__[i4] = z__[ipn4 - i4 - 4];
356 z__[ipn4 - i4 - 4] = temp;
362 d__1 = 0., d__2 = qmin - sqrt(qmin) * 2. * sqrt(emax);
363 dmin__ = -((d__1>d__2) ? d__1 : d__2);
365 nbig = (n0 - i0 + 1) * 30;
367 for (iwhilb = 1; iwhilb <= i__2; ++iwhilb) {
372 F77_FUNC(slasq3,SLASQ3)(&i0, &n0, &z__[1], &pp, &dmin__, &sigma, &desig, &qmax, &
373 nfail, &iter, &ndiv, &ieee);
377 if (pp == 0 && n0 - i0 >= 3) {
378 if (z__[n0 * 4] <= tol2 * qmax || z__[(n0 << 2) - 1] <= tol2 *
381 qmax = z__[(i0 << 2) - 3];
382 emin = z__[(i0 << 2) - 1];
383 oldemn = z__[i0 * 4];
385 for (i4 = i0 << 2; i4 <= i__3; i4 += 4) {
386 if (z__[i4] <= tol2 * z__[i4 - 3] || z__[i4 - 1] <=
388 z__[i4 - 1] = -sigma;
392 oldemn = z__[i4 + 4];
394 d__1 = qmax, d__2 = z__[i4 + 1];
395 qmax = (d__1>d__2) ? d__1 : d__2;
396 d__1 = emin, d__2 = z__[i4 - 1];
397 emin = (d__1<d__2) ? d__1 : d__2;
398 d__1 = oldemn, d__2 = z__[i4];
399 oldemn = (d__1<d__2) ? d__1 : d__2;
402 z__[(n0 << 2) - 1] = emin;
403 z__[n0 * 4] = oldemn;
423 for (k = 2; k <= i__1; ++k) {
424 z__[k] = z__[(k << 2) - 3];
427 F77_FUNC(slasrt,SLASRT)("D", n, &z__[1], &iinfo);
430 for (k = *n; k >= 1; --k) {
435 z__[(*n << 1) + 1] = trace;
436 z__[(*n << 1) + 2] = e;
437 z__[(*n << 1) + 3] = (float) iter;
439 z__[(*n << 1) + 4] = (float) ndiv / (float) (i__1 * i__1);
440 z__[(*n << 1) + 5] = nfail * 100. / (float) iter;