Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Solving spinglass ground state with Yao, Tropical numbers and ForwardDiff.
# References
# * Yao:
# * ForwardDiff:
# * Tropical Numbers:
using ForwardDiff, Yao, LinearAlgebra
# define tropical numbers with the following property.
# x ⊕ y := max(x ,y)
# x ⊗ y := x + y
struct Tropical{T} <: Number
Tropical{T}(x::Tropical{T}) where T = x
Base.:*(a::Tropical, b::Tropical) = Tropical(a.n + b.n)
Base.:+(a::Tropical, b::Tropical) = Tropical(max(a.n, b.n)){Tropical{T}}) where T<:Integer = Tropical(T(-999999)){Tropical{T}}) where T<:AbstractFloat = Tropical(typemin(T))
# define the "spinglass gates" that will be used in our "quantum" simulation.
# * `Gh` is the magnetic field term.
# * `G2` is the gate on parallel bond.
# * `G4` is the vertical two qubit diagonal "gate".
Gh(h::Real) = matblock(Diagonal(Tropical.([h, -h])))
G2(Jij::Real) = matblock(Tropical.([Jij -Jij; -Jij Jij]))
G4(Jij::Real) = matblock(Diagonal(Tropical.([Jij, -Jij, -Jij, Jij])))
function square_solve!(Lx::Int, Ly::Int, Js::AbstractVector{T}, hs::AbstractVector{T}; usecuda=false) where T
Js, hs = copy(Js), copy(hs)
reg = ArrayReg(Tropical.(zeros(T, 1<<Ly)))
if usecuda
reg = cu(reg)
for i=1:Lx
println("Layer $i/$Lx")
i!=1 && for j=1:Ly
reg |> put(Ly, j=>G2(Js |> popfirst!))
for j=1:Ly
reg |> put(Ly, j=>Gh(hs |> popfirst!))
for j=1:Ly-1
reg |> put(Ly, (j,j+1)=>G4(Js |> popfirst!))
L = 15
Js = randn(2*L*(L-1))
hs = zeros(L^2)
energy = square_solve!(L, L, Js, hs; usecuda=false)
config = ForwardDiff.gradient(x->square_solve!(L, L,
convert.(eltype(x), Js), x; usecuda=false), hs)
# use cuda
using CuYao
energy = square_solve!(L, L, Js, hs; usecuda=true)
config = ForwardDiff.gradient(x->square_solve!(L, L,
convert.(eltype(x), Js), x; usecuda=true), hs)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment