📄 dlasd4.c
字号:
#include <math.h>#include "gmx_lapack.h"#include "lapack_limits.h"#include <types/simple.h>void F77_FUNC(dlasd4,DLASD4)(int *n, int *i__, double *d__, double *z__, double *delta, double *rho, double *sigma, double *work, int *info){ int i__1; double d__1; double a, b, c__; int j; double w, dd[3]; int ii; double dw, zz[3]; int ip1; double eta, phi, eps, tau, psi; int iim1, iip1; double dphi, dpsi; int iter; double temp, prew, sg2lb, sg2ub, temp1, temp2, dtiim, delsq, dtiip; int niter; double dtisq; int swtch; double dtnsq; double delsq2, dtnsq1; int swtch3; int orgati; double erretm, dtipsq, rhoinv; --work; --delta; --z__; --d__; *info = 0; if (*n == 1) { *sigma = sqrt(d__[1] * d__[1] + *rho * z__[1] * z__[1]); delta[1] = 1.; work[1] = 1.; return; } if (*n == 2) { F77_FUNC(dlasd5,DLASD5)(i__, &d__[1], &z__[1], &delta[1], rho, sigma, &work[1]); return; } eps = GMX_DOUBLE_EPS; rhoinv = 1. / *rho; if (*i__ == *n) { ii = *n - 1; niter = 1; temp = *rho / 2.; temp1 = temp / (d__[*n] + sqrt(d__[*n] * d__[*n] + temp)); i__1 = *n; for (j = 1; j <= i__1; ++j) { work[j] = d__[j] + d__[*n] + temp1; delta[j] = d__[j] - d__[*n] - temp1; } psi = 0.; i__1 = *n - 2; for (j = 1; j <= i__1; ++j) { psi += z__[j] * z__[j] / (delta[j] * work[j]); } c__ = rhoinv + psi; w = c__ + z__[ii] * z__[ii] / (delta[ii] * work[ii]) + z__[*n] * z__[* n] / (delta[*n] * work[*n]); if (w <= 0.) { temp1 = sqrt(d__[*n] * d__[*n] + *rho); temp = z__[*n - 1] * z__[*n - 1] / ((d__[*n - 1] + temp1) * (d__[* n] - d__[*n - 1] + *rho / (d__[*n] + temp1))) + z__[*n] * z__[*n] / *rho; if (c__ <= temp) { tau = *rho; } else { delsq = (d__[*n] - d__[*n - 1]) * (d__[*n] + d__[*n - 1]); a = -c__ * delsq + z__[*n - 1] * z__[*n - 1] + z__[*n] * z__[* n]; b = z__[*n] * z__[*n] * delsq; if (a < 0.) { tau = b * 2. / (sqrt(a * a + b * 4. * c__) - a); } else { tau = (a + sqrt(a * a + b * 4. * c__)) / (c__ * 2.); } } } else { delsq = (d__[*n] - d__[*n - 1]) * (d__[*n] + d__[*n - 1]); a = -c__ * delsq + z__[*n - 1] * z__[*n - 1] + z__[*n] * z__[*n]; b = z__[*n] * z__[*n] * delsq; if (a < 0.) { tau = b * 2. / (sqrt(a * a + b * 4. * c__) - a); } else { tau = (a + sqrt(a * a + b * 4. * c__)) / (c__ * 2.); } } eta = tau / (d__[*n] + sqrt(d__[*n] * d__[*n] + tau)); *sigma = d__[*n] + eta; i__1 = *n; for (j = 1; j <= i__1; ++j) { delta[j] = d__[j] - d__[*i__] - eta; work[j] = d__[j] + d__[*i__] + eta; } dpsi = 0.; psi = 0.; erretm = 0.; i__1 = ii; for (j = 1; j <= i__1; ++j) { temp = z__[j] / (delta[j] * work[j]); psi += z__[j] * temp; dpsi += temp * temp; erretm += psi; } erretm = fabs(erretm); temp = z__[*n] / (delta[*n] * work[*n]); phi = z__[*n] * temp; dphi = temp * temp; erretm = (-phi - psi) * 8. + erretm - phi + rhoinv + fabs(tau) * (dpsi + dphi); w = rhoinv + phi + psi; if (fabs(w) <= eps * erretm) { goto L240; } ++niter; dtnsq1 = work[*n - 1] * delta[*n - 1]; dtnsq = work[*n] * delta[*n]; c__ = w - dtnsq1 * dpsi - dtnsq * dphi; a = (dtnsq + dtnsq1) * w - dtnsq * dtnsq1 * (dpsi + dphi); b = dtnsq * dtnsq1 * w; if (c__ < 0.) { c__ = fabs(c__); } if ( fabs(c__)<GMX_DOUBLE_MIN) { eta = *rho - *sigma * *sigma; } else if (a >= 0.) { eta = (a + sqrt(fabs(a * a - b * 4. * c__))) / (c__ * 2.); } else { eta = b * 2. / (a - sqrt(fabs(a * a - b * 4. * c__))); } if (w * eta > 0.) { eta = -w / (dpsi + dphi); } temp = eta - dtnsq; if (temp > *rho) { eta = *rho + dtnsq; } tau += eta; eta /= *sigma + sqrt(eta + *sigma * *sigma); i__1 = *n; for (j = 1; j <= i__1; ++j) { delta[j] -= eta; work[j] += eta; } *sigma += eta; dpsi = 0.; psi = 0.; erretm = 0.; i__1 = ii; for (j = 1; j <= i__1; ++j) { temp = z__[j] / (work[j] * delta[j]); psi += z__[j] * temp; dpsi += temp * temp; erretm += psi; } erretm = fabs(erretm); temp = z__[*n] / (work[*n] * delta[*n]); phi = z__[*n] * temp; dphi = temp * temp; erretm = (-phi - psi) * 8. + erretm - phi + rhoinv + fabs(tau) * (dpsi + dphi); w = rhoinv + phi + psi; iter = niter + 1; for (niter = iter; niter <= 20; ++niter) { if (fabs(w) <= eps * erretm) { goto L240; } dtnsq1 = work[*n - 1] * delta[*n - 1]; dtnsq = work[*n] * delta[*n]; c__ = w - dtnsq1 * dpsi - dtnsq * dphi; a = (dtnsq + dtnsq1) * w - dtnsq1 * dtnsq * (dpsi + dphi); b = dtnsq1 * dtnsq * w; if (a >= 0.) { eta = (a + sqrt(fabs(a * a - b * 4. * c__))) / (c__ * 2.); } else { eta = b * 2. / (a - sqrt(fabs(a * a - b * 4. * c__))); } if (w * eta > 0.) { eta = -w / (dpsi + dphi); } temp = eta - dtnsq; if (temp <= 0.) { eta /= 2.; } tau += eta; eta /= *sigma + sqrt(eta + *sigma * *sigma); i__1 = *n; for (j = 1; j <= i__1; ++j) { delta[j] -= eta; work[j] += eta; } *sigma += eta; dpsi = 0.; psi = 0.; erretm = 0.; i__1 = ii; for (j = 1; j <= i__1; ++j) { temp = z__[j] / (work[j] * delta[j]); psi += z__[j] * temp; dpsi += temp * temp; erretm += psi; } erretm = fabs(erretm); temp = z__[*n] / (work[*n] * delta[*n]); phi = z__[*n] * temp; dphi = temp * temp; erretm = (-phi - psi) * 8. + erretm - phi + rhoinv + fabs(tau) * ( dpsi + dphi); w = rhoinv + phi + psi; } *info = 1; goto L240; } else { niter = 1; ip1 = *i__ + 1; delsq = (d__[ip1] - d__[*i__]) * (d__[ip1] + d__[*i__]); delsq2 = delsq / 2.; temp = delsq2 / (d__[*i__] + sqrt(d__[*i__] * d__[*i__] + delsq2)); i__1 = *n; for (j = 1; j <= i__1; ++j) { work[j] = d__[j] + d__[*i__] + temp; delta[j] = d__[j] - d__[*i__] - temp; } psi = 0.; i__1 = *i__ - 1; for (j = 1; j <= i__1; ++j) { psi += z__[j] * z__[j] / (work[j] * delta[j]); } phi = 0.; i__1 = *i__ + 2; for (j = *n; j >= i__1; --j) { phi += z__[j] * z__[j] / (work[j] * delta[j]); } c__ = rhoinv + psi + phi; w = c__ + z__[*i__] * z__[*i__] / (work[*i__] * delta[*i__]) + z__[ ip1] * z__[ip1] / (work[ip1] * delta[ip1]); if (w > 0.) { orgati = 1; sg2lb = 0.; sg2ub = delsq2; a = c__ * delsq + z__[*i__] * z__[*i__] + z__[ip1] * z__[ip1]; b = z__[*i__] * z__[*i__] * delsq; if (a > 0.) { tau = b * 2. / (a + sqrt(fabs(a * a - b * 4. * c__))); } else { tau = (a - sqrt(fabs(a * a - b * 4. * c__))) / (c__ * 2.); } eta = tau / (d__[*i__] + sqrt(d__[*i__] * d__[*i__] + tau)); } else { orgati = 0; sg2lb = -delsq2; sg2ub = 0.; a = c__ * delsq - z__[*i__] * z__[*i__] - z__[ip1] * z__[ip1]; b = z__[ip1] * z__[ip1] * delsq; if (a < 0.) { tau = b * 2. / (a - sqrt(fabs(a * a + b * 4. * c__))); } else { tau = -(a + sqrt(fabs(a * a + b * 4. * c__))) / (c__ * 2.); } eta = tau / (d__[ip1] + sqrt(fabs(d__[ip1] * d__[ip1] + tau))); } if (orgati) { ii = *i__; *sigma = d__[*i__] + eta; i__1 = *n; for (j = 1; j <= i__1; ++j) { work[j] = d__[j] + d__[*i__] + eta; delta[j] = d__[j] - d__[*i__] - eta; } } else { ii = *i__ + 1; *sigma = d__[ip1] + eta; i__1 = *n; for (j = 1; j <= i__1; ++j) { work[j] = d__[j] + d__[ip1] + eta; delta[j] = d__[j] - d__[ip1] - eta; } } iim1 = ii - 1; iip1 = ii + 1; dpsi = 0.; psi = 0.; erretm = 0.; i__1 = iim1; for (j = 1; j <= i__1; ++j) { temp = z__[j] / (work[j] * delta[j]); psi += z__[j] * temp; dpsi += temp * temp; erretm += psi; } erretm = fabs(erretm); dphi = 0.; phi = 0.;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -