Fix mis-use of fabs in LAPACK
[alexxy/gromacs.git] / src / gromacs / linearalgebra / gmx_lapack / slagts.c
1 #include <stdlib.h>
2 #include <math.h>
3 #include "types/simple.h"
4
5 #include "../gmx_lapack.h"
6 #include "lapack_limits.h"
7
8
9 void
10 F77_FUNC(slagts,SLAGTS)(int *job, 
11         int *n, 
12         float *a, 
13         float *b, 
14         float *c__, 
15         float *d__, 
16         int *in, 
17         float *y, 
18         float *tol, 
19         int *info)
20 {
21     int i__1;
22     float d__1, d__2, d__4, d__5;
23
24     int k;
25     float ak, eps, temp, pert, absak, sfmin;
26     float bignum,minval;
27     --y;
28     --in;
29     --d__;
30     --c__;
31     --b;
32     --a;
33
34     *info = 0;
35     if (abs(*job) > 2 || *job == 0) {
36         *info = -1;
37     } else if (*n < 0) {
38         *info = -2;
39     }
40     if (*info != 0) {
41         i__1 = -(*info);
42         return;
43     }
44
45     if (*n == 0) {
46         return;
47     }
48     eps = GMX_FLOAT_EPS;
49     minval = GMX_FLOAT_MIN;
50     sfmin = minval / eps;
51
52     bignum = 1. / sfmin;
53
54     if (*job < 0) {
55         if (*tol <= 0.) {
56             *tol = fabs(a[1]);
57             if (*n > 1) {
58                 d__1 = *tol;
59                 d__2 = fabs(a[2]);
60                 d__1 = (d__1>d__2) ? d__1 : d__2;
61                 d__2 = fabs(b[1]);
62                 *tol = (d__1>d__2) ? d__1 : d__2;
63             }
64             i__1 = *n;
65             for (k = 3; k <= i__1; ++k) {
66               d__4 = *tol;
67               d__5 = fabs(a[k]);
68               d__4 = (d__4>d__5) ? d__4 : d__5;
69               d__5 = fabs(b[k - 1]);
70               d__4 = (d__4>d__5) ? d__4 : d__5;
71               d__5 = fabs(d__[k - 2]);
72               *tol = (d__4>d__5) ? d__4 : d__5;
73             }
74             *tol *= eps;
75             if (fabs(*tol)<GMX_FLOAT_MIN) {
76                 *tol = eps;
77             }
78         }
79     }
80
81     if (1 == abs(*job)) {
82         i__1 = *n;
83         for (k = 2; k <= i__1; ++k) {
84             if (in[k - 1] == 0) {
85                 y[k] -= c__[k - 1] * y[k - 1];
86             } else {
87                 temp = y[k - 1];
88                 y[k - 1] = y[k];
89                 y[k] = temp - c__[k - 1] * y[k];
90             }
91         }
92         if (*job == 1) {
93             for (k = *n; k >= 1; --k) {
94                 if (k <= *n - 2) {
95                     temp = y[k] - b[k] * y[k + 1] - d__[k] * y[k + 2];
96                 } else if (k == *n - 1) {
97                     temp = y[k] - b[k] * y[k + 1];
98                 } else {
99                     temp = y[k];
100                 }
101                 ak = a[k];
102                 absak = fabs(ak);
103                 if (absak < 1.) {
104                     if (absak < sfmin) {
105                         if (fabs(absak)<GMX_FLOAT_MIN || fabs(temp) * sfmin > absak) {
106                             *info = k;
107                             return;
108                         } else {
109                             temp *= bignum;
110                             ak *= bignum;
111                         }
112                     } else if (fabs(temp) > absak * bignum) {
113                         *info = k;
114                         return;
115                     }
116                 }
117                 y[k] = temp / ak;
118             }
119         } else {
120             for (k = *n; k >= 1; --k) {
121                 if (k <= *n - 2) {
122                     temp = y[k] - b[k] * y[k + 1] - d__[k] * y[k + 2];
123                 } else if (k == *n - 1) {
124                     temp = y[k] - b[k] * y[k + 1];
125                 } else {
126                     temp = y[k];
127                 }
128                 ak = a[k];
129
130                 pert = *tol;
131                 if(ak<0)
132                   pert *= -1.0;
133 L40:
134                 absak = fabs(ak);
135                 if (absak < 1.) {
136                     if (absak < sfmin) {
137                         if (fabs(absak)<GMX_FLOAT_MIN || fabs(temp) * sfmin > absak) {
138                             ak += pert;
139                             pert *= 2;
140                             goto L40;
141                         } else {
142                             temp *= bignum;
143                             ak *= bignum;
144                         }
145                     } else if (fabs(temp) > absak * bignum) {
146                         ak += pert;
147                         pert *= 2;
148                         goto L40;
149                     }
150                 }
151                 y[k] = temp / ak;
152             }
153         }
154     } else {
155
156         if (*job == 2) {
157             i__1 = *n;
158             for (k = 1; k <= i__1; ++k) {
159                 if (k >= 3) {
160                     temp = y[k] - b[k - 1] * y[k - 1] - d__[k - 2] * y[k - 2];
161                 } else if (k == 2) {
162                     temp = y[k] - b[k - 1] * y[k - 1];
163                 } else {
164                     temp = y[k];
165                 }
166                 ak = a[k];
167                 absak = fabs(ak);
168                 if (absak < 1.) {
169                     if (absak < sfmin) {
170                         if (fabs(absak)<GMX_FLOAT_MIN || fabs(temp) * sfmin > absak) {
171                             *info = k;
172                             return;
173                         } else {
174                             temp *= bignum;
175                             ak *= bignum;
176                         }
177                     } else if (fabs(temp) > absak * bignum) {
178                         *info = k;
179                         return;
180                     }
181                 }
182                 y[k] = temp / ak;
183             }
184         } else {
185             i__1 = *n;
186             for (k = 1; k <= i__1; ++k) {
187                 if (k >= 3) {
188                     temp = y[k] - b[k - 1] * y[k - 1] - d__[k - 2] * y[k - 2];
189                 } else if (k == 2) {
190                     temp = y[k] - b[k - 1] * y[k - 1];
191                 } else {
192                     temp = y[k];
193                 }
194                 ak = a[k];
195
196                 pert = *tol;
197                 if(ak<0)
198                   pert *= -1.0;
199
200 L70:
201                 absak = fabs(ak);
202                 if (absak < 1.) {
203                     if (absak < sfmin) {
204                         if (fabs(absak)<GMX_FLOAT_MIN || fabs(temp) * sfmin > absak) {
205                             ak += pert;
206                             pert *= 2;
207                             goto L70;
208                         } else {
209                             temp *= bignum;
210                             ak *= bignum;
211                         }
212                     } else if (fabs(temp) > absak * bignum) {
213                         ak += pert;
214                         pert *= 2;
215                         goto L70;
216                     }
217                 }
218                 y[k] = temp / ak;
219             }
220         }
221
222         for (k = *n; k >= 2; --k) {
223             if (in[k - 1] == 0) {
224                 y[k - 1] -= c__[k - 1] * y[k];
225             } else {
226                 temp = y[k - 1];
227                 y[k - 1] = y[k];
228                 y[k] = temp - c__[k - 1] * y[k];
229             }
230         }
231     }
232
233     return;
234 }
235
236