-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
222 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
using QMTK | ||
using QMTK.Consts.Pauli | ||
import IterTools | ||
|
||
struct FusedHamiltonian{D<:Tuple} <: AbstractHamiltonian | ||
data::D | ||
end | ||
|
||
FusedHamiltonian(h::LocalHamiltonian...) = FusedHamiltonian(h) | ||
function (h::FusedHamiltonian)(lattice::AbstractLattice, rhs::AbstractSites) | ||
itrs = [] | ||
for each in h.data | ||
push!(itrs, RegionIterator(each, lattice, rhs)) | ||
end | ||
IterTools.chain(itrs...) | ||
end | ||
|
||
|
||
function make_hamiltonian(ex::Expr) | ||
expr = Expr(:call, :FusedHamiltonian) | ||
if Meta.isexpr(ex, :call) | ||
if ex.args[1] == :sum # only one region | ||
ex.args[1] = :LocalHamiltonian | ||
return ex | ||
elseif ex.args[1] == :+ | ||
for each in ex.args[2:end] | ||
if each.args[1] == :sum | ||
each.args[1] = :LocalHamiltonian | ||
push!(expr.args, each) | ||
elseif each.args[1] == :* | ||
factor = each.args[2] | ||
each.args[3].args[1] = :LocalHamiltonian | ||
each.args[3].args[end] = Expr(:call, :*, factor, each.args[3].args[end]) | ||
push!(expr.args, each.args[3]) | ||
else | ||
throw(ErrorException("Invalid Expression: $each")) | ||
end | ||
end | ||
elseif ex.args[1] == :- | ||
# preserve sign for the first one | ||
each = ex.args[2] | ||
if each.args[1] == :sum | ||
each.args[1] = :LocalHamiltonian | ||
push!(expr.args, each) | ||
elseif each.args[1] == :* | ||
factor = each.args[2] | ||
each.args[3].args[1] = :LocalHamiltonian | ||
each.args[3].args[end] = Expr(:call, :*, factor, each.args[3].args[end]) | ||
push!(expr.args, each.args[3]) | ||
else | ||
throw(ErrorException("Invalid Expression: $each")) | ||
end | ||
|
||
for each in ex.args[3:end] | ||
if each.args[1] == :sum | ||
each.args[1] = :LocalHamiltonian | ||
each.args[end] = Expr(:call, :*, -1, each.args[end]) # merge -1 to local matrix | ||
push!(expr.args, each) | ||
elseif each.args[1] == :* | ||
factor = each.args[2] | ||
each.args[3].args[1] = :LocalHamiltonian | ||
each.args[3].args[end] = Expr(:call, :*, -1, factor, each.args[3].args[end]) | ||
push!(expr.args, each.args[3]) | ||
else | ||
throw(ErrorException("Invalid Expression: $each")) | ||
end | ||
end | ||
end | ||
else | ||
throw(ErrorException("Invalid Expression: $each")) | ||
end | ||
return expr | ||
end | ||
|
||
macro ham(expr::Expr) | ||
make_hamiltonian(expr) | ||
end | ||
|
||
h = @ham sum(Region{1}, σ₁⊗σ₂) + sum(Region{2}, σ₁⊗σ₂) | ||
|
||
chain = Chain(Fixed, 4) | ||
rhs = rand(Bit, 4) | ||
for (val, lhs) in h(chain, rhs) | ||
@show val | ||
@show lhs | ||
end | ||
|
||
# # merge factor into local matrix | ||
# @ham 2 * sum(Region{1}, σ₁⊗σ₂) # => sum(Region{1}, 2 * σ₁⊗σ₂) | ||
|
||
# mat = σ₁⊗σ₂ | ||
# h1 = LocalHamiltonian(Region{1}, mat) | ||
# h2 = LocalHamiltonian(Region{2}, mat) | ||
|
||
# FusedHamiltonian(h1, h2) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
import QMTK: toexpr, kronparse, getid, Chain, Fixed, bonds, kronsum | ||
using QMTK.Consts.Pauli | ||
|
||
mutable struct ExprKernel | ||
ex::Expr | ||
legs::Vector | ||
end | ||
|
||
function ExprKernel(ex::Expr) | ||
kernel = make_kernel_legs!(ExprKernel(ex, [])) | ||
kernel.ex = expr2lambda(ex) | ||
return kernel | ||
end | ||
|
||
function toexpr(kernel::ExprKernel) | ||
Expr(:->, Expr(:tuple, kernel.legs...), Expr(:block, Expr(:quote, kernel.ex))) | ||
end | ||
|
||
make_kernel_legs!(kernel::ExprKernel, ex::Symbol) = kernel | ||
make_kernel_legs!(kernel::ExprKernel) = make_kernel_legs!(kernel, kernel.ex) | ||
|
||
function make_kernel_legs!(kernel::ExprKernel, ex::Expr) | ||
if Meta.isexpr(ex, :call) | ||
for each in ex.args | ||
make_kernel_legs!(kernel, each) | ||
end | ||
elseif Meta.isexpr(ex, :ref) | ||
for each in ex.args[2:end] | ||
if !(each in kernel.legs) | ||
push!(kernel.legs, each) | ||
end | ||
end | ||
else | ||
throw(ErrorException("Invalid Expression $(ex)")) | ||
end | ||
return kernel | ||
end | ||
|
||
function ref2lambda(expr) | ||
for i = 2:length(expr.args) | ||
expr.args[i] = Expr(:$, expr.args[i]) | ||
end | ||
return expr | ||
end | ||
|
||
function expr2lambda(expr) | ||
if isa(expr, Symbol) | ||
return expr | ||
end | ||
|
||
if Meta.isexpr(expr, :call) | ||
for (i, each) in enumerate(expr.args) | ||
expr.args[i] = expr2lambda(each) | ||
end | ||
elseif Meta.isexpr(expr, :ref) | ||
return ref2lambda(expr) | ||
else | ||
throw(ErrorException("Invalid Expression $(expr)")) | ||
end | ||
return expr | ||
end | ||
|
||
macro kron(region, expr) | ||
kernels = [] | ||
if Meta.isexpr(expr, :block) | ||
for each in expr.args | ||
if !Meta.isexpr(each, :line) | ||
push!(kernels, ExprKernel(each)) | ||
end | ||
end | ||
else | ||
push!(kernels, ExprKernel(expr)) | ||
end | ||
|
||
kernel = kernels[1] | ||
|
||
kernel_ex = toexpr(kernel) | ||
ex = :(kronsum($(esc(kernel_ex)), $region)) | ||
for kernel in kernels[2:end] | ||
ex = :(kronsum($(esc(toexpr(kernel))), $region) + $ex) | ||
end | ||
|
||
return ex | ||
end | ||
|
||
|
||
# kernel = ExprKernel(:(σ₁[i] * σ₁[j])) | ||
# f = eval(toexpr(kernel)) | ||
# println(f(1, 2)) | ||
chain = Chain(Fixed, 4) | ||
# f = @kron bonds(chain, 1) | ||
# println(f(1, 2)) | ||
h = @kron bonds(chain, 1) σ₁[i] * σ₁[j] | ||
|
||
# t = kronsum(bonds(chain, 1)) do i, j | ||
# :(σ₁[$i] * σ₁[$j]) | ||
# end | ||
|
||
println(h == t) | ||
# println(@macroexpand @kron bonds(chain, 1) σ₁[i] * σ₁[j]) | ||
|
||
# kernel = ExprKernel(:(a[i] * (b[j] + c[k]))) | ||
|
||
# println(kernel.legs) | ||
# ex = toexpr(kernel) | ||
# f = eval(ex) | ||
# println(f(1, 2, 3)) | ||
# println(kernel.ex) | ||
# println(kernel.legs) | ||
|
||
# i, j, k = 2, 3, 4 | ||
# # ex = expr2lambda(:(a[i] * (b[j] + c[k]))) | ||
# # expr2kernel(ex) | ||
|
||
# ex = eval(Expr(:quote, kernel.ex)) | ||
# println(ex) | ||
|
||
# # @kron sum(bonds(chain, 1)) a[i] * b[j] | ||
|
||
# # @kron sum(bonds(chain, 1)) begin | ||
# # a[i] * b[j] | ||
# # a[i] * b[j] | ||
# # end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters