@@ -43,46 +43,70 @@ function exp(A::ITensor, Linds, Rinds; ishermitian=false)
4343 end
4444 end
4545
46- N = ndims (A)
4746 NL = length (Linds)
4847 NR = length (Rinds)
4948 NL != NR && error (" Must have equal number of left and right indices" )
50- N != NL + NR &&
49+ ndims (A) != NL + NR &&
5150 error (" Number of left and right indices must add up to total number of indices" )
5251
53- # Linds, Rinds may not have the correct directions
54- # TODO : does the need a conversion?
55- Lis = Linds
56- Ris = Rinds
52+ # Replace Linds and Rinds with index sets having
53+ # same id's but arrow directions as on A
54+ Linds = permute ( commoninds (A, Linds), Linds)
55+ Rinds = permute ( commoninds (A, Rinds), Rinds)
5756
58- # Ensure the indices have the correct directions,
59- # QNs, etc.
60- # First grab the indices in A, then permute them
61- # correctly.
62- Lis = permute (commoninds (A, Lis), Lis)
63- Ris = permute (commoninds (A, Ris), Ris)
64-
65- for (l, r) in zip (Lis, Ris)
57+ # Ensure indices have correct directions, QNs, etc.
58+ for (l, r) in zip (Linds, Rinds)
6659 if space (l) != space (r)
6760 error (" In exp, indices must come in pairs with equal spaces." )
6861 end
69- if hasqns (A)
70- if dir (l) == dir (r)
71- error (" In exp, indices must come in pairs with opposite directions" )
72- end
62+ if hasqns (A) && dir (l) == dir (r)
63+ error (" In exp, indices must come in pairs with opposite directions" )
64+ end
65+ end
66+
67+ # <fermions>
68+ auto_fermion_enabled = using_auto_fermion ()
69+ if auto_fermion_enabled
70+ # If fermionic, bring indices into i',j',..,dag(j),dag(i)
71+ # ordering with Out indices coming before In indices
72+ # Resulting tensor acts like a normal matrix (no extra signs
73+ # when taking powers A^n)
74+ if all (j-> dir (j)== Out, Linds) && all (j-> dir (j)== In, Rinds)
75+ ordered_inds = [Linds... , reverse (Rinds)... ]
76+ elseif all (j-> dir (j)== Out, Rinds) && all (j-> dir (j)== In, Linds)
77+ ordered_inds = [Rinds... , reverse (Linds)... ]
78+ else
79+ error (
80+ " For fermionic exp, Linds and Rinds must have same directions within each set. Got dir.(Linds)=" ,
81+ dir .(Linds),
82+ " , dir.(Rinds)=" ,
83+ dir .(Rinds),
84+ )
7385 end
86+ A = permute (A, ordered_inds)
87+ # A^n now sign free, ok to temporarily disable fermion system
88+ disable_auto_fermion ()
7489 end
7590
76- CL = combiner (Lis ... ; dir= Out)
77- CR = combiner (Ris ... ; dir= In)
91+ CL = combiner (Linds ... ; dir= Out)
92+ CR = combiner (Rinds ... ; dir= In)
7893 AC = (A * CR) * CL
7994 expAT = ishermitian ? exp (Hermitian (tensor (AC))) : exp (tensor (AC))
80- return (itensor (expAT) * dag (CR)) * dag (CL)
95+ expA = (itensor (expAT) * dag (CR)) * dag (CL)
96+
97+ # <fermions>
98+ if auto_fermion_enabled
99+ # Ensure expA indices in "matrix" form before re-enabling fermion system
100+ expA = permute (expA, ordered_inds)
101+ enable_auto_fermion ()
102+ end
103+
104+ return expA
81105end
82106
83107function exp (A:: ITensor ; kwargs... )
84108 Ris = filterinds (A; plev= 0 )
85- Lis = Ris'
109+ Lis = dag .( prime .( Ris))
86110 return exp (A, Lis, Ris; kwargs... )
87111end
88112
0 commit comments