/* From bryant@sioux.stanford.edu Sat Apr 3 14:57:54 1993 Return-Path: Received: from sioux.stanford.edu by alnitak.usc.edu (4.1/SMI-4.1+ucs-3.6) id AA12724; Sat, 3 Apr 93 14:57:52 PST Received: from oglala.ice (oglala.Stanford.EDU) by sioux.stanford.edu (4.1/inc-1.0) id AA07300; Sat, 3 Apr 93 14:53:25 PST Date: Sat, 3 Apr 93 14:53:25 PST From: bryant@sioux.stanford.edu (Bryant Marks) Message-Id: <9304032253.AA07300@sioux.stanford.edu> To: ajayshah@rcf.usc.edu Subject: Re: SVD Status: ORr > Hi! Long ago you sent me an svd routine in C based on code > from Nash in Pascal. Has this changed any over the years? (Your > email is dated July 1992). Is your code available by anon ftp? Hi Ajay, I don't think I have changed the code -- but here's my most recent version of the code, you can check to see if it's any different. Currently it's not available via anonymous ftp but feel free to redistribute the code -- it seems to work well in the application I'm using it in. Bryant */ /* This SVD routine is based on pgs 30-48 of "Compact Numerical Methods for Computers" by J.C. Nash (1990), used to compute the pseudoinverse. Modifications include: Translation from Pascal to ANSI C. Array indexing from 0 rather than 1. Float replaced by double everywhere. Support for the Matrix structure. I changed the array indexing so that the matricies (float [][]) could be replaced be a single list (double *) for more efficient communication with Mathematica. */ /* rjrw 7/7/99: changed z back to a vector, moved one line... */ #include #define TOLERANCE 1.0e-22 #ifdef MAIN #include #define NC 2 #define NR 2 main() { int i,j,n,m; double w[NC*(NR+NC)*20], z[NC*NC*20]; void SVD(double *W, double *Z, int nRow, int nCol); for (i=0;i= r) { if (q<=e2*Z[0] || fabs(p)<=tol*q) RotCount--; else { p /= q; r = 1 - r/q; vt = sqrt(4*p*p+r*r); c0 = sqrt(fabs(.5*(1+r/vt))); s0 = p/(vt*c0); for (i=0; i=3 && Z[(EstColRank-1)]<=Z[0]*tol+tol*tol) EstColRank--; } #if DEBUG if (SweepCount > slimit) fprintf(stderr, "Sweeps = %d\n", SweepCount); #endif }