From b1f1be84579ecd10eaabdc1c29a1af2c729e42d8 Mon Sep 17 00:00:00 2001 From: Jiri Pittner Date: Tue, 3 Feb 2026 15:46:39 +0100 Subject: [PATCH] SemiSparseMat introduced --- mat.h | 5 +++++ sparsemat.cc | 14 ++++++++++++++ sparsemat.h | 41 +++++++++++++++++++++++++++++++++++++++++ t.cc | 28 +++++++++++++++++++++++++++- vec.h | 2 +- 5 files changed, 88 insertions(+), 2 deletions(-) diff --git a/mat.h b/mat.h index abf2f13..26c868f 100644 --- a/mat.h +++ b/mat.h @@ -35,6 +35,9 @@ template class WeightPermutation; template class PermutationAlgebra; template class CyclePerm; template class NRMat_from1; +template class SparseMat; +template class SparseSMat; +template class SemiSparseMat; /***************************************************************************//** @@ -404,6 +407,8 @@ public: explicit NRMat(const SparseSMat &rhs); //! explicit constructor converting sparse CSR matrix into \c NRMat object explicit NRMat(const CSRMat &rhs); + //! explicit constructor converting sparse matrix into \c NRMat object + explicit NRMat(const SemiSparseMat &rhs); //! add up given sparse matrix NRMat & operator+=(const SparseMat &rhs); diff --git a/sparsemat.cc b/sparsemat.cc index 586014d..d300882 100644 --- a/sparsemat.cc +++ b/sparsemat.cc @@ -557,6 +557,16 @@ for(i=0;i +NRMat::NRMat(const SemiSparseMat &rhs) + : NRMat(rhs.offdiagonal) + { + if(rhs.diagonal.size()>0) + { + for(int i=0; i) //some functions are not OK for hermitean matri //// forced instantization in the corresponding object file template class SparseMat; template class SparseMat >; +template class SemiSparseMat; +template class SemiSparseMat >; + #define INSTANTIZE(T) \ +template NRMat::NRMat(const SemiSparseMat &rhs); \ template NRMat::NRMat(const SparseMat &rhs); \ template NRSMat::NRSMat(const SparseMat &rhs); \ template NRVec::NRVec(const SparseMat &rhs); \ diff --git a/sparsemat.h b/sparsemat.h index dcfd509..3542a0b 100644 --- a/sparsemat.h +++ b/sparsemat.h @@ -321,5 +321,46 @@ while(l) return *this; } + +//a rudimentary class for sparse matrix with a dense diagonal - implemented just enough to call davidson etc. on it +template +class SemiSparseMat { + friend class NRMat; +protected: + NRVec diagonal; + SparseMat offdiagonal; +public: + SemiSparseMat() {}; + SemiSparseMat(const SPMatindex n, const SPMatindex m) : offdiagonal(n,m) {if(n==m) diagonal.resize(n);}; + SPMatindex nrows() const {return offdiagonal.nrows();} + SPMatindex ncols() const {return offdiagonal.ncols();} + SPMatindex issymmetric() const {return offdiagonal.issymmetric();} + void setsymmetric() {offdiagonal.setsymmetric();} + void gemv(const T beta, NRVec &r, const char trans, const T alpha, const NRVec &x, bool treat_as_symmetric=false) const + { + offdiagonal.gemv(beta,r,trans,alpha,x,treat_as_symmetric); + if(diagonal.size()>0 && alpha!=(T)0) + { + if(diagonal.size()!=r.size()) laerror("mismatch in diagonal size"); + for(int i=0; i &x, const bool divide=0, bool cache=false) const + { + if(diagonal.size()>0) //we ASSUME the diagonal is ONLY in the vector + { + if(diagonal.size()!=x.size()) laerror("mismatch in diagonal size"); + if(divide) {x.copyonwrite(); for (int i=1; i0 && n==m) diagonal[n]+=elem; else offdiagonal.add(n,m,elem);} + void clear() {diagonal.clear(); offdiagonal.clear();} + void copyonwrite() {diagonal.copyonwrite(); offdiagonal.copyonwrite();} + void resize(const SPMatindex n, const SPMatindex m) {offdiagonal.resize(n,m); diagonal.resize(n==m?n:0);} +}; + + }//namespace #endif diff --git a/t.cc b/t.cc index dd1612c..d72edd6 100644 --- a/t.cc +++ b/t.cc @@ -4572,7 +4572,7 @@ for(int i=0; i>r>>n>>sym; @@ -4624,4 +4624,30 @@ cout <>n>>m; + SemiSparseMat aa(n,n); + aa.setsymmetric(); + for(int i=0; i r(m); +davidson(aa,r,(NRVec *)NULL,"eivecs",m,1,1e-5,0,300,300); +cout < b(n); + cout <::copyonwrite() ******************************************************************************/