seed = 1641329179 ... jk: 7 8 0 jk: 7 8 0 jk: 7 8 0 ... infinite loop >> V([8 9],:)*V([8 9],:)' ans = 1 3.45776883297926e-16 3.45776883297926e-16 1 >> ans-eye(2) ans = 4.44089209850063e-16 3.45776883297926e-16 3.45776883297926e-16 -4.44089209850063e-16 >> Q=nash( V(:,[8 9])) p = -7.5460e-17 q = 1 r = 1.00000 swap = 0 p = -7.5460e-17 r = 1.1102e-16 v = 1.8736e-16 Q = 0.89235 0.45135 -0.45135 0.89235 >> e2 = 10*m*eps*eps, tol = 0.01*eps*eps e2 = 4.9304e-30 tol = 4.9304e-34 >> S(1) ans = 2.9467 >> e2*S(1) ans = 1.4528e-29 >> p=V(:,8)'*V(:,9) p = -7.5460e-17 >> p*p ans = 5.6943e-33 >> tol tol = 4.9304e-34 >> 0.1*eps ans = 2.2204e-17 >> abs(p) ans = 7.5460e-17 >> code with convergence problems, using Nash tolerances and convergence tests: Real e2 = 10*m*eps*eps, tol = 0.01*eps*eps, q, r, v, c; Complex p, s; int done; unsigned long count = 0; if( limit == 0) { limit = n/2; } if( limit < 12) limit = 12; // twice Nash values do { done = 1; ++count; // make rows j & k of V orthogonal: for( j = 0, Vj = V, Qj = Q; j < n-1; ++j, Vj += m, Qj += n) for( k = j+1, Vk = Vj+m, Qk = Qj+n; k < n; ++k, Vk += m, Qk += n) { q = S[j]; r = S[k]; p = prod(Vj,Vk,m); int swap = 0; if( q >= r) { // if both norms or inner product are too small then skip if( q <= e2*S[0] || abs2(p) <= tol*q*q) continue; } else { // rows out of order, incorporate swap with rotate swap = 1; Real t = q; q = r; r = t; p = Conj(p); } // std::cout << q << " " << r << " " << p << " "; // debug done = 0; p = p/q; r = 1-r/q; v = sqrt(4*abs2(p) + r*r); c = sqrt(0.5*(1+r/v)); s = Conj(p)/(v*c); // std::cout << c << " " << s << "\n"; // debug rotate( Vj, Vk, m, c, s, swap); rotate( Qj, Qk, n, c, s, swap); S[j] = abs2( Vj, m); S[k] = abs2( Vk, m); } // update norms } while( !done && count < limit); if( !done && count >= limit) std::cerr << "svd: reached sweep limit (" << limit << ")" << std::endl;