24 #include "SheafSystem/svd.h" 26 #include "SheafSystem/std_algorithm.h" 27 #include "SheafSystem/std_cmath.h" 28 #include "SheafSystem/std_iostream.h" 47 double* ltemp =
new double[ncols];
52 svd_reduce(xa, xw, xv, nrows, ncols, ltemp, lnorm);
98 svd_reduce(
double* xa,
double* xw,
double* xv,
int nrows,
int ncols,
99 double* ltemp,
double& lnorm)
113 for(
int i=0; i<ncols; ++i)
125 for(
int k=i; k<nrows; ++k)
127 lscale += abs(xa[k*ncols+i]);
132 for(
int k=i; k<nrows; ++k)
139 double f = xa[i*ncols+i];
145 for(
int j=l-1; j<ncols; ++j)
148 for(
int k=i; k<nrows; ++k)
150 s += xa[k*ncols+i] * xa[k*ncols+j];
155 for(
int k=i; k<nrows; ++k)
157 xa[k*ncols+j] += f*xa[k*ncols+i];
161 for(
int k=i; k<nrows; ++k)
163 xa[k*ncols+i] *= lscale;
173 if(((i+1)<=nrows) && ((i+1)!=ncols))
175 for(
int k=l-1; k<ncols; ++k)
177 lscale += abs(xa[i*ncols+k]);
182 for(
int k=l-1; k<ncols; ++k)
184 xa[i*ncols+k] /= lscale;
185 s += xa[i*ncols+k]*xa[i*ncols+k];
188 double f = xa[i*ncols+l-1];
191 xa[i*ncols+l-1] = f-g;
193 for(
int k=l-1; k<ncols; ++k)
195 ltemp[k] = xa[i*ncols+k]/h;
198 for(
int j=l-1; j<nrows; ++j)
201 for(
int k=l-1; k<ncols; ++k)
203 s += xa[j*ncols+k]*xa[i*ncols+k];
206 for(
int k=l-1; k<ncols; ++k)
208 xa[j*ncols+k] += s*ltemp[k];
212 for(
int k=l-1; k<ncols; ++k)
214 xa[i*ncols+k] *= lscale;
219 lnorm =
max(lnorm, (abs(xw[i]) + abs(ltemp[i])));
224 for(
int i=ncols-1; i>=0; i--)
230 for(
int j=l; j<ncols; ++j)
232 xv[j*ncols+i] = (xa[i*ncols+j]/xa[i*ncols+l])/g;
235 for(
int j=l; j<ncols; ++j)
238 for(
int k=l; k<ncols; ++k)
240 s += xa[i*ncols+k]*xv[k*ncols+j];
243 for(
int k=l; k<ncols; ++k)
245 xv[k*ncols+j] += s*xv[k*ncols+i];
250 for(
int j=l; j<ncols; ++j)
252 xv[i*ncols+j] = xv[j*ncols+i] = 0.0;
263 for(
int i=
min(nrows, ncols)-1; i>=0; i--)
268 for(
int j=l; j<ncols; ++j)
277 for(
int j=l; j<ncols; ++j)
280 for(
int k=l; k<nrows; ++k)
282 s += xa[k*ncols+i]*xa[k*ncols+j];
285 double f = (s/xa[i*ncols+i])*g;
287 for(
int k=i; k<nrows; ++k)
289 xa[k*ncols+j] += f*xa[k*ncols+i];
293 for(
int j=i; j<nrows; ++j)
301 for(
int j=i; j<nrows; ++j)
322 double* ltemp,
double lnorm)
330 static const int MAX_ITERATIONS = 30;
334 for(
int k=ncols-1; k>=0; k--)
340 for(
int iterations=0; iterations<MAX_ITERATIONS; ++iterations)
350 if(abs(ltemp[l])+lnorm == lnorm)
356 if(abs(xw[p])+lnorm == lnorm)
369 for(
int i=l; i<k+1; ++i)
371 double f = s*ltemp[i];
372 ltemp[i] = c*ltemp[i];
374 if((abs(f) + lnorm) == lnorm)
387 for(
int j=0; j<nrows; ++j)
411 for(
int j=0; j<ncols; ++j)
421 if(iterations >= MAX_ITERATIONS)
424 cerr <<
"Error: No convergence in " << MAX_ITERATIONS
425 <<
" svd iterations." << endl;
435 double g = ltemp[kk];
438 double f = ((y-z)*(y+z) + (g-h)*(g+h))/(2.0*h*y);
440 f = ((x-z)*(x+z)+h*((y/(f+
same_sign(g,f)))-h))/x;
447 for(
int j=l; j<=kk; ++j)
468 for(
int n=0; n<ncols; ++n)
474 xv[nj] = x*lcos + z*lsin;
475 xv[ni] = z*lcos - x*lsin;
493 for(
int m=0; m<nrows; ++m)
499 xa[mj] = y*lcos + z*lsin;
500 xa[mi] = z*lcos - y*lsin;
554 double labs_a = abs(xa);
555 double labs_b = abs(xb);
561 double lratio = labs_b/labs_a;
562 double lratio2 = lratio*lratio;
563 result = labs_a*
sqrt(1.0+lratio2);
565 else if(labs_b > 0.0)
567 double lratio = labs_a/labs_b;
568 double lratio2 = lratio*lratio;
569 result = labs_b*
sqrt(1.0+lratio2);
SHEAF_DLL_SPEC void sqrt(const sec_at0 &x0, sec_at0 &xresult, bool xauto_access)
Compute sqrt of x0 (sqrt(x0)) (pre-allocated version).
SHEAF_DLL_SPEC bool svd_diagonalize(double *xa, double *xw, double *xv, int nrows, int ncols, double *xtemp, double lnorm)
Diagonalization of the bidiagonal form. Convenience function.
SHEAF_DLL_SPEC double svd_pythag(double xa, double xb)
Pthagorean theorem calculation.
SHEAF_DLL_SPEC bool svd_reduce(double *xa, double *xw, double *xv, int nrows, int ncols, double *ltemp, double &lnorm)
Householder reduction to bidiagonal form. Convenience function.
SHEAF_DLL_SPEC bool svd_decompose(double *xa, double *xs, double *xv, int xnrows, int xncols)
Perform single value decomposition.
SHEAF_DLL_SPEC double same_sign(double xa, double xb)
Convert xa to have the same sign as xb.
SHEAF_DLL_SPEC void max(const vd &x0, vd_value_type &xresult, bool xauto_access)
Maximum component of x0, pre-allocated version.
SHEAF_DLL_SPEC void min(const vd &x0, vd_value_type &xresult, bool xauto_access)
Minimum component of x0, pre-allocated version.