Update use of isnan in linearalgebra
[gromacs.git] / src / gromacs / linearalgebra / gmx_lapack / slarrfx.cpp
blob81a4058028e55406ca345685f46be40b5eac323c
1 #include <cmath>
3 #include "gromacs/utility/real.h"
5 #include "../gmx_blas.h"
6 #include "../gmx_lapack.h"
7 #include "lapack_limits.h"
10 void
11 F77_FUNC(slarrfx,SLARRFX)(int *n,
12 float *d__,
13 float *l,
14 float *ld,
15 float *lld,
16 int *ifirst,
17 int *ilast,
18 float *w,
19 float *sigma,
20 float *dplus,
21 float *lplus,
22 float *work,
23 int *info)
25 int i1 = 1;
26 int i__1;
27 float d__2, d__3;
29 int i__;
30 float s, eps, tmp, dmax1, dmax2, delta;
31 --work;
32 --lplus;
33 --dplus;
34 --w;
35 --lld;
36 --ld;
37 --l;
38 --d__;
39 *info = 0;
40 eps = GMX_FLOAT_EPS;
41 *sigma = w[*ifirst];
42 delta = eps * 2.;
44 L10:
45 s = -(*sigma);
46 dplus[1] = d__[1] + s;
47 dmax1 = std::abs(dplus[1]);
48 i__1 = *n - 1;
49 for (i__ = 1; i__ <= i__1; ++i__) {
50 lplus[i__] = ld[i__] / dplus[i__];
51 s = s * lplus[i__] * l[i__] - *sigma;
52 dplus[i__ + 1] = d__[i__ + 1] + s;
53 d__2 = dmax1, d__3 = std::abs(dplus[i__ + 1]);
54 dmax1 = (d__2>d__3) ? d__2 : d__3;
56 if (std::isnan(dmax1)) {
57 *sigma -= std::abs(*sigma) * delta;
58 delta *= 2.;
59 goto L10;
62 tmp = w[*ilast];
63 delta = eps * 2.;
64 L30:
65 s = -tmp;
66 work[1] = d__[1] + s;
67 dmax2 = std::abs(work[1]);
68 i__1 = *n - 1;
69 for (i__ = 1; i__ <= i__1; ++i__) {
70 work[*n + i__] = ld[i__] / work[i__];
71 s = s * work[*n + i__] * l[i__] - tmp;
72 work[i__ + 1] = d__[i__ + 1] + s;
73 d__2 = dmax2, d__3 = std::abs(work[i__ + 1]);
74 dmax2 = (d__2>d__3) ? d__2 : d__3;
76 if (std::isnan(dmax2)) {
77 tmp += std::abs(tmp) * delta;
78 delta *= 2.;
79 goto L30;
81 if (dmax2 < dmax1) {
82 *sigma = tmp;
83 F77_FUNC(scopy,SCOPY)(n, &work[1], &i1, &dplus[1], &i1);
84 i__1 = *n - 1;
85 F77_FUNC(scopy,SCOPY)(&i__1, &work[*n + 1], &i1, &lplus[1], &i1);
88 return;