From 5505d39b99b9f5e6b7103546d033f635ed791de1 Mon Sep 17 00:00:00 2001 From: Jiri Pittner Date: Sat, 15 Nov 2025 18:33:36 +0100 Subject: [PATCH] tensor: working on add_permuted_contractions --- t.cc | 58 +++++++++++++++-- tensor.cc | 183 ++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 219 insertions(+), 22 deletions(-) diff --git a/t.cc b/t.cc index d31c91b..60b286d 100644 --- a/t.cc +++ b/t.cc @@ -3135,20 +3135,25 @@ generate antisymmetrization operator for Brandow diagrams in the Kucharski conve #correspond to already existing antisymmetry #in principle it would be more logical to printout permutation of places rather than indices #but this is more convenient for further processing +P "i/j,k l" input is +2 +3 1 2 2 +1 3 */ NRVec > groups; cin >> groups; int ntot=0; for(int i=0; i indices(ntot); -cin >>indices; +NRVec_from1 indices(ntot); +for(int i=1; i<=ntot; ++i) sprintf(indices[i].name,"%c",'i'+i-1); PermutationAlgebra a=general_antisymmetrizer(groups,-2,true); +cout <<"PA = "< pindices=applypermutation(a[i].perm,indices,false); + NRVec_from1 pindices=applypermutation(a[i].perm,indices,false); for(int j=1; j<=pindices.size(); ++j) cout <(xlist); +Tensor y(s); y.randomize(1.); +INDEXNAME ylist[] = {"n","m","j","i"}; +y.names=NRVec(ylist); + +Tensorz(s); z.clear(); +INDEXNAME zlist[] = {"k","l","m","n"}; +z.names=NRVec(zlist); +Tensorzz(z); + + +z.add_permuted_contractions("k/l,m",x,y,1,0,false,false); + +zz.copyonwrite(); +for(int k=0; k zzz(s); +for(int k=0; k #include "bitvector.h" +#include namespace LA { @@ -1908,6 +1909,109 @@ s>>x.group>>x.index; return s; } +static NRPerm find_indexperm(const NRVec &what, const NRVec &where) +{ +if(what.size()!=where.size()) laerror("sizes of index name vectors do not match in find_indexperm"); +NRPerm basicperm(what.size()); +basicperm.clear(); +for(int i=0; i > &groups0, NRVec &names0) +{ +int igroup= -1; +int iname= -1; +int iclass=0; + +char *txt=strdup(txt0); +char *p=txt; +std::list > groups; +std::list names; +std::list currentgroup; + +foundspace: + while(isspace(*p)) ++p; + if(*p==0) goto finished; + if(!isalpha(*p)) laerror("letter expected in parse_antisymmetrizer"); + ++iname; + ++igroup; + ++iclass; +foundname: + { + INDEXNAME n; + int i=0; + while(isalnum(*p)) + { + n.name[i]=*p; + ++i; + if(i>N_INDEXNAME) laerror("too long index name in parse_antisymmetrizer"); + ++p; + } + if(i>=N_INDEXNAME) laerror("too long index name in parse_antisymmetrizer"); + n.name[i]=0; + + //store + names.push_back(n); + currentgroup.push_back(iclass); + + //now decide based on next character + if(*p==',') + { + ++iname; + ++p; + if(!isalpha(*p)) laerror("letter expected in parse_antisymmetrizer"); + goto foundname; + } + if(*p=='/') + { + ++iname; + ++p; + ++iclass; + if(!isalpha(*p)) laerror("letter expected in parse_antisymmetrizer"); + goto foundname; + } + if(isspace(*p)) + { + groups.push_back(currentgroup); + currentgroup.clear(); + ++p; + goto foundspace; + } + if(*p==0) + { + groups.push_back(currentgroup); + goto finished; + } + laerror("unexpected character in parse_antisymmetrizer"); + } + +finished: + +names0= NRVec (names); +std::cout <<"names parsed "< >::const_iterator ii=groups.begin(); ii!=groups.end(); ++ii) + { + groups0[i++] = NRVec_from1(*ii); + } +std::cout<<"groups parsed "< void Tensor::add_permuted_contractions(const char *antisymmetrizer, const Tensor &rhs1, const Tensor &rhs2, T alpha, T beta, bool conjugate1, bool conjugate2) @@ -1945,33 +2049,76 @@ Tensor tmp=rhs1.contractions(il1,rhs2,il2,alpha,conjugate1,conjugate2); if(rank()!=tmp.rank()) laerror("rank mismatch in add_permuted_contractions"); //generate the antisymmetrizer, adding also indices not involved as a constant subpermutation -//@@@ -PermutationAlgebra pa(1); -pa[0].weight=1; -pa[0].perm.resize(rank()); -pa[0].perm.identity(); +// +//first parse the antisymmetrizer +NRVec antinames; +NRVec > antigroups; +parse_antisymmetrizer(antisymmetrizer,antigroups,antinames); + +//check the names make sense and fill in the possibly missing ones as separate group +if(antinames.size()>tmp.names.size()) laerror("too many indices in the antisymmetrizet"); +bitvector isexplicit(tmp.names.size()); +isexplicit.clear(); +for(int i=0; i pa = general_antisymmetrizer(antigroups,-2,true); + +//find permutation between antisym and TMP index order +NRPerm antiperm=find_indexperm(antinames,tmp.names); + +//@@@conjugate the PA by antiperm or its inverse + +//@@@recast the PA + +//@@@permutationalgebra::is_identity() a pokd ano, neaplikovat ale vratit tmp tenzor resp. s nim udelat axpy //std::cout <<"LHS names = "< basicperm=find_indexperm(names,tmp.names); std::cout <<"Basic permutation = "< pb = basicperm*pa; apply_permutation_algebra(tmp,pb,false,(T)1/(T)pb.size(),beta); -//equivalently possible +//equivalently possible (for trivial pa) //PermutationAlgebra pb = basicperm.inverse()*pa; //apply_permutation_algebra(tmp,pb,true,(T)1/(T)pb.size(),beta); }