diff --git a/nonclass.h b/nonclass.h index 5232e97..1bb0864 100644 --- a/nonclass.h +++ b/nonclass.h @@ -169,29 +169,39 @@ declare_la(std::complex) //svd_solve without contamination from nullspace, b is n x nrhs, result returns in b, A is destroyed template -NRVec svd_solve(NRMat &a, const NRVec &b, double thres=1e-12) +NRVec svd_solve(NRMat &a, const NRVec &b, double thres=1e-12, int *nullity = NULL) { if(b.size()!=a.nrows()) laerror("size mismatch in svd_solve"); +if(nullity) *nullity=0; NRVec w(a.ncols()); NRMat u(a.nrows(),a.ncols()); NRMat vt(a.ncols(),a.ncols()); singular_decomposition(a,&u,w,&vt,false); NRVec utb = b*u; -for(int i=0; ithres ? utb[i]/w[i] : 0.; +for(int i=0; ithres) utb[i] /= w[i]; + else {utb[i]=0; if(nullity) ++*nullity;} + } return utb*vt; } template -NRMat svd_solve(NRMat &a, const NRMat &b, double thres=1e-12) +NRMat svd_solve(NRMat &a, const NRMat &b, double thres=1e-12, int *nullity = NULL) { if(b.nrows()!=a.nrows()) laerror("size mismatch in svd_solve"); +if(nullity) *nullity=0; NRVec w(a.ncols()); NRMat u(a.nrows(),a.ncols()); NRMat vt(a.ncols(),a.ncols()); singular_decomposition(a,&u,w,&vt,false); NRVec ww(w.size()); -for(int i=0; ithres ? 1./w[i] : 0.; +for(int i=0; ithres) ww[i] = 1./w[i]; + else {ww[i]=0; if(nullity) ++*nullity;} + } NRMat utb(a.ncols(),b.ncols()); utb.gemm((T)0,u,'c',b,'n',(T)1); utb.diagmultl(ww);