/***** *Property of the University of British Columbia (UBC), *Copyright 2001, by UBC. * *By receiving this code, you are agreeing to the following terms: *1. You will use this code for academic purposes only. *2. For academic use only, you may distribute the binary or executable code * to persons at UBC or the Univ. of Western Australia who have previously * read and agreed to these terms, but you must distribute the SOURCE code * with it. *3. Each file of source code so distributed must have this header attached. *4. If the code is revised, the programmer's name and revision date must be added * to the Revision List below, as well as the revisions identified in the code. *5. You will not make this code more widely available via any method such as * publishing in print, email mail-list, usenet posting, website etc. *6. UBC reserves all rights to this work and all derivative works. * *For other proposed purposes please contact: *The University-Industry Liaison Office *IRC Room 331 - 2194 Health Sciences Mall *University of British Columbia *Vancouver, BC, Canada V6T 1Z3 *Tel: (604) 822-8580 *Fax: (604) 822-8589 * *or contact: *Peter D. Lawrence, Professor at peterl@ece.ubc.ca or *Greg Z. Grudic, Assistant Professor, at grudic@cs.colorado.edu * *Revision List: *Greg Grudic, August 28, 1998. *****/ /* % % File: svd.c % Program: Functions for Functional Approximation code % % % Author: Greg Grudic % */ #include #include #include "pc.h" void svd(My_Real **A, My_Real *S2, int n) { int i, j, k, EstColRank = n, RotCount = n, SweepCount = 0, slimit = (n<120) ? 30 : n/4; My_Real eps = 1e-15, e2 = 10.0*n*eps*eps, tol = 0.1*eps, vt, p, x0, y0, q, r, c0, s0, d1, d2; for (i=0; i= r) { if (q<=e2*S2[0] || fabs(p)<=tol*q) RotCount--; else { p /= q; r = 1.0-r/q; vt = sqrt(4.0*p*p+r*r); c0 = sqrt(0.5*(1.0+r/vt)); s0 = p/(vt*c0); for (i=0; i<2*n; i++) { d1 = A[i][j]; d2 = A[i][k]; A[i][j] = d1*c0+d2*s0; A[i][k] = -d1*s0+d2*c0; } } } else { p /= r; q = q/r-1.0; vt = sqrt(4.0*p*p+q*q); s0 = sqrt(0.5*(1.0-q/vt)); if (p<0.0) s0 = -s0; c0 = p/(vt*s0); for (i=0; i<2*n; i++) { d1 = A[i][j]; d2 = A[i][k]; A[i][j] = d1*c0+d2*s0; A[i][k] = -d1*s0+d2*c0; } } } while (EstColRank>2 && S2[EstColRank-1]<=S2[0]*tol+tol*tol) EstColRank--; } }