diff --git a/fourindex.h b/fourindex.h index cf14503..d1f88a3 100644 --- a/fourindex.h +++ b/fourindex.h @@ -1221,9 +1221,11 @@ protected: unsigned int nnbas; friend class explicit_t2; public: + unsigned int nbas() const {return nnbas;}; fourindex_dense(): NRSMat() {nnbas=0;}; void resize(const int n) {nnbas=n; (*this).NRSMat::resize(nnbas*nnbas);}; explicit fourindex_dense(const int n): NRSMat(n*n) {nnbas=n;}; + explicit fourindex_dense(const int n, const NRSMat&data): NRSMat(data) {nnbas=n; if(data.nrows()!=n*n) laerror("data size mismatch in fourindex_dense antisymtwoelectronrealdiracAB constructor");}; //here i,a are alpha j,b beta inline T& operator() (unsigned int i, unsigned int j, unsigned int a, unsigned int b) @@ -1256,11 +1258,13 @@ return (*this).NRSMat::operator() ((j-1)*nnbas+i-1,(b-1)*nnbas+a-1); template class fourindex_dense : public NRMat { protected: - unsigned int nocc,nvrt,ntri; + unsigned int ntri; friend class explicit_t2; public: + unsigned int nocc,nvrt; fourindex_dense(): NRMat() {nocc=nvrt=ntri=0;}; explicit fourindex_dense(const int noc, const int nvr): NRMat(noc*(noc-1)/2,nvr*(nvr-1)/2) {nocc=noc; nvrt=nvr; ntri=nvr*(nvr-1)/2;}; + explicit fourindex_dense(const int noc, const int nvr, const NRMat &data): NRMat(data) {nocc=noc; nvrt=nvr; ntri=nvr*(nvr-1)/2; if(data.nrows()!=noc*(noc-1)/2 || data.ncols()!=nvr*(nvr-1)/2) laerror("data size mismatch in T2ijab_aces constructor"); }; void resize(const int noc, const int nvr) {(*this).NRMat::resize(noc*(noc-1)/2,nvr*(nvr-1)/2); nocc=noc; nvrt=nvr; ntri=nvr*(nvr-1)/2;}; //we cannot return reference due to the possible sign change @@ -1322,8 +1326,10 @@ class fourindex_dense : public NRSMat { private: int nnbas; public: + int nbas() const {return nnbas;}; fourindex_dense(): NRSMat() {}; explicit fourindex_dense(const int n): nnbas(n), NRSMat(n*(n-1)/2) {}; + explicit fourindex_dense(const int n, const NRSMat &data): nnbas(n), NRSMat(data) {if(data.nrows()!=n*(n-1)/2) laerror("data size mismatch in fourindex_dense antisymtwoelectronrealdirac constructor");}; fourindex_dense(const T &a, const int n): nnbas(n), NRSMat(a,n*(n-1)/2) {}; fourindex_dense(const T *a, const int n): nnbas(n), NRSMat(a,n*(n-1)/2) {}; //and also construct it from sparse and externally stored fourindex classes diff --git a/t.cc b/t.cc index 370e38f..0ae16fb 100644 --- a/t.cc +++ b/t.cc @@ -3743,9 +3743,8 @@ tensor2fourindex(t,ff); cout <<"Error = "<<(f-ff).norm()<>n; fourindex_dense f(n+1,n,n+3,n+2); @@ -3757,7 +3756,49 @@ tensor2fourindex(t,ff); cout <<"Error = "<<(f-ff).norm()<>n; +fourindex_dense f(n,n+2); +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); +f.randomize(1.); +Tensor t=fourindex2tensor(f); +cout < ff; +tensor2fourindex(t,ff); +cout <<"Error = "<<(f-ff).norm()<(noca,nocb,nvra,nvrb,mat); +template +Tensor fourindex2tensor(const fourindex_dense &f) +{ +NRVec shape(2); +for(int i=0; i<2; ++i) + { + shape[i].number=2; + shape[i].symmetry= -1; + shape[i].offset=1; + } +shape[1].range=f.nocc; +shape[0].range=f.nvrt; +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 nvrt=t.shape[0].range; +int nocc=t.shape[1].range; +int offset=t.shape[0].offset; +for(int i=0; i mat(t.data,nocc*(nocc-1)/2,nvrt*(nvrt-1)/2); +f=fourindex_dense(nocc,nvrt,mat); +} + + + +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=1; + shape[i].range=n; + } +NRMat data(f); //expand to full matrix +return Tensor(shape,NRVec(data)); +} + +template +void tensor2fourindex(const Tensor &t, fourindex_dense &f) +{ +if(t.rank()!=4) laerror("wrong rank in tensor2fourindex"); +if(t.shape.size()!=4) 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,range*range); +f=fourindex_dense(range,NRSMat(mat)); +} + + + +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(range,NRSMat(mat)); //symmetrize mat +}