You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
importpdaggerqimportnumpyasnpimportreimportsys# Replace by the correct pathsys.path.append('#PATH_TO_SimpleWick')
importcopyimportwickaswfromIPython.displayimportdisplay, Latex
Factorial
# Factorial of a numberdeffactorial(k):
iftype(k) !=type(1):
print('Error type arg k in factorial')
sys.exit()
f=1foriinrange(2,k+1):
f=f*ireturnf
Left operator string
defgen_left_str(ops):
iftype(ops) !=type(['aa','bb']):
print('Error type arg ops in gen_left_str')
sys.exit()
acc='e'+str(len(ops)//2)+'('foropinops:
acc=acc+op+','acc=acc[0:len(acc)-1] +')'acc=acc.replace('-','')
acc=acc.replace('+','')
returnacc
T_pq
# Class for a single T operatorclassT_pq():
def__init__(self,t):
# Initself.is_ok=Trueself.t=tself.na_i=0self.nb_i=0self.ng_i=0self.na_a=0self.nb_a=0self.ng_a=0self.sign=1# clean the Tdefclean(self):
T=self.t#print('Not cleaned T:',T)T=T.replace('t','')
T=re.sub(r'[()]','',T)
T=re.sub(r'[0-9]+', '', T)
T=T.split(',')
self.t=T#print('Cleaned T:',T)# t2 act -> act = 0# t1 act -> act = 0defremove_act_exc(self):
acc= []
foropinself.t:
acc.append(op[1])
nb_n=acc.count('n')
nb_m=acc.count('m')
# Remove the t1 act -> actiflen(self.t) ==2:
ifnb_m==1andnb_n==1:
self.is_ok=True# Remove the t2 act -> acteliflen(self.t) ==4:
ifnb_m==2andnb_n==2:
self.is_ok=False# Count alpha, beta and general spindefcount_spin(self):
na_i=self.na_inb_i=self.nb_ing_i=self.ng_ina_a=self.na_anb_a=self.nb_ang_a=self.ng_aforopinself.t:
if (op[2] =='a'andop[0] =='i'):
na_i=na_i+1if (op[2] =='b'andop[0] =='i'):
nb_i=nb_i+1if (op[2] =='g'andop[0] =='i'):
ng_i=ng_i+1if (op[2] =='a'andop[0] =='a'):
na_a=na_a+1if (op[2] =='b'andop[0] =='a'):
nb_a=nb_a+1if (op[2] =='g'andop[0] =='a'):
ng_a=ng_a+1self.na_i=na_iself.nb_i=nb_iself.ng_i=ng_iself.na_a=na_aself.nb_a=nb_aself.ng_a=ng_a#print('Spin i:',self.na_i,self.nb_i,self.ng_i)#print('Spin a:',self.na_a,self.nb_a,self.ng_a)# Check is the term is zero by spin# alpha -> + 1, beta -> -1s_i=na_i-nb_is_a=na_a-nb_aif (s_i!=s_a) and (abs(s_i-s_a) !=ng_i+ng_a):
self.is_ok=False#print('is ok:', self.is_ok)# Put the hole indexes before the particle onesdefto_std_order(self):
acc= []
foriinrange(len(self.t)//2,len(self.t)):
acc.append(self.t[i])
foriinrange(0,len(self.t)//2):
acc.append(self.t[i])
#print('acc',acc)self.t=acc# Remove the first index that define the orbital classdefremove_first_idx(self):
acc= []
fortinself.t:
acc.append(t[1:3])
self.t=acc# Move indexes to end up with: beta g alphadefmove_b_to_left(self):
iflen(self.t) ==2:
returniflen(self.t) >4:
print('Error, only done for t1 and t2')
sys.exit()
sign=1idx_spin=2t=copy.deepcopy(self.t)
#print(t)t_i=t[0:(len(t)//2)]
t_a=t[(len(t)//2):len(t)]
#print("ti",t_i)#print("ta",t_a)# b=0, g=1, a=2# For hole partacc_i= []
forelemint_i:
acc_i.append(elem[idx_spin])
foriinrange(len(acc_i)):
ifacc_i[i] =='b':
acc_i[i] =0elifacc_i[i] =='g':
acc_i[i] =1else:
acc_i[i] =2#print(acc_i)ifacc_i[1] <acc_i[0]:
sign=-signt[0] =t_i[1]
t[1] =t_i[0]
# For particle partacc_a= []
forelemint_a:
acc_a.append(elem[idx_spin])
foriinrange(len(acc_a)):
ifacc_a[i] =='b':
acc_a[i] =0elifacc_a[i] =='g':
acc_a[i] =1else:
acc_a[i] =2#print(acc_a)ifacc_a[1] <acc_a[0]:
sign=-signt[2] =t_a[1]
t[3] =t_a[0]
#print(self.t,t)#print(self.sign,sign)# New t and update the signself.t=tself.sign=sign
Term_pq
# Class for the whole term comming from pdaggerq (prefactor + Ts)classTerm_pq():
def__init__(self,a_term):
self.prefactor=float(a_term[0]) # prefactor self.str_T=a_term[1:] # output from pdaggerqself.nb_T=len(self.str_T) # Number of Tself.l_T=None# List of Tself.tex=None# Tex#self.ref = None#self.deltas = deltas# Loop over the Tsacc= []
foriinrange(4):
ifi>=self.nb_T:
breakt=T_pq(self.str_T[i])
# Cleaningt.clean()
# Remove act -> act amplitudest.remove_act_exc()
# t(i,j,...a,b,...)t.to_std_order()
#print("T n°",i,":",t.t)# To check if the T is zerot.count_spin()
# Put the beta indexes on the left and change the signt.move_b_to_left()
#print(self.prefactor,t.sign)self.prefactor=self.prefactor*t.sign#print(self.prefactor)# The first index for the orbital class is not useful anymoret.remove_first_idx()
# Nullify if a term is zero by spinifnott.is_ok:
self.prefactor=0.0acc.append(t.t)
# List of Tsself.l_T=acc#if self.prefactor != 0.0:# print('Term:',self.prefactor,self.l_T)#def remove_disconnected(self):# Convert the term to latexdefto_latex(self):
# Sign + prefactorifstr(self.prefactor)[0] =='-':
acc=str(self.prefactor)
else:
acc='+'+str(self.prefactor)
# Tsself.tex=acc+Ts_to_tex(self.l_T)
#for t in self.l_T:# acc = acc + ' \\ t_{'# #print('t',t)# # Lower indexes# for i in range(0,len(t)//2):# acc = acc + t[i][0] + '$' + t[i][1]# acc = acc + '}^{'# # Upper indexes# for i in range(len(t)//2,len(t)):# acc = acc + t[i][0] + '$' + t[i][1]# acc = acc + '}'##print(acc)## Spin#acc = acc.replace('$a','_{\\alpha}')#acc = acc.replace('$b','_{\\beta}')#acc = acc.replace('$g','_{}')#self.tex = acc# To diplay the latex eqdeftex_show(self):
null=self.to_latex()
display(Latex(f'${self.tex}$'))
defprefactor_to_tex(prefactor):
iftype(prefactor) !=type(1.0):
print('Error type arg prefactor in prefactor_to_tex')
sys.exit()
# Sign + prefactorifstr(prefactor)[0] =='-':
tex=str(prefactor)
else:
tex='+'+str(prefactor)
returntexdefTs_to_tex(Ts):
iftype(Ts) !=type([['aa'],['bb']]):
print('Error type Ts in Ts_to_tex')
sys.exit()
tex=''fortinTs:
tex=tex+' \\ t_{'#print('t',t)# Lower indexesforiinrange(0,len(t)//2):
ift[i][1] =='b':
tex=tex+'\\bar{'+t[i][0] +'}'else:
tex=tex+t[i][0]
#tex = tex + t[i][0] + '$' + t[i][1]tex=tex+'}^{'# Upper indexesforiinrange(len(t)//2,len(t)):
ift[i][1] =='b':
tex=tex+'\\bar{'+t[i][0] +'}'else:
tex=tex+t[i][0]
#tex = tex + t[i][0] + '$' + t[i][1]tex=tex+'}'#print(tex)# Spin#tex = tex.replace('$a','_{\\alpha}')#tex = tex.replace('$b','_{\\beta}')#tex = tex.replace('$g','_{}')returntexdefdeltas_to_tex(deltas):
iftype(deltas) !=type([['aa','bb'],['aa','bb']]):
print('Error type arg deltas in deltas to tex')
sys.exit()
#tex = w.deltas_to_tex(deltas)#tex = tex.replace('_{\\alpha}','')#tex = tex.replace('_{\\beta}','')tex=''fordeltaindeltas:
ifdelta[0][3] =='b':
d1='\\bar{'+str(delta[0][1])+'}'else:
d1=str(delta[0][1])
ifdelta[1][3] =='b':
d2='\\bar{'+str(delta[1][1])+'}'else:
d2=str(delta[1][1])
tex=tex+'\delta('+d1+','+d2+') \ 'returntex
defapply_ops_eT(ops,Ts):
iftype(ops) !=type(['aa','bb']):
print('Error type arg ops in apply_ops_eT')
sys.exit()
iftype(Ts) !=type([['t1','t1','t2']]):
print('Error type arg Ts in apply_ops_eT')
sys.exit()
# Initpq=pdaggerq.pq_helper("fermi")
op_str=gen_left_str(ops)
#print('Left ops:',op_str)# Set left operatorspq.set_left_operators([[op_str]])
#pq.set_left_operators([['e3(ira,isb,iig,aqa,apb,aag)']])#print('If there are many T, set the prefactor to 1/k! ...\n')# Set Ts operators#Ts = ['t1','t2']prefactor=1.0/factorial(Ts.count('t1')) *1.0/factorial(Ts.count('t2'))
pq.add_operator_product(prefactor,Ts)
#print(prefactor)#pq.add_operator_product(1.0/factorial(len(Ts)),Ts)#pq.add_operator_product(1.0,['t1','t1'])pq.simplify()
# list of fully-contracted strings, then printterms=pq.fully_contracted_strings()
#print(1,terms)#for term in terms:# print(term)# #pq.clear()# obj = Term_pq(term)# #print('prefactor',obj.prefactor)# #print('T:',obj.l_T)# obj.to_latex()returnterms
Gen all T
defgen_all_T(max_rank,nb_min_op,nb_max_op):
iftype(max_rank) !=type(1):
print('Error type arg max_rank in gen_all_T')
sys.exit()
iftype(nb_min_op) !=type(1):
print('Error type arg nb_min_op in gen_all_T')
sys.exit()
iftype(nb_max_op) !=type(1):
print('Error type arg nb_max_op in gen_all_T')
sys.exit()
T= [[]]
foriinrange(1,max_rank+1):
T[0].append([i])
#print(T)forjinrange(1,nb_max_op//2+1):
l=copy.deepcopy(T[j-1])
idx= [iforiinrange(1,max_rank+1)]
res= []
foreleminl:
#print('e',elem)foriinidx:
#print(sum(elem)+i)ifi<elem[-1] orsum(elem)+i>nb_max_op//2: continuetmp=copy.deepcopy(elem)
tmp.append(i)
res.append(tmp)
#print(res)iflen(res) >0:
T.append(res)
#print(T)#print('T',T)#for elem in T:# print(elem)# Reduce the number of dimacc= []
forlinT:
fortsinl:
#print(ts)ifsum(ts) <nb_min_op//2:
continueacc.append(ts)
T=acc# Transform to stringsforiinrange(len(T)):
forjinrange(len(T[i])):
T[i][j] ='t'+str(T[i][j])
returnT
Spin flip
defspin_flip(list_op,idx_spin):
iftype(list_op) !=type(['aa','bb']):
print('Error type arg list_op in spin_flip')
sys.exit()
iftype(idx_spin) !=type(0):
print('Error type arg idx_spin in spin_flip')
sys.exit()
acc= []
foriinrange(len(list_op)):
tmp1=copy.deepcopy(list_op[i][:idx_spin])
s=list_op[i][idx_spin]
iflen(list_op[i]) >idx_spin:
tmp2=copy.deepcopy(list_op[i][idx_spin+1:])
else:
tmp2=''ifs=='b':
s='a'elifs=='a':
s='b'acc.append(tmp1+s+tmp2)
returnacc# Apply a spin flip on the resultdefspin_flip_ltup(l,idx_perm_Ts):
iftype(l) !=type([(1.0,[['aa']],[['aa']])]):
print('Error type arg l in perm_ltup')
sys.exit()
iftype(idx_perm_Ts) !=type(1):
print('Error type arg idx_perm_Ts in perm_ltup')
sys.exit()
list_prefactor= []
list_deltas= []
list_Ts= []
l2=copy.deepcopy(l)
forprefactor, deltas, Tsinl2:
list_prefactor.append(prefactor)
list_deltas.append(deltas)
list_Ts.append(Ts)
acc_Ts=copy.deepcopy(list_Ts)
foriinrange(len(list_Ts)):
forjinrange(len(list_Ts[i])):
#print(list_Ts[i][j])forkinrange(len(list_Ts[i][j])):
tmp1=list_Ts[i][j][k][0:idx_perm_Ts]
tmp2=list_Ts[i][j][k][idx_perm_Ts+1:]
tmp=list_Ts[i][j][k][idx_perm_Ts]
iftmp=='a':
tmp='b'eliftmp=='b':
tmp='a'acc_Ts[i][j][k] =tmp1+tmp+tmp2#print(list_Ts[i][j])acc_d=copy.deepcopy(list_deltas)
foriinrange(len(list_deltas)):
forjinrange(len(list_deltas[i])):
forkinrange(len(list_deltas[i][j])):
tmp=list_deltas[i][j][k][0]
tmp1=list_deltas[i][j][k][1]
tmp2=list_deltas[i][j][k][3:]
#print('1',list_deltas[i][j][k])iftmp=='i':
tmp='a'ifk==0:
op='-'else:
op='+'eliftmp=='a':
tmp='i'ifk==0:
op='+'else:
op='-'acc_d[i][j][k] =tmp+tmp1+op+tmp2#print('2',list_deltas[i][j][k])#print('4',list_deltas[i][j])acc= []
forprefactor, deltas, Tsinzip(list_prefactor,acc_d,acc_Ts):
acc.append((prefactor,deltas,Ts))
returnacc
Search unique deltas
# Search the unique elem of a list and sort them depending on their lengthdefsearch_unique_deltas(l):
list_deltas=copy.deepcopy(l)
iftype(list_deltas) !=type([['aa','bb'],['aa','bb']]):
print('Error type arg list_deltas in search_unique_deltas')
sys.exit()
list_unique= []
fordeltasinlist_deltas:
ifnotis_in(deltas,list_unique):
list_unique.append(deltas)
# Sort## Max lenmax_len=0foreleminlist_unique:
iflen(elem) >max_len:
max_len=len(elem)
## Split depending on the lengthacc= [[] foriinrange(max_len+1)]
fordeltasinlist_unique:
acc[len(deltas)].append(deltas)
## Reduction of the number of dimensionstmp= []
forlist_eleminacc:
foreleminlist_elem:
tmp.append(elem)
list_unique=tmpreturnlist_unique# Search if an elem is in a list ldefis_in(elem,l):
foriinl:
ifelem==i:
returnTruereturnFalsedefsearch_idx(elem,l):
idx=0foriinl:
ifi==elem:
returnidxidx=idx+1print('Not found in the list')
sys.exit()
Prod
defprod_ltup(l1,l2):
iftype(l1) !=type([(1.0,[['aa','bb']],[['aa','bb']])]):
print('Error type arg l1 in prod_ltup')
sys.exit()
iftype(l2) !=type(l1):
print('Error type arg l1 in prod_ltup')
sys.exit()
# Prodres= []
forprefactor1, deltas1, Ts1inl1:
forprefactor2, deltas2, Ts2inl2:
#print('1:',prefactor1,prefactor2)#print('1:',deltas1,deltas2)#print('1:',Ts1,Ts2)prefactor=prefactor1*prefactor2deltas=copy.deepcopy(deltas1)
is_in=Falseforelemindeltas2:
forop2inelem:
fore1indeltas1:
forop1ine1:
ifop1==op2:
is_in=Truedeltas.append(elem)
# Remove the products of deltas leading to conflictsifis_in:
continuedeltas=remove_duplicate(deltas)
Ts=copy.deepcopy(Ts1)
foreleminTs2:
Ts.append(elem)
Ts=sort_Ts(Ts)
#print('2:',prefactor)#print('2:',deltas)#print('2:',Ts)res.append((prefactor,deltas,Ts))
returnres
Print
defprint_ltup(l):
iftype(l) !=type([(1.0,[['aa','bb']],[['aa','bb']])]):
print('Error type arg l in print_ltup')
sys.exit()
tex=''forprefactor,deltas,Tsinl:
tex=tex+prefactor_to_tex(prefactor) +' \ 'tex=tex+deltas_to_tex(deltas)
tex=tex+Ts_to_tex(Ts)
display(Latex(f'${tex}$'))
defprint_fact_ltup(l,l_factor):
iftype(l) !=type([(1.0,[['aa','bb']])]):
print('Error type arg l in print_fact_ltup')
sys.exit()
iftype(l_factor) !=type([['aa','bb']]):
print('Error type arg l_factor in print_fact_ltup')
sys.exit()
tex='\\textbf{Factorized form:}'display(Latex(f'${tex}$'))
foriinrange(len(l)):
tex=deltas_to_tex(l_factor[i]) +'\\bigl['#print('\nFactor:',list_unique_deltas[i])#if len(tex) > 0:# display(Latex(f'${tex}$'))j=0foreleminl[i]:
#print(elem)e1,e2=elemprefactor=prefactor_to_tex(e1)
ifj==0andprefactor[0] =='+':
prefactor=prefactor[1:]
tex=tex+prefactor+' \ 'tex=tex+Ts_to_tex(e2)
j=j+1tex=tex+'\\bigr]'display(Latex(f'${tex}$'))
defprint_contrib_M1(si,sa,len_res):
ifsi=='b':
i='\\bar{i}'else:
i='i'ifsa=='b':
a='\\bar{a}'else:
a='a'tex='M_{'+i+'}^{'+a+'} \\leftarrow 'iflen_res==0:
tex=tex+'0'null=display_tex(tex)
#print(tex)defprint_contrib_M2(si,sj,sa,sb,len_res):
ifsi=='b':
i='\\bar{i}'else:
i='i'ifsj=='b':
j='\\bar{j}'else:
j='j'ifsa=='b':
a='\\bar{a}'else:
a='a'ifsb=='b':
b='\\bar{b}'else:
b='b'tex='M_{'+i+j+'}^{'+a+b+'} \\leftarrow 'iflen_res==0:
tex=tex+'0'null=display_tex(tex)
#print(tex)
Factorize by deltas
deffactorize_from_ltup(l):
iftype(l) !=type([(1.0,[['aa','bb']],[['aa','bb']])]):
print('Error type arg l in factorize_from_ltup')
sys.exit()
list_prefactor= []
list_deltas= []
list_Ts= []
forprefactor,deltas,Tsinl:
list_prefactor.append(prefactor)
list_deltas.append(deltas)
list_Ts.append(Ts)
returnfactorize_by_deltas(list_prefactor,list_deltas,list_Ts)
deffactorize_by_deltas(list_prefactor,list_deltas,list_Ts):
iftype(list_prefactor) !=type([1.0,1.0]):
print('Error type arg list_prefactor in factorize_by_deltas')
sys.exit()
iftype(list_deltas) !=type([['aa','bb']]):
print('Error type arg list_deltas in factorize_by_deltas')
sys.exit()
iftype(list_Ts) !=type([['aa','bb']]):
print('Error type arg list_Ts in factorize_by_deltas')
sys.exit()
list_unique_deltas=search_unique_deltas(list_deltas)
#for unique_deltas in list_unique_deltas:# print(unique_deltas)# factorizationfact_terms= [[] foriinrange(len(list_unique_deltas))]
forprefactor,deltas,Tsinzip(list_prefactor,list_deltas,list_Ts):
idx=search_idx(deltas,list_unique_deltas)
fact_terms[idx].append((prefactor,Ts))
#for i in range(len(fact_terms)):# print('\nFactor:',list_unique_deltas[i])# for elem in fact_terms[i]:# print(elem)returnfact_terms, list_unique_deltasdefsimplify_by_deltas(fact_terms):
acc= []
fortermsinfact_terms:
list_prefactor= []
list_Ts= []
foriinrange(0,len(terms)):
a_i=terms[i]
prefactor_i=a_i[0]
Ts_i=a_i[1]
is_in=Falseforjinrange(0,len(list_Ts)):
prefactor_j=list_prefactor[j]
Ts_j=list_Ts[j]
ifTs_i==Ts_j:
list_prefactor[j] =prefactor_i+prefactor_jis_in=Truebreakifis_in:
continue#if prefactor_i == 0:# continuelist_prefactor.append(prefactor_i)
list_Ts.append(Ts_i)
tmp= []
forp,tinzip(list_prefactor,list_Ts):
#if p == 0.0:# continuetmp.append((p,t))
acc.append(tmp)
returnaccdefordered_by_t1(fact_terms):
f= []
fortermsinfact_terms:
list_unique_inact_t1= []
forp,Tsinterms:
fortinTs:
iflen(t) !=2:
breakift[0][0] !='i'andt[0][0] !='j':
continueift[1][0] !='a'andt[1][0] !='b':
continueis_in=Falseforeleminlist_unique_inact_t1:
ift==elem:
is_in=Truebreakifis_in:
continuelist_unique_inact_t1.append(t)
acc= [[] foriinrange(len(list_unique_inact_t1)+1)]
forp,Tsinterms:
fortinTs:
i=0found=Falseforeleminlist_unique_inact_t1:
ifelem[0][0] ==t[0][0] andelem[1][0] ==t[1][0]:
found=Truebreaki=i+1iffound:
breakifnotfound:
i=-1acc[i].append((p,Ts))
#print(acc)tmp= []
forterminacc:
foreleminterm:
tmp.append(elem)
f.append(tmp)
returnf
# Remove disconnected terms by looking if there is at least one# active index in each tdefremove_disconnected(l):
iftype(l) !=type([(1.0,[[]],[[]])]):
print('Type error arg l in function remove disconnected')
sys.exit()
l2=copy.deepcopy(l)
acc= []
forprefactor, deltas, Tsinl2:
fortinTs:
is_co=Falseforidxint:
ifidx[0] =='n'oridx[0] =='m':
is_co=Truebreakifnotis_co:
breakifnotis_co:
continueacc.append((prefactor,deltas,Ts))
returnacc