From f8923b1a3fd317a7ed2919cd74539915b361c8b6 Mon Sep 17 00:00:00 2001 From: Jiri Pittner Date: Wed, 11 Feb 2026 16:56:12 +0100 Subject: [PATCH] svd_solve implemented --- nonclass.cc | 3 --- nonclass.h | 39 ++++++++++++++++++++++++++++++++++++++- t.cc | 24 +++++++++++++++++++++++- 3 files changed, 61 insertions(+), 5 deletions(-) diff --git a/nonclass.cc b/nonclass.cc index 0981e94..e6b4e98 100644 --- a/nonclass.cc +++ b/nonclass.cc @@ -918,9 +918,6 @@ void singular_decomposition(NRMat > &a, NRMat &a, NRVec &b, double *det=0, int n=0); \ extern void linear_solve(NRSMat &a, NRVec &b, double *det=0, int n=0); \ extern void diagonalize(NRMat &a, NRVec::normtype> &w, const bool eivec=1, const bool corder=1, int n=0, NRMat *b=NULL, const int itype=1); \ extern void diagonalize(NRSMat &a, NRVec::normtype> &w, NRMat *v, const bool corder=1, int n=0, NRSMat *b=NULL, const int itype=1);\ -extern void singular_decomposition(NRMat &a, NRMat *u, NRVec::normtype> &s, NRMat *v, const bool vnotdagger=0, int m=0, int n=0); +extern void singular_decomposition(NRMat &a, NRMat *u, NRVec::normtype> &s, NRMat *v, const bool vnotdagger=0, int m=0, int n=0); \ /*NOTE!!! all versions of diagonalize DESTROY A and generalized diagonalize also B matrix */ declare_la(double) 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) +{ +if(b.size()!=a.nrows()) laerror("size mismatch in svd_solve"); +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.; +return utb*vt; +} + + +template +NRMat svd_solve(NRMat &a, const NRMat &b, double thres=1e-12) +{ +if(b.nrows()!=a.nrows()) laerror("size mismatch in svd_solve"); +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.; +NRMat utb(a.ncols(),b.ncols()); +utb.gemm((T)0,u,'c',b,'n',(T)1); +utb.diagmultl(ww); +NRMat res(a.ncols(),b.ncols()); +res.gemm((T)0,vt,'c',utb,'n',(T)1); +return res; +} + + + // Separate declarations //general nonsymmetric matrix and generalized diagonalization //corder =0 ... C rows are eigenvectors, =1 ... C columns are eigenvectors diff --git a/t.cc b/t.cc index c835e60..9c319a2 100644 --- a/t.cc +++ b/t.cc @@ -4665,7 +4665,7 @@ NRMat b = explicit_matrix >(a); cout <<"Error = "<<(a-b).norm()< a; +NRVec b; +cin >>a>>b; +NRMat aa(a); +NRVec x = svd_solve(aa,b); +cout <