Skip to content

Commit 57dc354

Browse files
Add quantum Ashkin-Teller model (#67)
1 parent 4e7ce75 commit 57dc354

6 files changed

Lines changed: 125 additions & 0 deletions

File tree

docs/src/man/models.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ heisenberg_XXZ
1515
heisenberg_XYZ
1616
bilinear_biquadratic_model
1717
tj_model
18+
ashkin_teller
1819
hubbard_model
1920
bose_hubbard_model
2021
quantum_chemistry_hamiltonian

src/MPSKitModels.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export heisenberg_XXX, heisenberg_XXZ, heisenberg_XYZ
4545
export bilinear_biquadratic_model
4646
export hubbard_model, bose_hubbard_model
4747
export tj_model
48+
export ashkin_teller
4849
export quantum_chemistry_hamiltonian
4950

5051
export classical_ising

src/models/hamiltonians.jl

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,4 +461,75 @@ function tj_model(
461461
end
462462
end
463463

464+
#===========================================================================================
465+
Quantum Ashkin-Teller model
466+
===========================================================================================#
467+
"""
468+
ashkin_teller([T::Type{<:Number} = ComplexF64], [S = Trivial],
469+
[lattice::AbstractLattice = InfiniteChain(1)];
470+
h = 1.0, J = 1.0, λ = 1.0)
471+
472+
MPO for the hamiltonian of the quantum Ashkin-Teller model. The model is
473+
defined on a chain of two qubits per site. Writing Pauli operators on each of these qubits
474+
as ``\\sigma `` and ``\\tau ``, the Hamiltonian reads:
475+
```math
476+
H = -h \\sum_i\\bigg(\\sigma_i^x + \\tau_i^x + \\lambda \\sigma_i^x \\tau_i^x \\bigg)
477+
-J \\sum_{\\langle i,j \\rangle} \\bigg( \\sigma_i^z \\sigma_j^z + \\tau_i^z \\tau_j^z
478+
+\\lambda \\sigma_i^z \\sigma_j^z \\tau_i^z \\tau_j^z \\bigg).
479+
480+
```
481+
"""
482+
function ashkin_teller end
483+
function ashkin_teller(lattice::AbstractLattice; kwargs...)
484+
return ashkin_teller(ComplexF64, Trivial, lattice; kwargs...)
485+
end
486+
function ashkin_teller(symmetry::Type{<:Sector}; kwargs...)
487+
return ashkin_teller(ComplexF64, symmetry; kwargs...)
488+
end
489+
function ashkin_teller(T::Type{<:Number}, lattice::AbstractLattice; kwargs...)
490+
return ashkin_teller(T, Trivial, lattice; kwargs...)
491+
end
492+
function ashkin_teller(
493+
T::Type{<:Number} = ComplexF64, S::Type{<:Sector} = Trivial,
494+
lattice::AbstractLattice = InfiniteChain(1);
495+
h = 1.0, J = 1.0, λ = 1.0
496+
)
497+
S₁, S₂ = _ashin_teller_decompose_symmetry(S)
498+
499+
# component tensors
500+
X₁ = σˣ(T, S₁)
501+
Z₁Z₁ = σᶻᶻ(T, S₁)
502+
I₁ = id(T, domain(X₁))
503+
I₁I₁ = id(T, domain(Z₁Z₁))
504+
505+
Z₂Z₂ = σᶻᶻ(T, S₂)
506+
X₂ = σˣ(T, S₂)
507+
I₂ = id(T, domain(X₂))
508+
I₂I₂ = id(T, domain(Z₂Z₂))
509+
510+
# Single site operators
511+
XI = X₁ I₂
512+
IX = I₁ X₂
513+
XX = X₁ X₂
514+
F = isometry(Int, fuse(domain(XX)) domain(XX))
515+
onsite = F * (-h * (XI + IX + λ * XX)) * F'
516+
517+
# Nearest-neighbour terms
518+
@tensor FF[-1 -2; -3 -5 -4 -6] := F[-1; -3 -4] * F[-2; -5 -6] # note permutation!
519+
ZIZI = FF * (Z₁Z₁ I₂I₂) * FF'
520+
IZIZ = FF * (I₁I₁ Z₂Z₂) * FF'
521+
ZZZZ = FF * (Z₁Z₁ Z₂Z₂) * FF'
522+
twosite = -J * (ZIZI + IZIZ + λ * ZZZZ)
523+
524+
return @mpoham sum(vertices(lattice)) do i
525+
return onsite{i}
526+
end + sum(nearest_neighbours(lattice)) do (i, j)
527+
return twosite{i, j}
528+
end
529+
end
530+
531+
_ashin_teller_decompose_symmetry(::Type{Trivial}) = (Trivial, Trivial)
532+
_ashin_teller_decompose_symmetry(::Type{ProductSector{Tuple{A, B}}}) where {A <: Union{Trivial, Z2Irrep}, B <: Union{Trivial, Z2Irrep}} = (A, B)
533+
_ashin_teller_decompose_symmetry(T) = error("Ashkin-Teller model not implemented for symmetry $T")
534+
464535
# TODO: add (hardcore) bosonic t-J model (https://arxiv.org/abs/2409.15424)

src/utility.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,15 @@ function split_twosite(O::AbstractTensorMap{<:Any, <:Any, 2, 2})
5757
@plansor R[a p'; p] := sqrtS[a; 1] * V[1; p p']
5858
return L, R
5959
end
60+
61+
#===========================================================================================
62+
Other utility
63+
===========================================================================================#
64+
65+
"""
66+
flip_charge(charge, flip)
67+
68+
Take the product of charge with flip.
69+
Works only for abelian symmetries.
70+
"""
71+
flip_charge(charge, flip) = only(charge sectortype(charge)(flip))

test/ashkin_teller.jl

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using Test
2+
using TensorKit
3+
using MPSKit
4+
using MPSKitModels
5+
6+
# Setup
7+
8+
gammas = [
9+
pi / 2, pi / 3, pi / 4, pi / 6, 0,
10+
]
11+
# Exact GS energy density via mapping to spin 1/2 XXZ and Bethe ansatz
12+
# https://www.sciencedirect.com/science/article/pii/0003491688900152
13+
E0s = [
14+
-8 / pi, -12 / 4, -4 * (sqrt(2) / pi + 1 / (2 * sqrt(2))),
15+
-4 * (1 / pi + 11 / (12 * sqrt(3))), 2 - 8 * log(2),
16+
]
17+
alg = VUMPS(; maxiter = 100, verbosity = 0)
18+
19+
# Test
20+
21+
@testset "Ashkin-Teller" for (gamma, E0) in zip(gammas, E0s)
22+
H = ashkin_teller(h = 1, J = 1, λ = cos(gamma))
23+
Ψ = InfiniteMPS(physicalspace(H), [ComplexSpace(24)])
24+
@test imag(expectation_value(Ψ, H)) 0 atol = 1.0e-12
25+
Ψ0, _ = find_groundstate(Ψ, H, alg)
26+
@test real(expectation_value(Ψ0, H)) E0 atol = 1.0e-3
27+
end
28+
29+
@testset "Ashkin-Teller (Z2 ⊠ Z2)" for (gamma, E0) in zip(gammas, E0s)
30+
H = ashkin_teller(Z2Irrep Z2Irrep; h = 1, J = 1, λ = cos(gamma))
31+
V = spacetype(H)(c => 6 for c in values(sectortype(H)))
32+
Ψ = InfiniteMPS(physicalspace(H), [V])
33+
@test imag(expectation_value(Ψ, H)) 0 atol = 1.0e-12
34+
Ψ0, _ = find_groundstate(Ψ, H, alg)
35+
@test real(expectation_value(Ψ0, H)) E0 atol = 1.0e-3
36+
end

test/runtests.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ end
4545
include("quantum_potts.jl")
4646
end
4747

48+
@testset "quantum Ashkin-Teller model" begin
49+
include("ashkin_teller.jl")
50+
end
51+
4852
@testset "classical ising model" begin
4953
include("classical_ising.jl")
5054
end

0 commit comments

Comments
 (0)