void SVD::solve(MatDoub_I &b, MatDoub_O &x, Doub thresh = -1.) { int i,j,m=b.ncols(); if (b.nrows() != n || x.nrows() != n || b.ncols() != x.ncols()) throw("SVD::solve bad sizes"); VecDoub xx(n); for (j=0;j<m;j++) { for (i=0;i<n;i++) xx[i] = b[i][j]; solve(xx,xx,thresh); for (i=0;i<n;i++) x[i][j] = xx[i]; } }
QRdcmp::QRdcmp(MatDoub_I &a) : n(a.nrows()), qt(n,n), r(a), sing(false) { Int i,j,k; VecDoub c(n), d(n); Doub scale,sigma,sum,tau; for (k=0; k<n-1; k++) { scale=0.0; for (i=k; i<n; i++) scale=MAX(scale,std::abs(r[i][k])); if (scale == 0.0) { sing=true; c[k]=d[k]=0.0; } else { for (i=k; i<n; i++) r[i][k] /= scale; for (sum=0.0,i=k; i<n; i++) sum += SQR(r[i][k]); sigma=SIGN(sqrt(sum),r[k][k]); r[k][k] += sigma; c[k]=sigma*r[k][k]; d[k] = -scale*sigma; for (j=k+1; j<n; j++) { for (sum=0.0,i=k; i<n; i++) sum += r[i][k]*r[i][j]; tau=sum/c[k]; for (i=k; i<n; i++) r[i][j] -= tau*r[i][k]; } } } d[n-1]=r[n-1][n-1]; if (d[n-1] == 0.0) sing=true; for (i=0; i<n; i++) { for (j=0; j<n; j++) qt[i][j]=0.0; qt[i][i]=1.0; } for (k=0; k<n-1; k++) { if (c[k] != 0.0) { for (j=0; j<n; j++) { sum=0.0; for (i=k; i<n; i++) sum += r[i][k]*qt[i][j]; sum /= c[k]; for (i=k; i<n; i++) qt[i][j] -= sum*r[i][k]; } } } for (i=0; i<n; i++) { r[i][i]=d[i]; for (j=0; j<i; j++) r[i][j]=0.0; } }