From f1060245a0f7ee2ae18e7de1ced5e3ef6fac79ba Mon Sep 17 00:00:00 2001 From: Jiri Pittner Date: Fri, 24 Oct 2025 14:17:12 +0200 Subject: [PATCH] tensor-fourindex conversions for some more symemtries --- fourindex.h | 3 +- t.cc | 44 +++++++++++++++++++- tensor.h | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 160 insertions(+), 5 deletions(-) diff --git a/fourindex.h b/fourindex.h index 4aa8531..cf14503 100644 --- a/fourindex.h +++ b/fourindex.h @@ -1182,12 +1182,13 @@ void print(std::ostream &out) const template class fourindex_dense : public NRMat { protected: - unsigned int noca,nocb,nvra,nvrb; friend class explicit_t2; public: + unsigned int noca,nocb,nvra,nvrb; fourindex_dense(): NRMat() {noca=nocb=nvra=nvrb=0;}; void resize(const int nocca, const int noccb, const int nvrta, const int nvrtb) {noca=nocca; nocb=noccb; nvra=nvrta; nvrb=nvrtb; (*this).NRMat::resize(nocca*noccb,nvrta*nvrtb);}; explicit fourindex_dense(const int nocca, const int noccb, const int nvrta, const int nvrtb): NRMat(nocca*noccb,nvrta*nvrtb) {noca=nocca; nocb=noccb; nvra=nvrta; nvrb=nvrtb;}; + explicit fourindex_dense(const int nocca, const int noccb, const int nvrta, const int nvrtb, const NRMat &data): NRMat(data) {noca=nocca; nocb=noccb; nvra=nvrta; nvrb=nvrtb; if(data.nrows()!=nocca*noccb||data.ncols()!=nvrta*nvrtb) laerror("data size mismatch in fourindex_dense T2IjAb_aces constructor");}; //here i,a are alpha j,b beta inline T& operator() (unsigned int i, unsigned int j, unsigned int a, unsigned int b) diff --git a/t.cc b/t.cc index f5674ea..370e38f 100644 --- a/t.cc +++ b/t.cc @@ -3704,7 +3704,7 @@ cout <<"Error = "<<(x1-y).norm()<>n; @@ -3717,5 +3717,47 @@ tensor2fourindex(t,ff); cout <<"Error = "<<(f-ff).norm()<>n; +fourindex_dense f(n); +f.randomize(1.); +Tensor t=fourindex2tensor(f); +cout < ff; +tensor2fourindex(t,ff); +cout <<"Error = "<<(f-ff).norm()<>n; +fourindex_dense f(n); +f.randomize(1.); +Tensor t=fourindex2tensor(f); +cout < ff; +tensor2fourindex(t,ff); +cout <<"Error = "<<(f-ff).norm()<>n; +fourindex_dense f(n+1,n,n+3,n+2); +f.randomize(1.); +Tensor t=fourindex2tensor(f); +cout < ff; +tensor2fourindex(t,ff); +cout <<"Error = "<<(f-ff).norm()< Tensor fourindex2tensor(const fourindex_dense &f); template void tensor2fourindex(const Tensor &t, fourindex_dense &f); //conversions from/to fourindex specialized by symmetry type +//NOTE also different index order due to tensor's leftmost index being the least significant template Tensor fourindex2tensor(const fourindex_dense &f) { NRVec shape(4); +int n=f.nbas(); for(int i=0; i<4; ++i) { shape[i].number=1; - shape[i].symmetry-0; - shape[i].offset=0; - shape[i].range=f.nbas(); + shape[i].symmetry=0; + shape[i].offset=1; + shape[i].range=n; } NRVec data(f); return Tensor(shape,data); @@ -303,6 +307,114 @@ f=fourindex_dense(range,NRMat(t.data,range*range,range*range) } +template +Tensor fourindex2tensor(const fourindex_dense &f) +{ +NRVec shape(2); +int n=f.nbas(); +for(int i=0; i<2; ++i) + { + shape[i].number=2; + shape[i].symmetry=1; + shape[i].offset=1; + shape[i].range=n; + } +NRVec data(f); +return Tensor(shape,data); +} + +template +void tensor2fourindex(const Tensor &t, fourindex_dense &f) +{ +if(t.rank()!=4) laerror("wrong rank in tensor2fourindex"); +if(t.shape.size()!=2) laerror("wrong symmetry groups in tensor2fourindex"); +int range=t.shape[0].range; +int offset=t.shape[0].offset; +for(int i=0; i(NRMat(t.data,range*(range+1)/2,range*(range+1)/2)); +} + + +template +Tensor fourindex2tensor(const fourindex_dense &f) +{ +NRVec shape(2); +int n=f.nbas(); +for(int i=0; i<2; ++i) + { + shape[i].number=2; + shape[i].symmetry=1; + shape[i].offset=1; + shape[i].range=n; + } +NRMat mat(f); +NRVec data(mat); //expand symmetric to full matrix for index group symmetry +return Tensor(shape,data); +} + +template +void tensor2fourindex(const Tensor &t, fourindex_dense &f) +{ +if(t.rank()!=4) laerror("wrong rank in tensor2fourindex"); +if(t.shape.size()!=2) laerror("wrong symmetry groups in tensor2fourindex"); +int range=t.shape[0].range; +int offset=t.shape[0].offset; +for(int i=0; i mat(t.data,range*(range+1)/2,range*(range+1)/2); +f=fourindex_dense(NRSMat(mat)); //symmetrize mat +} + + +template +Tensor fourindex2tensor(const fourindex_dense &f) +{ +NRVec shape(4); +for(int i=0; i<4; ++i) + { + shape[i].number=1; + shape[i].symmetry=0; + shape[i].offset=1; + } +shape[3].range=f.noca; +shape[2].range=f.nocb; +shape[1].range=f.nvra; +shape[0].range=f.nvrb; +NRVec data(f); +return Tensor(shape,data); +} + +template +void tensor2fourindex(const Tensor &t, fourindex_dense &f) +{ +if(t.rank()!=4 ||t.shape.size()!=4) laerror("wrong rank/shape in tensor2fourindex"); +int noca = t.shape[3].range; +int nocb = t.shape[2].range; +int nvra = t.shape[1].range; +int nvrb = t.shape[0].range; + +int offset=t.shape[0].offset; +for(int i=0; i mat(t.data,noca*nocb,nvra*nvrb); +f=fourindex_dense(noca,nocb,nvra,nvrb,mat); +} + + + +