TEST(generateExpression, index_op) { static const bool user_facing = true; std::stringstream msgs; // expr: row_vector stan::lang::double_literal dblLit(5.1); dblLit.string_ = "5.1"; stan::lang::expression e1 = dblLit; std::vector<stan::lang::expression> elements; elements.push_back(e1); elements.push_back(e1); stan::lang::row_vector_expr rv1(elements); stan::lang::expression e2 = rv1; // dimensions: vector of vector of dimensions std::vector<std::vector<stan::lang::expression> > dimss; std::vector<stan::lang::expression> dim; dim.push_back(stan::lang::int_literal(1)); dimss.push_back(dim); stan::lang::index_op i_op(e2, dimss); stan::lang::expression e3 = i_op; // result is index into row_vector generate_expression(e3, user_facing, msgs); EXPECT_NE(msgs.str().find("stan::math::to_row_vector"), std::string::npos); EXPECT_NE(msgs.str().find("stan::math::array_builder<double"), std::string::npos); EXPECT_NE(msgs.str().find("add(5.1).array()"), std::string::npos); EXPECT_NE(msgs.str().find("[1]"), std::string::npos); }
TEST(generateExpression, row_vector_expr) { static const bool user_facing = true; std::stringstream msgs; stan::lang::double_literal dblLit(5.1); dblLit.string_ = "5.1"; stan::lang::expression e1 = dblLit; std::vector<stan::lang::expression> elements; elements.push_back(e1); elements.push_back(e1); stan::lang::row_vector_expr rv1(elements); stan::lang::expression e2 = rv1; generate_expression(e2, user_facing, msgs); EXPECT_NE(msgs.str().find("stan::math::to_row_vector"), std::string::npos); EXPECT_NE(msgs.str().find("stan::math::array_builder<double"), std::string::npos); EXPECT_NE(msgs.str().find("add(5.1).array()"), std::string::npos); }
Foam::SVD::SVD(const scalarRectangularMatrix& A, const scalar minCondition) : U_(A), V_(A.m(), A.m()), S_(A.m()), VSinvUt_(A.m(), A.n()), nZeros_(0) { // SVDcomp to find U_, V_ and S_ - the singular values const label Um = U_.m(); const label Un = U_.n(); scalarList rv1(Um); scalar g = 0; scalar scale = 0; scalar s = 0; scalar anorm = 0; label l = 0; for (label i = 0; i < Um; i++) { l = i+2; rv1[i] = scale*g; g = s = scale = 0; if (i < Un) { for (label k = i; k < Un; k++) { scale += mag(U_[k][i]); } if (scale != 0) { for (label k = i; k < Un; k++) { U_[k][i] /= scale; s += U_[k][i]*U_[k][i]; } scalar f = U_[i][i]; g = -sign(Foam::sqrt(s), f); scalar h = f*g - s; U_[i][i] = f - g; for (label j = l-1; j < Um; j++) { s = 0; for (label k = i; k < Un; k++) { s += U_[k][i]*U_[k][j]; } f = s/h; for (label k = i; k < A.n(); k++) { U_[k][j] += f*U_[k][i]; } } for (label k = i; k < Un; k++) { U_[k][i] *= scale; } } } S_[i] = scale*g; g = s = scale = 0; if (i+1 <= Un && i != Um) { for (label k = l-1; k < Um; k++) { scale += mag(U_[i][k]); } if (scale != 0) { for (label k=l-1; k < Um; k++) { U_[i][k] /= scale; s += U_[i][k]*U_[i][k]; } scalar f = U_[i][l-1]; g = -sign(Foam::sqrt(s),f); scalar h = f*g - s; U_[i][l-1] = f - g; for (label k = l-1; k < Um; k++) { rv1[k] = U_[i][k]/h; } for (label j = l-1; j < Un; j++) { s = 0; for (label k = l-1; k < Um; k++) { s += U_[j][k]*U_[i][k]; } for (label k = l-1; k < Um; k++) { U_[j][k] += s*rv1[k]; } } for (label k = l-1; k < Um; k++) { U_[i][k] *= scale; } } } anorm = max(anorm, mag(S_[i]) + mag(rv1[i])); } for (label i = Um-1; i >= 0; i--) { if (i < Um-1) { if (g != 0) { for (label j = l; j < Um; j++) { V_[j][i] = (U_[i][j]/U_[i][l])/g; } for (label j=l; j < Um; j++) { s = 0; for (label k = l; k < Um; k++) { s += U_[i][k]*V_[k][j]; } for (label k = l; k < Um; k++) { V_[k][j] += s*V_[k][i]; } } } for (label j = l; j < Um;j++) { V_[i][j] = V_[j][i] = 0.0; } } V_[i][i] = 1; g = rv1[i]; l = i; } for (label i = min(Um, Un) - 1; i >= 0; i--) { l = i+1; g = S_[i]; for (label j = l; j < Um; j++) { U_[i][j] = 0.0; } if (g != 0) { g = 1.0/g; for (label j = l; j < Um; j++) { s = 0; for (label k = l; k < Un; k++) { s += U_[k][i]*U_[k][j]; } scalar f = (s/U_[i][i])*g; for (label k = i; k < Un; k++) { U_[k][j] += f*U_[k][i]; } } for (label j = i; j < Un; j++) { U_[j][i] *= g; } } else { for (label j = i; j < Un; j++) { U_[j][i] = 0.0; } } ++U_[i][i]; } for (label k = Um-1; k >= 0; k--) { for (label its = 0; its < 35; its++) { bool flag = true; label nm; for (l = k; l >= 0; l--) { nm = l-1; if (mag(rv1[l]) + anorm == anorm) { flag = false; break; } if (mag(S_[nm]) + anorm == anorm) break; } if (flag) { scalar c = 0.0; s = 1.0; for (label i = l-1; i < k+1; i++) { scalar f = s*rv1[i]; rv1[i] = c*rv1[i]; if (mag(f) + anorm == anorm) break; g = S_[i]; scalar h = sqrtSumSqr(f, g); S_[i] = h; h = 1.0/h; c = g*h; s = -f*h; for (label j = 0; j < Un; j++) { scalar y = U_[j][nm]; scalar z = U_[j][i]; U_[j][nm] = y*c + z*s; U_[j][i] = z*c - y*s; } } } scalar z = S_[k]; if (l == k) { if (z < 0.0) { S_[k] = -z; for (label j = 0; j < Um; j++) V_[j][k] = -V_[j][k]; } break; } if (its == 34) { WarningIn ( "SVD::SVD" "(scalarRectangularMatrix& A, const scalar minCondition)" ) << "no convergence in 35 SVD iterations" << endl; } scalar x = S_[l]; nm = k-1; scalar y = S_[nm]; g = rv1[nm]; scalar h = rv1[k]; scalar f = ((y - z)*(y + z) + (g - h)*(g + h))/(2.0*h*y); g = sqrtSumSqr(f, scalar(1)); f = ((x - z)*(x + z) + h*((y/(f + sign(g, f))) - h))/x; scalar c = 1.0; s = 1.0; for (label j = l; j <= nm; j++) { label i = j + 1; g = rv1[i]; y = S_[i]; h = s*g; g = c*g; scalar z = sqrtSumSqr(f, h); rv1[j] = z; c = f/z; s = h/z; f = x*c + g*s; g = g*c - x*s; h = y*s; y *= c; for (label jj = 0; jj < Um; jj++) { x = V_[jj][j]; z = V_[jj][i]; V_[jj][j] = x*c + z*s; V_[jj][i] = z*c - x*s; } z = sqrtSumSqr(f, h); S_[j] = z; if (z) { z = 1.0/z; c = f*z; s = h*z; } f = c*g + s*y; x = c*y - s*g; for (label jj=0; jj < Un; jj++) { y = U_[jj][j]; z = U_[jj][i]; U_[jj][j] = y*c + z*s; U_[jj][i] = z*c - y*s; } } rv1[l] = 0.0; rv1[k] = f; S_[k] = x; } } // zero singular values that are less than minCondition*maxS const scalar minS = minCondition*S_[findMax(S_)]; forAll(S_, i) { if (S_[i] <= minS) { //Info<< "Removing " << S_[i] << " < " << minS << endl; S_[i] = 0; nZeros_++; } } // now multiply out to find the pseudo inverse of A, VSinvUt_ multiply(VSinvUt_, V_, inv(S_), U_.T()); // test SVD /*scalarRectangularMatrix SVDA(A.n(), A.m()); multiply(SVDA, U_, S_, transpose(V_)); scalar maxDiff = 0; scalar diff = 0; for (label i = 0; i < A.n(); i++) { for (label j = 0; j < A.m(); j++) { diff = mag(A[i][j] - SVDA[i][j]); if (diff > maxDiff) maxDiff = diff; } } Info<< "Maximum discrepancy between A and svd(A) = " << maxDiff << endl; if (maxDiff > 4) { Info<< "singular values " << S_ << endl; } */ }
void SVD::decompose() { bool flag; Int i,its,j,jj,k,l,nm; Doub anorm,c,f,g,h,s,scale,x,y,z; VecDoub rv1(n); g = scale = anorm = 0.0; for (i=0;i<n;i++) { l=i+2; rv1[i]=scale*g; g=s=scale=0.0; if (i < m) { for (k=i;k<m;k++) scale += abs(u[k][i]); if (scale != 0.0) { for (k=i;k<m;k++) { u[k][i] /= scale; s += u[k][i]*u[k][i]; } f=u[i][i]; g = -SIGN(sqrt(s),f); h=f*g-s; u[i][i]=f-g; for (j=l-1;j<n;j++) { for (s=0.0,k=i;k<m;k++) s += u[k][i]*u[k][j]; f=s/h; for (k=i;k<m;k++) u[k][j] += f*u[k][i]; } for (k=i;k<m;k++) u[k][i] *= scale; } } w[i]=scale *g; g=s=scale=0.0; if (i+1 <= m && i+1 != n) { for (k=l-1;k<n;k++) scale += abs(u[i][k]); if (scale != 0.0) { for (k=l-1;k<n;k++) { u[i][k] /= scale; s += u[i][k]*u[i][k]; } f=u[i][l-1]; g = -SIGN(sqrt(s),f); h=f*g-s; u[i][l-1]=f-g; for (k=l-1;k<n;k++) rv1[k]=u[i][k]/h; for (j=l-1;j<m;j++) { for (s=0.0,k=l-1;k<n;k++) s += u[j][k]*u[i][k]; for (k=l-1;k<n;k++) u[j][k] += s*rv1[k]; } for (k=l-1;k<n;k++) u[i][k] *= scale; } } anorm=MAX(anorm,(abs(w[i])+abs(rv1[i]))); } for (i=n-1;i>=0;i--) { if (i < n-1) { if (g != 0.0) { for (j=l;j<n;j++) v[j][i]=(u[i][j]/u[i][l])/g; for (j=l;j<n;j++) { for (s=0.0,k=l;k<n;k++) s += u[i][k]*v[k][j]; for (k=l;k<n;k++) v[k][j] += s*v[k][i]; } } for (j=l;j<n;j++) v[i][j]=v[j][i]=0.0; } v[i][i]=1.0; g=rv1[i]; l=i; } for (i=MIN(m,n)-1;i>=0;i--) { l=i+1; g=w[i]; for (j=l;j<n;j++) u[i][j]=0.0; if (g != 0.0) { g=1.0/g; for (j=l;j<n;j++) { for (s=0.0,k=l;k<m;k++) s += u[k][i]*u[k][j]; f=(s/u[i][i])*g; for (k=i;k<m;k++) u[k][j] += f*u[k][i]; } for (j=i;j<m;j++) u[j][i] *= g; } else for (j=i;j<m;j++) u[j][i]=0.0; ++u[i][i]; } for (k=n-1;k>=0;k--) { for (its=0;its<30;its++) { flag=true; for (l=k;l>=0;l--) { nm=l-1; if (l == 0 || abs(rv1[l]) <= eps*anorm) { flag=false; break; } if (abs(w[nm]) <= eps*anorm) break; } if (flag) { c=0.0; s=1.0; for (i=l;i<k+1;i++) { f=s*rv1[i]; rv1[i]=c*rv1[i]; if (abs(f) <= eps*anorm) break; g=w[i]; h=pythag(f,g); w[i]=h; h=1.0/h; c=g*h; s = -f*h; for (j=0;j<m;j++) { y=u[j][nm]; z=u[j][i]; u[j][nm]=y*c+z*s; u[j][i]=z*c-y*s; } } } z=w[k]; if (l == k) { if (z < 0.0) { w[k] = -z; for (j=0;j<n;j++) v[j][k] = -v[j][k]; } break; } if (its == 29) throw("no convergence in 30 svdcmp iterations"); x=w[l]; nm=k-1; y=w[nm]; g=rv1[nm]; h=rv1[k]; f=((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y); g=pythag(f,1.0); f=((x-z)*(x+z)+h*((y/(f+SIGN(g,f)))-h))/x; c=s=1.0; for (j=l;j<=nm;j++) { i=j+1; g=rv1[i]; y=w[i]; h=s*g; g=c*g; z=pythag(f,h); rv1[j]=z; c=f/z; s=h/z; f=x*c+g*s; g=g*c-x*s; h=y*s; y *= c; for (jj=0;jj<n;jj++) { x=v[jj][j]; z=v[jj][i]; v[jj][j]=x*c+z*s; v[jj][i]=z*c-x*s; } z=pythag(f,h); w[j]=z; if (z) { z=1.0/z; c=f*z; s=h*z; } f=c*g+s*y; x=c*y-s*g; for (jj=0;jj<m;jj++) { y=u[jj][j]; z=u[jj][i]; u[jj][j]=y*c+z*s; u[jj][i]=z*c-y*s; } } rv1[l]=0.0; rv1[k]=f; w[k]=x; } } }
bool svdCoreT(AddressableMatrix<R> & U, long rows, long cols, S * D, AddressableMatrix<T> & V) { static int const MAX_ITERATIONS = 30; if (rows == 0 && cols == 0) return true; debugAssertM(rows >= cols, "SVD: Matrix must have more rows than columns"); long i, j, jj, k, l = 0, nm = 0; int flag, its; double c, f, h, s, x, y, z; double anorm = 0.0, g = 0.0, scale = 0.0; // Temp row vector TheaArray<double> rv1((array_size_t)cols); // Householder reduction to bidiagonal form for (i = 0; i < cols; ++i) { // Left-hand reduction l = i + 1; rv1[i] = scale * g; g = s = scale = 0.0; if (i < rows) { for (k = i; k < rows; ++k) { scale += std::fabs((double)U.get(k, i)); } if (scale) { for (k = i; k < rows; ++k) { double x = (double)U.get(k, i) / scale; U.set(k, i, x); s += (x * x); } f = (double)U.get(i, i); g = -SVD_SIGN(std::sqrt(s), f); h = f * g - s; U.set(i, i, (R)(f - g)); if (i != cols - 1) { for (j = l; j < cols; j++) { for (s = 0.0, k = i; k < rows; ++k) { s += ((double)U.get(k, i) * (double)U.get(k, j)); } f = s / h; for (k = i; k < rows; ++k) { U.getMutable(k, j) += (R)(f * (double)U.get(k, i)); } } } for (k = i; k < rows; ++k) { U.getMutable(k, i) *= (R)scale; } } } D[i] = (S)(scale * g); // right-hand reduction g = s = scale = 0.0; if (i < rows && i != cols - 1) { for (k = l; k < cols; ++k) { scale += std::fabs((double)U.get(i, k)); } if (scale) { for (k = l; k < cols; ++k) { double x = (double)U.get(i, k) / scale; U.set(i, k, (R)x); s += (x * x); } f = (double)U.get(i, l); g = -SVD_SIGN(std::sqrt(s), f); h = f * g - s; U.set(i, l, (R)(f - g)); for (k = l; k < cols; ++k) { rv1[k] = (double)U.get(i, k) / h; } if (i != rows - 1) { for (j = l; j < rows; ++j) { for (s = 0.0, k = l; k < cols; ++k) { s += ((double)U.get(j, k) * (double)U.get(i, k)); } for (k = l; k < cols; ++k) { U.getMutable(j, k) += (R)(s * rv1[k]); } } } for (k = l; k < cols; ++k) { U.getMutable(i, k) *= (R)scale; } } } anorm = std::max(anorm, std::fabs((double)D[i]) + std::fabs(rv1[i])); } // accumulate the right-hand transformation for (i = cols - 1; i >= 0; --i) { if (i < cols - 1) { if (g != 0.0) { for (j = l; j < cols; j++) { V.set(j, i, (T)(((double)U.get(i, j) / (double)U.get(i, l)) / g)); } // double division to avoid underflow for (j = l; j < cols; ++j) { for (s = 0.0, k = l; k < cols; k++) { s += ((double)U.get(i, k) * (double)V.get(k, j)); } for (k = l; k < cols; ++k) { V.getMutable(k, j) += (T)(s * (double)V.get(k, i)); } } } for (j = l; j < cols; ++j) { V.set(i, j, 0.0); V.set(j, i, 0.0); } } V.set(i, i, 1.0); g = rv1[i]; l = i; } // accumulate the left-hand transformation for (i = cols - 1; i >= 0; --i) { l = i + 1; g = (double)D[i]; if (i < cols - 1) { for (j = l; j < cols; ++j) { U.set(i, j, 0.0); } } if (g) { g = 1.0 / g; if (i != cols - 1) { for (j = l; j < cols; ++j) { for (s = 0.0, k = l; k < rows; ++k) { s += ((double)U.get(k, i) * (double)U.get(k, j)); } f = (s / (double)U.get(i, i)) * g; for (k = i; k < rows; ++k) { U.getMutable(k, j) += (R)(f * (double)U.get(k, i)); } } } for (j = i; j < rows; ++j) { U.getMutable(j, i) *= (R)g; } } else { for (j = i; j < rows; ++j) { U.set(j, i, 0.0); } } U.getMutable(i, i)++; } // diagonalize the bidiagonal form for (k = cols - 1; k >= 0; --k) { // loop over singular values for (its = 0; its < MAX_ITERATIONS; ++its) { // loop over allowed iterations flag = 1; for (l = k; l >= 0; --l) { // test for splitting nm = l - 1; if (std::fabs(rv1[l]) + anorm == anorm) { flag = 0; break; } if (std::fabs((double)D[nm]) + anorm == anorm) { break; } } if (flag) { c = 0.0; s = 1.0; for (i = l; i <= k; ++i) { f = s * rv1[i]; if (std::fabs(f) + anorm != anorm) { g = (double)D[i]; h = pythag(f, g); D[i] = (S)h; h = 1.0 / h; c = g * h; s = (- f * h); for (j = 0; j < rows; ++j) { y = (double)U.get(j, nm); z = (double)U.get(j, i); U.set(j, nm, (R)(y * c + z * s)); U.set(j, i, (R)(z * c - y * s)); } } } } z = (double)D[k]; if (l == k) { // convergence if (z < 0.0) { // make singular value nonnegative D[k] = (S)(-z); for (j = 0; j < cols; ++j) { V.set(j, k, -V.get(j, k)); } } break; } if (its >= MAX_ITERATIONS) { THEA_DEBUG << "SVD: Failed to converge"; return false; } // shift from bottom 2 x 2 minor x = (double)D[l]; nm = k - 1; y = (double)D[nm]; g = rv1[nm]; h = rv1[k]; f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y); g = pythag(f, 1.0); f = ((x - z) * (x + z) + h * ((y / (f + SVD_SIGN(g, f))) - h)) / x; // next QR transformation c = s = 1.0; for (j = l; j <= nm; ++j) { i = j + 1; g = rv1[i]; y = (double)D[i]; h = s * g; g = c * g; z = pythag(f, h); rv1[j] = z; c = f / z; s = h / z; f = x * c + g * s; g = g * c - x * s; h = y * s; y = y * c; for (jj = 0; jj < cols; ++jj) { x = (double)V.get(jj, j); z = (double)V.get(jj, i); V.set(jj, j, (T)(x * c + z * s)); V.set(jj, i, (T)(z * c - x * s)); } z = pythag(f, h); D[j] = (S)z; if (z) { z = 1.0 / z; c = f * z; s = h * z; } f = (c * g) + (s * y); x = (c * y) - (s * g); for (jj = 0; jj < rows; jj++) { y = (double)U.get(jj, j); z = (double)U.get(jj, i); U.set(jj, j, (R)(y * c + z * s)); U.set(jj, i, (R)(z * c - y * s)); } } rv1[l] = 0.0; rv1[k] = f; D[k] = (S)x; } } // So far V actually contains V^T, so we transpose V in-place for (i = 0; i < rows; ++i) for (j = i + 1; j < cols; ++j) std::swap(V.getMutable(i, j), V.getMutable(j, i)); return true; }
bool obsoletesvddecomposition(ap::real_2d_array& a, int m, int n, ap::real_1d_array& w, ap::real_2d_array& v) { bool result; int nm; int minmn; int l; int k; int j; int jj; int its; int i; double z; double y; double x; double vscale; double s; double h; double g; double f; double c; double anorm; ap::real_1d_array rv1; bool flag; rv1.setbounds(1, n); w.setbounds(1, n); v.setbounds(1, n, 1, n); result = true; if( m<n ) { minmn = m; } else { minmn = n; } g = 0.0; vscale = 0.0; anorm = 0.0; for(i = 1; i <= n; i++) { l = i+1; rv1(i) = vscale*g; g = 0; s = 0; vscale = 0; if( i<=m ) { for(k = i; k <= m; k++) { vscale = vscale+fabs(a(k,i)); } if( ap::fp_neq(vscale,0.0) ) { for(k = i; k <= m; k++) { a(k,i) = a(k,i)/vscale; s = s+a(k,i)*a(k,i); } f = a(i,i); g = -extsign(sqrt(s), f); h = f*g-s; a(i,i) = f-g; if( i!=n ) { for(j = l; j <= n; j++) { s = 0.0; for(k = i; k <= m; k++) { s = s+a(k,i)*a(k,j); } f = s/h; for(k = i; k <= m; k++) { a(k,j) = a(k,j)+f*a(k,i); } } } for(k = i; k <= m; k++) { a(k,i) = vscale*a(k,i); } } } w(i) = vscale*g; g = 0.0; s = 0.0; vscale = 0.0; if( i<=m&&i!=n ) { for(k = l; k <= n; k++) { vscale = vscale+fabs(a(i,k)); } if( ap::fp_neq(vscale,0.0) ) { for(k = l; k <= n; k++) { a(i,k) = a(i,k)/vscale; s = s+a(i,k)*a(i,k); } f = a(i,l); g = -extsign(sqrt(s), f); h = f*g-s; a(i,l) = f-g; for(k = l; k <= n; k++) { rv1(k) = a(i,k)/h; } if( i!=m ) { for(j = l; j <= m; j++) { s = 0.0; for(k = l; k <= n; k++) { s = s+a(j,k)*a(i,k); } for(k = l; k <= n; k++) { a(j,k) = a(j,k)+s*rv1(k); } } } for(k = l; k <= n; k++) { a(i,k) = vscale*a(i,k); } } } anorm = mymax(anorm, fabs(w(i))+fabs(rv1(i))); } for(i = n; i >= 1; i--) { if( i<n ) { if( ap::fp_neq(g,0.0) ) { for(j = l; j <= n; j++) { v(j,i) = a(i,j)/a(i,l)/g; } for(j = l; j <= n; j++) { s = 0.0; for(k = l; k <= n; k++) { s = s+a(i,k)*v(k,j); } for(k = l; k <= n; k++) { v(k,j) = v(k,j)+s*v(k,i); } } } for(j = l; j <= n; j++) { v(i,j) = 0.0; v(j,i) = 0.0; } } v(i,i) = 1.0; g = rv1(i); l = i; } for(i = minmn; i >= 1; i--) { l = i+1; g = w(i); if( i<n ) { for(j = l; j <= n; j++) { a(i,j) = 0.0; } } if( ap::fp_neq(g,0.0) ) { g = 1.0/g; if( i!=n ) { for(j = l; j <= n; j++) { s = 0.0; for(k = l; k <= m; k++) { s = s+a(k,i)*a(k,j); } f = s/a(i,i)*g; for(k = i; k <= m; k++) { a(k,j) = a(k,j)+f*a(k,i); } } } for(j = i; j <= m; j++) { a(j,i) = a(j,i)*g; } } else { for(j = i; j <= m; j++) { a(j,i) = 0.0; } } a(i,i) = a(i,i)+1.0; } for(k = n; k >= 1; k--) { for(its = 1; its <= maxsvditerations; its++) { flag = true; for(l = k; l >= 1; l--) { nm = l-1; if( ap::fp_eq(fabs(rv1(l))+anorm,anorm) ) { flag = false; break; } if( ap::fp_eq(fabs(w(nm))+anorm,anorm) ) { break; } } if( flag ) { c = 0.0; s = 1.0; for(i = l; i <= k; i++) { f = s*rv1(i); if( ap::fp_neq(fabs(f)+anorm,anorm) ) { g = w(i); h = pythag(f, g); w(i) = h; h = 1.0/h; c = g*h; s = -f*h; for(j = 1; j <= m; j++) { y = a(j,nm); z = a(j,i); a(j,nm) = y*c+z*s; a(j,i) = -y*s+z*c; } } } } z = w(k); if( l==k ) { if( ap::fp_less(z,0.0) ) { w(k) = -z; for(j = 1; j <= n; j++) { v(j,k) = -v(j,k); } } break; } if( its==maxsvditerations ) { result = false; return result; } x = w(l); nm = k-1; y = w(nm); g = rv1(nm); h = rv1(k); f = ((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y); g = pythag(f, double(1)); f = ((x-z)*(x+z)+h*(y/(f+extsign(g, f))-h))/x; c = 1.0; s = 1.0; for(j = l; j <= nm; j++) { i = j+1; g = rv1(i); y = w(i); h = s*g; g = c*g; z = pythag(f, h); rv1(j) = z; c = f/z; s = h/z; f = x*c+g*s; g = -x*s+g*c; h = y*s; y = y*c; for(jj = 1; jj <= n; jj++) { x = v(jj,j); z = v(jj,i); v(jj,j) = x*c+z*s; v(jj,i) = -x*s+z*c; } z = pythag(f, h); w(j) = z; if( ap::fp_neq(z,0.0) ) { z = 1.0/z; c = f*z; s = h*z; } f = c*g+s*y; x = -s*g+c*y; for(jj = 1; jj <= m; jj++) { y = a(jj,j); z = a(jj,i); a(jj,j) = y*c+z*s; a(jj,i) = -y*s+z*c; } } rv1(l) = 0.0; rv1(k) = f; w(k) = x; } } return result; }