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.
39 #include "gmx_lapack.h"
41 #include <types/simple.h>
44 F77_FUNC(sbdsqr,SBDSQR)(const char *uplo,
60 const char xuplo = toupper(*uplo);
61 int c_dim1, c_offset, u_dim1, u_offset, vt_dim1, vt_offset, i__1,
63 float r__1, r__2, r__3, r__4;
75 int nm1, nm12, nm13, lll;
76 float eps, sll, tol, abse;
82 float unfl, sinl, cosr, smin, smax, sinr;
85 float shift, sigmn, oldsn;
100 vt_offset = 1 + vt_dim1;
103 u_offset = 1 + u_dim1;
106 c_offset = 1 + c_dim1;
112 itmp1 = (*n > 1) ? *n : 1;
113 itmp2 = (*nru > 1) ? *nru : 1;
115 lower = (xuplo == 'L');
116 if ( (xuplo!='U') && !lower) {
120 } else if (*ncvt < 0) {
122 } else if (*nru < 0) {
124 } else if (*ncc < 0) {
126 } else if ( ((*ncvt == 0) && (*ldvt < 1)) || ((*ncvt > 0) && (*ldvt < itmp1)) ) {
128 } else if (*ldu < itmp2) {
130 } else if ( ((*ncc == 0) && (*ldc < 1)) || ((*ncc > 0) && (*ldc < itmp1))) {
143 rotate = *ncvt > 0 || *nru > 0 || *ncc > 0;
146 F77_FUNC(slasq1,SLASQ1)(n, &d__[1], &e[1], &work[1], info);
156 unfl = GMX_FLOAT_MIN/GMX_FLOAT_EPS;
160 for (i__ = 1; i__ <= i__1; ++i__) {
161 F77_FUNC(slartg,SLARTG)(&d__[i__], &e[i__], &cs, &sn, &r__);
163 e[i__] = sn * d__[i__ + 1];
164 d__[i__ + 1] = cs * d__[i__ + 1];
166 work[nm1 + i__] = sn;
170 F77_FUNC(slasr,SLASR)("R", "V", "F", nru, n, &work[1], &work[*n], &u[u_offset],
174 F77_FUNC(slasr,SLASR)("L", "V", "F", n, ncc, &work[1], &work[*n], &c__[c_offset],
179 r__3 = 100.f, r__4 = pow(GMX_FLOAT_EPS,c_b15);
180 r__1 = 10.f, r__2 = (r__3<r__4) ? r__3 : r__4;
181 tolmul = (r__1>r__2) ? r__1 : r__2;
185 for (i__ = 1; i__ <= i__1; ++i__) {
186 r__2 = smax, r__3 = (r__1 = d__[i__], fabs(r__1));
187 smax = (r__2>r__3) ? r__2 : r__3;
190 for (i__ = 1; i__ <= i__1; ++i__) {
191 r__2 = smax, r__3 = (r__1 = e[i__], fabs(r__1));
192 smax = (r__2>r__3) ? r__2 : r__3;
196 sminoa = fabs(d__[1]);
202 for (i__ = 2; i__ <= i__1; ++i__) {
203 mu = (r__2 = d__[i__], fabs(r__2)) * (mu / (mu + (r__1 = e[i__ -
205 sminoa = (sminoa<mu) ? sminoa : mu;
211 sminoa /= sqrt((float) (*n));
212 r__1 = tol * sminoa, r__2 = *n * 6 * *n * unfl;
213 thresh = (r__1>r__2) ? r__1 : r__2;
215 r__1 = fabs(tol) * smax, r__2 = *n * 6 * *n * unfl;
216 thresh = (r__1>r__2) ? r__1 : r__2;
233 if (tol < 0.f && (r__1 = d__[m], fabs(r__1)) <= thresh) {
236 smax = (r__1 = d__[m], fabs(r__1));
239 for (lll = 1; lll <= i__1; ++lll) {
241 abss = (r__1 = d__[ll], fabs(r__1));
242 abse = (r__1 = e[ll], fabs(r__1));
243 if (tol < 0.f && abss <= thresh) {
246 if (abse <= thresh) {
249 smin = (smin<abss) ? smin : abss;
250 r__1 = (smax>abss) ? smax : abss;
251 smax = (r__1>abse) ? r__1 : abse;
264 F77_FUNC(slasv2,SLASV2)(&d__[m - 1], &e[m - 1], &d__[m], &sigmn, &sigmx, &sinr, &cosr,
270 F77_FUNC(srot,SROT)(ncvt, &vt[m - 1 + vt_dim1], ldvt, &vt[m + vt_dim1], ldvt, &
274 F77_FUNC(srot,SROT)(nru, &u[(m - 1) * u_dim1 + 1], &c__1, &u[m * u_dim1 + 1], &
278 F77_FUNC(srot,SROT)(ncc, &c__[m - 1 + c_dim1], ldc, &c__[m + c_dim1], ldc, &
284 if (ll > oldm || m < oldll) {
285 if ((r__1 = d__[ll], fabs(r__1)) >= (r__2 = d__[m], fabs(r__2))) {
293 if( (fabs(e[m-1]) <= fabs(tol) * fabs(d__[m])) ||
294 (tol<0.0 && fabs(e[m-1])<=thresh)) {
299 mu = (r__1 = d__[ll], fabs(r__1));
302 for (lll = ll; lll <= i__1; ++lll) {
303 if ((r__1 = e[lll], fabs(r__1)) <= tol * mu) {
308 mu = (r__2 = d__[lll + 1], fabs(r__2)) * (mu / (mu + (r__1 =
309 e[lll], fabs(r__1))));
310 sminl = (sminl<mu) ? sminl : mu;
314 if( (fabs(e[ll]) <= fabs(tol)*fabs(d__[ll])) ||
315 (tol<0.0 && fabs(e[ll])<=thresh)) {
320 mu = (r__1 = d__[m], fabs(r__1));
323 for (lll = m - 1; lll >= i__1; --lll) {
324 if ((r__1 = e[lll], fabs(r__1)) <= tol * mu) {
329 mu = (r__2 = d__[lll], fabs(r__2)) * (mu / (mu + (r__1 = e[
331 sminl = (sminl<mu) ? sminl : mu;
338 r__1 = eps, r__2 = tol * .01f;
339 if (tol >= 0.f && *n * tol * (sminl / smax) <= ((r__1>r__2) ? r__1 : r__2)) {
343 sll = (r__1 = d__[ll], fabs(r__1));
344 F77_FUNC(slas2,SLAS2)(&d__[m - 1], &e[m - 1], &d__[m], &shift, &r__);
346 sll = (r__1 = d__[m], fabs(r__1));
347 F77_FUNC(slas2,SLAS2)(&d__[ll], &e[ll], &d__[ll + 1], &shift, &r__);
351 if (r__1 * r__1 < eps) {
356 iter = iter + m - ll;
362 for (i__ = ll; i__ <= i__1; ++i__) {
363 r__1 = d__[i__] * cs;
364 F77_FUNC(slartg,SLARTG)(&r__1, &e[i__], &cs, &sn, &r__);
366 e[i__ - 1] = oldsn * r__;
369 r__2 = d__[i__ + 1] * sn;
370 F77_FUNC(slartg,SLARTG)(&r__1, &r__2, &oldcs, &oldsn, &d__[i__]);
371 work[i__ - ll + 1] = cs;
372 work[i__ - ll + 1 + nm1] = sn;
373 work[i__ - ll + 1 + nm12] = oldcs;
374 work[i__ - ll + 1 + nm13] = oldsn;
377 d__[m] = h__ * oldcs;
378 e[m - 1] = h__ * oldsn;
381 F77_FUNC(slasr,SLASR)("L", "V", "F", &i__1, ncvt, &work[1], &work[*n], &vt[
382 ll + vt_dim1], ldvt);
386 F77_FUNC(slasr,SLASR)("R", "V", "F", nru, &i__1, &work[nm12 + 1], &work[nm13
387 + 1], &u[ll * u_dim1 + 1], ldu);
391 F77_FUNC(slasr,SLASR)("L", "V", "F", &i__1, ncc, &work[nm12 + 1], &work[nm13
392 + 1], &c__[ll + c_dim1], ldc);
394 if ((r__1 = e[m - 1], fabs(r__1)) <= thresh) {
401 for (i__ = m; i__ >= i__1; --i__) {
402 r__1 = d__[i__] * cs;
403 F77_FUNC(slartg,SLARTG)(&r__1, &e[i__ - 1], &cs, &sn, &r__);
405 e[i__] = oldsn * r__;
408 r__2 = d__[i__ - 1] * sn;
409 F77_FUNC(slartg,SLARTG)(&r__1, &r__2, &oldcs, &oldsn, &d__[i__]);
411 work[i__ - ll + nm1] = -sn;
412 work[i__ - ll + nm12] = oldcs;
413 work[i__ - ll + nm13] = -oldsn;
416 d__[ll] = h__ * oldcs;
420 F77_FUNC(slasr,SLASR)("L", "V", "B", &i__1, ncvt, &work[nm12 + 1], &work[
421 nm13 + 1], &vt[ll + vt_dim1], ldvt);
425 F77_FUNC(slasr,SLASR)("R", "V", "B", nru, &i__1, &work[1], &work[*n], &u[ll *
430 F77_FUNC(slasr,SLASR)("L", "V", "B", &i__1, ncc, &work[1], &work[*n], &c__[
433 if ((r__1 = e[ll], fabs(r__1)) <= thresh) {
440 f = ((r__1 = d__[ll], fabs(r__1)) - shift) * ( ((d__[ll] > 0) ? c_b49 : -c_b49) + shift / d__[ll]);
443 for (i__ = ll; i__ <= i__1; ++i__) {
444 F77_FUNC(slartg,SLARTG)(&f, &g, &cosr, &sinr, &r__);
448 f = cosr * d__[i__] + sinr * e[i__];
449 e[i__] = cosr * e[i__] - sinr * d__[i__];
450 g = sinr * d__[i__ + 1];
451 d__[i__ + 1] = cosr * d__[i__ + 1];
452 F77_FUNC(slartg,SLARTG)(&f, &g, &cosl, &sinl, &r__);
454 f = cosl * e[i__] + sinl * d__[i__ + 1];
455 d__[i__ + 1] = cosl * d__[i__ + 1] - sinl * e[i__];
457 g = sinl * e[i__ + 1];
458 e[i__ + 1] = cosl * e[i__ + 1];
460 work[i__ - ll + 1] = cosr;
461 work[i__ - ll + 1 + nm1] = sinr;
462 work[i__ - ll + 1 + nm12] = cosl;
463 work[i__ - ll + 1 + nm13] = sinl;
469 F77_FUNC(slasr,SLASR)("L", "V", "F", &i__1, ncvt, &work[1], &work[*n], &vt[
470 ll + vt_dim1], ldvt);
474 F77_FUNC(slasr,SLASR)("R", "V", "F", nru, &i__1, &work[nm12 + 1], &work[nm13
475 + 1], &u[ll * u_dim1 + 1], ldu);
479 F77_FUNC(slasr,SLASR)("L", "V", "F", &i__1, ncc, &work[nm12 + 1], &work[nm13
480 + 1], &c__[ll + c_dim1], ldc);
482 if ((r__1 = e[m - 1], fabs(r__1)) <= thresh) {
487 f = ((r__1 = d__[m], fabs(r__1)) - shift) * ( ((d__[m] > 0) ? c_b49 : -c_b49) + shift / d__[m]);
490 for (i__ = m; i__ >= i__1; --i__) {
491 F77_FUNC(slartg,SLARTG)(&f, &g, &cosr, &sinr, &r__);
495 f = cosr * d__[i__] + sinr * e[i__ - 1];
496 e[i__ - 1] = cosr * e[i__ - 1] - sinr * d__[i__];
497 g = sinr * d__[i__ - 1];
498 d__[i__ - 1] = cosr * d__[i__ - 1];
499 F77_FUNC(slartg,SLARTG)(&f, &g, &cosl, &sinl, &r__);
501 f = cosl * e[i__ - 1] + sinl * d__[i__ - 1];
502 d__[i__ - 1] = cosl * d__[i__ - 1] - sinl * e[i__ - 1];
504 g = sinl * e[i__ - 2];
505 e[i__ - 2] = cosl * e[i__ - 2];
507 work[i__ - ll] = cosr;
508 work[i__ - ll + nm1] = -sinr;
509 work[i__ - ll + nm12] = cosl;
510 work[i__ - ll + nm13] = -sinl;
514 if ((r__1 = e[ll], fabs(r__1)) <= thresh) {
519 F77_FUNC(slasr,SLASR)("L", "V", "B", &i__1, ncvt, &work[nm12 + 1], &work[
520 nm13 + 1], &vt[ll + vt_dim1], ldvt);
524 F77_FUNC(slasr,SLASR)("R", "V", "B", nru, &i__1, &work[1], &work[*n], &u[ll *
529 F77_FUNC(slasr,SLASR)("L", "V", "B", &i__1, ncc, &work[1], &work[*n], &c__[
539 for (i__ = 1; i__ <= i__1; ++i__) {
540 if (d__[i__] < 0.f) {
541 d__[i__] = -d__[i__];
544 F77_FUNC(sscal,SSCAL)(ncvt, &c_b72, &vt[i__ + vt_dim1], ldvt);
550 for (i__ = 1; i__ <= i__1; ++i__) {
555 for (j = 2; j <= i__2; ++j) {
556 if (d__[j] <= smin) {
561 if (isub != *n + 1 - i__) {
562 d__[isub] = d__[*n + 1 - i__];
563 d__[*n + 1 - i__] = smin;
565 F77_FUNC(sswap,SSWAP)(ncvt, &vt[isub + vt_dim1], ldvt, &vt[*n + 1 - i__ +
569 F77_FUNC(sswap,SSWAP)(nru, &u[isub * u_dim1 + 1], &c__1, &u[(*n + 1 - i__) *
573 F77_FUNC(sswap,SSWAP)(ncc, &c__[isub + c_dim1], ldc, &c__[*n + 1 - i__ +
583 for (i__ = 1; i__ <= i__1; ++i__) {