First off simply change ampo += ...
to ampo .+=
, this way you are directly modifying ampo
each time instead of constructing a copy and then reassigning it. With this one character modification here are my timings
julia> include("foo.jl"); # ampo += ...
Time for N = 10: 0.018505916
Time for N = 30: 3.156324
Time for N = 40: 32.901548875
julia> include("foo.jl"); # ampo .+= ...
Time for N = 10: 0.014833458
Time for N = 30: 0.033778666
Time for N = 40: 0.095046791
Time for N = 50: 0.271597917
Time for N = 60: 0.841291958
That said, I have encountered situations where this change simply isn’t fast enough, or when memory is limited, that’s why I created OpIDSum
.
I just merged a PR to ITensorMPOConstruction
that should get rid of the version conflicts (for now at least). Below is the example code modified to also use ITensorMPOConstruction.MPO_new
both from an OpSum
and OpIDSum
. TLDR is that for this case OpSum
is probably fast enough, and that MPO_new
can construct the MPO for N = 110 in the time it takes ITensorMPS.MPO
to construct for N = 50.
Code
using ITensorMPS
using Combinatorics
using ITensorMPOConstruction
function H_OpSum(N)::OpSum{Float64}
os = OpSum{Float64}()
for (k1,k2,k3,k4) in collect(combinations(1:N, 4))
os .+= 2*(N-k4),"Z",k1,"Z",k2,"Z",k3,"Z",k4
end
return os
end
function H_OpIDSum(N)::Tuple{OpIDSum{Float64}, Vector{Vector{String}}}
operatorNames = [["I", "Z"] for _ in 1:N]
opZ(n) = OpID(2, n)
os = OpIDSum{Float64}()
for (k1,k2,k3,k4) in collect(combinations(1:N, 4))
push!(os, Float64(2*(N-k4)), opZ(k1), opZ(k2), opZ(k3), opZ(k4))
end
return os, operatorNames
end
for N in [10:10:120]
sites = siteinds("Qubit", N)
println("N = $N")
if N <= 50
@time "\tOpSum construction " os = H_OpSum(N)
@time "\tMPO construction " mpo = MPO(os, sites)
@time "\tMPO_new construction" mpo = MPO_new(os, sites)
end
@time "\tOpIDSum construction" os, operatorNames = H_OpIDSum(N)
@time "\tMPO_new construction" mpo = MPO_new(os, sites, operatorNames; basis_op_cache_vec=operatorNames)
println()
end
Output
N = 10
OpSum construction : 0.000198 seconds (8.41 k allocations: 554.844 KiB)
MPO construction : 0.011609 seconds (149.35 k allocations: 16.557 MiB)
MPO_new construction: 0.001477 seconds (11.27 k allocations: 1.067 MiB)
OpIDSum construction: 0.000036 seconds (452 allocations: 55.156 KiB)
MPO_new construction: 0.001240 seconds (10.66 k allocations: 1.308 MiB)
N = 20
OpSum construction : 0.003953 seconds (193.81 k allocations: 12.399 MiB)
MPO construction : 0.406268 seconds (4.61 M allocations: 438.247 MiB)
MPO_new construction: 0.017774 seconds (155.02 k allocations: 17.642 MiB)
OpIDSum construction: 0.000392 seconds (9.74 k allocations: 1.029 MiB)
MPO_new construction: 0.016200 seconds (113.98 k allocations: 19.220 MiB)
N = 30
OpSum construction : 0.031350 seconds (1.10 M allocations: 70.375 MiB)
MPO construction : 3.718616 seconds (33.19 M allocations: 2.870 GiB, 9.76% gc time)
MPO_new construction: 0.100924 seconds (834.97 k allocations: 118.611 MiB)
OpIDSum construction: 0.001746 seconds (54.88 k allocations: 6.059 MiB)
MPO_new construction: 0.088726 seconds (592.16 k allocations: 124.450 MiB)
N = 40
OpSum construction : 0.092522 seconds (3.66 M allocations: 233.050 MiB)
MPO construction : 17.120962 seconds (134.23 M allocations: 11.427 GiB, 6.97% gc time)
MPO_new construction: 0.419496 seconds (2.78 M allocations: 493.040 MiB, 0.35% compilation time)
OpIDSum construction: 0.006401 seconds (182.86 k allocations: 18.643 MiB)
MPO_new construction: 0.364457 seconds (1.94 M allocations: 510.816 MiB, 9.73% gc time)
N = 50
OpSum construction : 0.265503 seconds (9.21 M allocations: 583.985 MiB, 21.69% gc time)
MPO construction : 70.386649 seconds (400.07 M allocations: 34.228 GiB, 6.95% gc time)
MPO_new construction: 1.170543 seconds (6.95 M allocations: 1.326 GiB, 2.96% gc time, 0.12% compilation time)
OpIDSum construction: 0.015412 seconds (460.69 k allocations: 41.196 MiB)
MPO_new construction: 1.002872 seconds (4.85 M allocations: 1.372 GiB, 3.58% gc time)
N = 60
OpIDSum construction: 0.086254 seconds (975.38 k allocations: 83.676 MiB, 63.58% gc time)
MPO_new construction: 2.551916 seconds (10.29 M allocations: 3.235 GiB, 3.50% gc time, 0.07% compilation time)
N = 70
OpIDSum construction: 0.092260 seconds (1.83 M allocations: 157.595 MiB, 23.97% gc time)
MPO_new construction: 6.453138 seconds (19.29 M allocations: 6.803 GiB, 10.16% gc time, 0.03% compilation time)
N = 80
OpIDSum construction: 0.142721 seconds (3.16 M allocations: 280.324 MiB, 15.90% gc time)
MPO_new construction: 12.330305 seconds (33.23 M allocations: 12.989 GiB, 6.08% gc time, 0.02% compilation time)
N = 90
OpIDSum construction: 0.243893 seconds (5.11 M allocations: 479.688 MiB, 15.81% gc time)
MPO_new construction: 22.095196 seconds (53.65 M allocations: 22.364 GiB, 6.99% gc time, 0.01% compilation time)
N = 100
OpIDSum construction: 0.347497 seconds (7.84 M allocations: 656.863 MiB, 16.94% gc time)
MPO_new construction: 40.768082 seconds (82.30 M allocations: 37.863 GiB, 7.64% gc time, 0.00% compilation time)
N = 110
OpIDSum construction: 0.499944 seconds (11.55 M allocations: 1011.284 MiB, 15.51% gc time)
MPO_new construction: 67.607090 seconds (121.15 M allocations: 59.888 GiB, 11.14% gc time, 0.00% compilation time)
N = 120
OpIDSum construction: 0.793480 seconds (16.43 M allocations: 1.342 GiB, 19.97% gc time)
MPO_new construction: 142.217085 seconds (172.36 M allocations: 86.625 GiB, 30.62% gc time, 0.00% compilation time)