4 #include "../gmx_blas.h"
5 #include "../gmx_lapack.h"
7 #include "gromacs/utility/real.h"
10 F77_FUNC(dbdsqr
,DBDSQR
)(const char *uplo
,
26 const char xuplo
= std::toupper(*uplo
);
27 int c_dim1
, c_offset
, u_dim1
, u_offset
, vt_dim1
, vt_offset
, i__1
,
29 double r__1
, r__2
, r__3
, r__4
;
41 int nm1
, nm12
, nm13
, lll
;
42 double eps
, sll
, tol
, abse
;
48 double unfl
, sinl
, cosr
, smin
, smax
, sinr
;
51 double shift
, sigmn
, oldsn
= 0.;
65 vt_offset
= 1 + vt_dim1
;
68 u_offset
= 1 + u_dim1
;
71 c_offset
= 1 + c_dim1
;
77 itmp1
= (*n
> 1) ? *n
: 1;
78 itmp2
= (*nru
> 1) ? *nru
: 1;
80 lower
= (xuplo
== 'L');
81 if ( (xuplo
!='U') && !lower
) {
85 } else if (*ncvt
< 0) {
87 } else if (*nru
< 0) {
89 } else if (*ncc
< 0) {
91 } else if ( ((*ncvt
== 0) && (*ldvt
< 1)) || ((*ncvt
> 0) && (*ldvt
< itmp1
)) ) {
93 } else if (*ldu
< itmp2
) {
95 } else if ( ((*ncc
== 0) && (*ldc
< 1)) || ((*ncc
> 0) && (*ldc
< itmp1
))) {
108 rotate
= *ncvt
> 0 || *nru
> 0 || *ncc
> 0;
111 F77_FUNC(dlasq1
,DLASQ1
)(n
, &d__
[1], &e
[1], &work
[1], info
);
120 eps
= GMX_DOUBLE_EPS
;
121 unfl
= GMX_DOUBLE_MIN
/GMX_DOUBLE_EPS
;
125 for (i__
= 1; i__
<= i__1
; ++i__
) {
126 F77_FUNC(dlartg
,DLARTG
)(&d__
[i__
], &e
[i__
], &cs
, &sn
, &r__
);
128 e
[i__
] = sn
* d__
[i__
+ 1];
129 d__
[i__
+ 1] = cs
* d__
[i__
+ 1];
131 work
[nm1
+ i__
] = sn
;
135 F77_FUNC(dlasr
,DLASR
)("R", "V", "F", nru
, n
, &work
[1], &work
[*n
], &u
[u_offset
],
139 F77_FUNC(dlasr
,DLASR
)("L", "V", "F", n
, ncc
, &work
[1], &work
[*n
], &c__
[c_offset
],
144 r__3
= 100.f
, r__4
= std::pow(GMX_DOUBLE_EPS
,c_b15
);
145 r__1
= 10.f
, r__2
= (r__3
<r__4
) ? r__3
: r__4
;
146 tolmul
= (r__1
>r__2
) ? r__1
: r__2
;
150 for (i__
= 1; i__
<= i__1
; ++i__
) {
151 r__2
= smax
, r__3
= (r__1
= d__
[i__
], std::abs(r__1
));
152 smax
= (r__2
>r__3
) ? r__2
: r__3
;
155 for (i__
= 1; i__
<= i__1
; ++i__
) {
156 r__2
= smax
, r__3
= (r__1
= e
[i__
], std::abs(r__1
));
157 smax
= (r__2
>r__3
) ? r__2
: r__3
;
161 sminoa
= std::abs(d__
[1]);
167 for (i__
= 2; i__
<= i__1
; ++i__
) {
168 mu
= (r__2
= d__
[i__
], std::abs(r__2
)) * (mu
/ (mu
+ (r__1
= e
[i__
-
169 1], std::abs(r__1
))));
170 sminoa
= (sminoa
<mu
) ? sminoa
: mu
;
176 sminoa
/= std::sqrt((double) (*n
));
177 r__1
= tol
* sminoa
, r__2
= *n
* 6 * *n
* unfl
;
178 thresh
= (r__1
>r__2
) ? r__1
: r__2
;
180 r__1
= std::abs(tol
) * smax
, r__2
= *n
* 6 * *n
* unfl
;
181 thresh
= (r__1
>r__2
) ? r__1
: r__2
;
198 if (tol
< 0.f
&& (r__1
= d__
[m
], std::abs(r__1
)) <= thresh
) {
201 smax
= (r__1
= d__
[m
], std::abs(r__1
));
204 for (lll
= 1; lll
<= i__1
; ++lll
) {
206 abss
= (r__1
= d__
[ll
], std::abs(r__1
));
207 abse
= (r__1
= e
[ll
], std::abs(r__1
));
208 if (tol
< 0.f
&& abss
<= thresh
) {
211 if (abse
<= thresh
) {
214 smin
= (smin
<abss
) ? smin
: abss
;
215 r__1
= (smax
>abss
) ? smax
: abss
;
216 smax
= (r__1
>abse
) ? r__1
: abse
;
229 F77_FUNC(dlasv2
,DLASV2
)(&d__
[m
- 1], &e
[m
- 1], &d__
[m
], &sigmn
, &sigmx
, &sinr
, &cosr
,
235 F77_FUNC(drot
,DROT
)(ncvt
, &vt
[m
- 1 + vt_dim1
], ldvt
, &vt
[m
+ vt_dim1
], ldvt
, &
239 F77_FUNC(drot
,DROT
)(nru
, &u
[(m
- 1) * u_dim1
+ 1], &c__1
, &u
[m
* u_dim1
+ 1], &
243 F77_FUNC(drot
,DROT
)(ncc
, &c__
[m
- 1 + c_dim1
], ldc
, &c__
[m
+ c_dim1
], ldc
, &
249 if (ll
> oldm
|| m
< oldll
) {
250 if ((r__1
= d__
[ll
], std::abs(r__1
)) >= (r__2
= d__
[m
], std::abs(r__2
))) {
258 if( (std::abs(e
[m
-1]) <= std::abs(tol
) * std::abs(d__
[m
])) ||
259 (tol
<0.0 && std::abs(e
[m
-1])<=thresh
)) {
264 mu
= (r__1
= d__
[ll
], std::abs(r__1
));
267 for (lll
= ll
; lll
<= i__1
; ++lll
) {
268 if ((r__1
= e
[lll
], std::abs(r__1
)) <= tol
* mu
) {
272 mu
= (r__2
= d__
[lll
+ 1], std::abs(r__2
)) * (mu
/ (mu
+ (r__1
=
273 e
[lll
], std::abs(r__1
))));
274 sminl
= (sminl
<mu
) ? sminl
: mu
;
278 if( (std::abs(e
[ll
]) <= std::abs(tol
)*std::abs(d__
[ll
])) ||
279 (tol
<0.0 && std::abs(e
[ll
])<=thresh
)) {
284 mu
= (r__1
= d__
[m
], std::abs(r__1
));
287 for (lll
= m
- 1; lll
>= i__1
; --lll
) {
288 if ((r__1
= e
[lll
], std::abs(r__1
)) <= tol
* mu
) {
292 mu
= (r__2
= d__
[lll
], std::abs(r__2
)) * (mu
/ (mu
+ (r__1
= e
[
293 lll
], std::abs(r__1
))));
294 sminl
= (sminl
<mu
) ? sminl
: mu
;
301 r__1
= eps
, r__2
= tol
* .01f
;
302 if (tol
>= 0.f
&& *n
* tol
* (sminl
/ smax
) <= ((r__1
>r__2
) ? r__1
: r__2
)) {
306 sll
= (r__1
= d__
[ll
], std::abs(r__1
));
307 F77_FUNC(dlas2
,DLAS2
)(&d__
[m
- 1], &e
[m
- 1], &d__
[m
], &shift
, &r__
);
309 sll
= (r__1
= d__
[m
], std::abs(r__1
));
310 F77_FUNC(dlas2
,DLAS2
)(&d__
[ll
], &e
[ll
], &d__
[ll
+ 1], &shift
, &r__
);
314 if (r__1
* r__1
< eps
) {
319 iter
= iter
+ m
- ll
;
325 for (i__
= ll
; i__
<= i__1
; ++i__
) {
326 r__1
= d__
[i__
] * cs
;
327 F77_FUNC(dlartg
,DLARTG
)(&r__1
, &e
[i__
], &cs
, &sn
, &r__
);
329 e
[i__
- 1] = oldsn
* r__
;
332 r__2
= d__
[i__
+ 1] * sn
;
333 F77_FUNC(dlartg
,DLARTG
)(&r__1
, &r__2
, &oldcs
, &oldsn
, &d__
[i__
]);
334 work
[i__
- ll
+ 1] = cs
;
335 work
[i__
- ll
+ 1 + nm1
] = sn
;
336 work
[i__
- ll
+ 1 + nm12
] = oldcs
;
337 work
[i__
- ll
+ 1 + nm13
] = oldsn
;
340 d__
[m
] = h__
* oldcs
;
341 e
[m
- 1] = h__
* oldsn
;
344 F77_FUNC(dlasr
,DLASR
)("L", "V", "F", &i__1
, ncvt
, &work
[1], &work
[*n
], &vt
[
345 ll
+ vt_dim1
], ldvt
);
349 F77_FUNC(dlasr
,DLASR
)("R", "V", "F", nru
, &i__1
, &work
[nm12
+ 1], &work
[nm13
350 + 1], &u
[ll
* u_dim1
+ 1], ldu
);
354 F77_FUNC(dlasr
,DLASR
)("L", "V", "F", &i__1
, ncc
, &work
[nm12
+ 1], &work
[nm13
355 + 1], &c__
[ll
+ c_dim1
], ldc
);
357 if ((r__1
= e
[m
- 1], std::abs(r__1
)) <= thresh
) {
364 for (i__
= m
; i__
>= i__1
; --i__
) {
365 r__1
= d__
[i__
] * cs
;
366 F77_FUNC(dlartg
,DLARTG
)(&r__1
, &e
[i__
- 1], &cs
, &sn
, &r__
);
368 e
[i__
] = oldsn
* r__
;
371 r__2
= d__
[i__
- 1] * sn
;
372 F77_FUNC(dlartg
,DLARTG
)(&r__1
, &r__2
, &oldcs
, &oldsn
, &d__
[i__
]);
374 work
[i__
- ll
+ nm1
] = -sn
;
375 work
[i__
- ll
+ nm12
] = oldcs
;
376 work
[i__
- ll
+ nm13
] = -oldsn
;
379 d__
[ll
] = h__
* oldcs
;
383 F77_FUNC(dlasr
,DLASR
)("L", "V", "B", &i__1
, ncvt
, &work
[nm12
+ 1], &work
[
384 nm13
+ 1], &vt
[ll
+ vt_dim1
], ldvt
);
388 F77_FUNC(dlasr
,DLASR
)("R", "V", "B", nru
, &i__1
, &work
[1], &work
[*n
], &u
[ll
*
393 F77_FUNC(dlasr
,DLASR
)("L", "V", "B", &i__1
, ncc
, &work
[1], &work
[*n
], &c__
[
396 if ((r__1
= e
[ll
], std::abs(r__1
)) <= thresh
) {
403 f
= ((r__1
= d__
[ll
], std::abs(r__1
)) - shift
) * ( ((d__
[ll
] > 0) ? c_b49
: -c_b49
) + shift
/ d__
[ll
]);
406 for (i__
= ll
; i__
<= i__1
; ++i__
) {
407 F77_FUNC(dlartg
,DLARTG
)(&f
, &g
, &cosr
, &sinr
, &r__
);
411 f
= cosr
* d__
[i__
] + sinr
* e
[i__
];
412 e
[i__
] = cosr
* e
[i__
] - sinr
* d__
[i__
];
413 g
= sinr
* d__
[i__
+ 1];
414 d__
[i__
+ 1] = cosr
* d__
[i__
+ 1];
415 F77_FUNC(dlartg
,DLARTG
)(&f
, &g
, &cosl
, &sinl
, &r__
);
417 f
= cosl
* e
[i__
] + sinl
* d__
[i__
+ 1];
418 d__
[i__
+ 1] = cosl
* d__
[i__
+ 1] - sinl
* e
[i__
];
420 g
= sinl
* e
[i__
+ 1];
421 e
[i__
+ 1] = cosl
* e
[i__
+ 1];
423 work
[i__
- ll
+ 1] = cosr
;
424 work
[i__
- ll
+ 1 + nm1
] = sinr
;
425 work
[i__
- ll
+ 1 + nm12
] = cosl
;
426 work
[i__
- ll
+ 1 + nm13
] = sinl
;
432 F77_FUNC(dlasr
,DLASR
)("L", "V", "F", &i__1
, ncvt
, &work
[1], &work
[*n
], &vt
[
433 ll
+ vt_dim1
], ldvt
);
437 F77_FUNC(dlasr
,DLASR
)("R", "V", "F", nru
, &i__1
, &work
[nm12
+ 1], &work
[nm13
438 + 1], &u
[ll
* u_dim1
+ 1], ldu
);
442 F77_FUNC(dlasr
,DLASR
)("L", "V", "F", &i__1
, ncc
, &work
[nm12
+ 1], &work
[nm13
443 + 1], &c__
[ll
+ c_dim1
], ldc
);
445 if ((r__1
= e
[m
- 1], std::abs(r__1
)) <= thresh
) {
450 f
= ((r__1
= d__
[m
], std::abs(r__1
)) - shift
) * ( ((d__
[m
] > 0) ? c_b49
: -c_b49
) + shift
/ d__
[m
]);
453 for (i__
= m
; i__
>= i__1
; --i__
) {
454 F77_FUNC(dlartg
,DLARTG
)(&f
, &g
, &cosr
, &sinr
, &r__
);
458 f
= cosr
* d__
[i__
] + sinr
* e
[i__
- 1];
459 e
[i__
- 1] = cosr
* e
[i__
- 1] - sinr
* d__
[i__
];
460 g
= sinr
* d__
[i__
- 1];
461 d__
[i__
- 1] = cosr
* d__
[i__
- 1];
462 F77_FUNC(dlartg
,DLARTG
)(&f
, &g
, &cosl
, &sinl
, &r__
);
464 f
= cosl
* e
[i__
- 1] + sinl
* d__
[i__
- 1];
465 d__
[i__
- 1] = cosl
* d__
[i__
- 1] - sinl
* e
[i__
- 1];
467 g
= sinl
* e
[i__
- 2];
468 e
[i__
- 2] = cosl
* e
[i__
- 2];
470 work
[i__
- ll
] = cosr
;
471 work
[i__
- ll
+ nm1
] = -sinr
;
472 work
[i__
- ll
+ nm12
] = cosl
;
473 work
[i__
- ll
+ nm13
] = -sinl
;
477 if ((r__1
= e
[ll
], std::abs(r__1
)) <= thresh
) {
482 F77_FUNC(dlasr
,DLASR
)("L", "V", "B", &i__1
, ncvt
, &work
[nm12
+ 1], &work
[
483 nm13
+ 1], &vt
[ll
+ vt_dim1
], ldvt
);
487 F77_FUNC(dlasr
,DLASR
)("R", "V", "B", nru
, &i__1
, &work
[1], &work
[*n
], &u
[ll
*
492 F77_FUNC(dlasr
,DLASR
)("L", "V", "B", &i__1
, ncc
, &work
[1], &work
[*n
], &c__
[
502 for (i__
= 1; i__
<= i__1
; ++i__
) {
503 if (d__
[i__
] < 0.f
) {
504 d__
[i__
] = -d__
[i__
];
507 F77_FUNC(dscal
,DSCAL
)(ncvt
, &c_b72
, &vt
[i__
+ vt_dim1
], ldvt
);
513 for (i__
= 1; i__
<= i__1
; ++i__
) {
518 for (j
= 2; j
<= i__2
; ++j
) {
519 if (d__
[j
] <= smin
) {
524 if (isub
!= *n
+ 1 - i__
) {
525 d__
[isub
] = d__
[*n
+ 1 - i__
];
526 d__
[*n
+ 1 - i__
] = smin
;
528 F77_FUNC(dswap
,DSWAP
)(ncvt
, &vt
[isub
+ vt_dim1
], ldvt
, &vt
[*n
+ 1 - i__
+
532 F77_FUNC(dswap
,DSWAP
)(nru
, &u
[isub
* u_dim1
+ 1], &c__1
, &u
[(*n
+ 1 - i__
) *
536 F77_FUNC(dswap
,DSWAP
)(ncc
, &c__
[isub
+ c_dim1
], ldc
, &c__
[*n
+ 1 - i__
+
546 for (i__
= 1; i__
<= i__1
; ++i__
) {