|
| 1 | +struct AC2Spec{S <: ElementarySpace} # <: BenchmarkSpec |
| 2 | + physicalspaces::NTuple{2, S} |
| 3 | + mps_virtualspaces::NTuple{3, S} |
| 4 | + mpo_virtualspaces::NTuple{3, SumSpace{S}} |
| 5 | + nonzero_keys::NTuple{2, Vector{Tuple{Int, Int}}} |
| 6 | +end |
| 7 | + |
| 8 | +function AC2Spec(mps, mpo; site = length(mps) ÷ 2) |
| 9 | + physicalspaces = (physicalspace(mps, site), physicalspace(mps, site + 1)) |
| 10 | + mps_virtualspaces = (left_virtualspace(mps, site), right_virtualspace(mps, site), right_virtualspace(mps, site + 1)) |
| 11 | + mpo_virtualspaces = (left_virtualspace(mpo, site), right_virtualspace(mpo, site), right_virtualspace(mpo, site + 1)) |
| 12 | + ks = ( |
| 13 | + map(x -> (x.I[1], x.I[4]), nonzero_keys(mpo[site])), |
| 14 | + map(x -> (x.I[1], x.I[4]), nonzero_keys(mpo[site])), |
| 15 | + ) |
| 16 | + return AC2Spec(physicalspaces, mps_virtualspaces, mpo_virtualspaces, ks) |
| 17 | +end |
| 18 | + |
| 19 | +# Benchmarks |
| 20 | +# ---------- |
| 21 | +function MPSKit.MPO_AC2_Hamiltonian(spec::AC2Spec{S}; T::Type = Float64) where {S} |
| 22 | + GL = randn(T, spec.mps_virtualspaces[1] ⊗ spec.mpo_virtualspaces[1]' ← spec.mps_virtualspaces[1]) |
| 23 | + GR = randn(T, spec.mps_virtualspaces[3] ⊗ spec.mpo_virtualspaces[3] ← spec.mps_virtualspaces[3]) |
| 24 | + W1 = JordanMPOTensor{T, S}(undef, spec.mpo_virtualspaces[1] ⊗ spec.physicalspaces[1] ← spec.physicalspaces[1] ⊗ spec.mpo_virtualspaces[2]) |
| 25 | + for (r, c) in spec.nonzero_keys[1] |
| 26 | + r == c == 1 && continue |
| 27 | + r == size(W1, 1) && c == size(W1, 4) && continue |
| 28 | + W1[r, 1, 1, c] = randn!(W1[r, 1, 1, c]) |
| 29 | + end |
| 30 | + W2 = JordanMPOTensor{T, S}(undef, spec.mpo_virtualspaces[2] ⊗ spec.physicalspaces[2] ← spec.physicalspaces[2] ⊗ spec.mpo_virtualspaces[3]) |
| 31 | + for (r, c) in spec.nonzero_keys[2] |
| 32 | + r == c == 1 && continue |
| 33 | + r == size(W2, 1) && c == size(W2, 4) && continue |
| 34 | + W2[r, 1, 1, c] = randn!(W2[r, 1, 1, c]) |
| 35 | + end |
| 36 | + |
| 37 | + return MPSKit.MPO_AC2_Hamiltonian(GL, W1, W2, GR) |
| 38 | +end |
| 39 | + |
| 40 | +function contraction_benchmark(spec::AC2Spec; T::Type = Float64) |
| 41 | + AA = randn(T, spec.mps_virtualspaces[1] ⊗ spec.physicalspaces[1] ← spec.mps_virtualspaces[3] ⊗ spec.physicalspaces[2]') |
| 42 | + H_eff = MPSKit.MPO_AC2_Hamiltonian(spec; T) |
| 43 | + H_prep, x_prep = MPSKit.prepare_operator!!(H_eff, AA) |
| 44 | + init() = randn!(similar(x_prep)) |
| 45 | + |
| 46 | + return @benchmarkable $H_prep * x setup = (x = $init()) |
| 47 | +end |
| 48 | + |
| 49 | +function preparation_benchmark(spec::AC2Spec; T::Type = Float64) |
| 50 | + init() = randn(T, spec.mps_virtualspaces[1] ⊗ spec.physicalspaces[1] ← spec.mps_virtualspaces[3] ⊗ spec.physicalspaces[2]') |
| 51 | + H_eff = MPSKit.MPO_AC2_Hamiltonian(spec; T) |
| 52 | + |
| 53 | + return @benchmarkable begin |
| 54 | + O′, x′ = MPSKit.prepare_operator!!($H_eff, x) |
| 55 | + y = MPSKit.unprepare_operator!!(x′, O′, x) |
| 56 | + end setup = (x = $init()) |
| 57 | +end |
| 58 | + |
| 59 | +# Converters |
| 60 | +# ---------- |
| 61 | +function tomlify(spec::AC2Spec) |
| 62 | + return Dict( |
| 63 | + "physicalspaces" => collect(tomlify.(spec.physicalspaces)), |
| 64 | + "mps_virtualspaces" => collect(tomlify.(spec.mps_virtualspaces)), |
| 65 | + "mpo_virtualspaces" => collect(tomlify.(spec.mpo_virtualspaces)), |
| 66 | + "nonzero_keys" => collect(map(Base.Fix1(map, collect), spec.nonzero_keys)) |
| 67 | + ) |
| 68 | +end |
| 69 | + |
| 70 | +function untomlify(::Type{AC2Spec}, x) |
| 71 | + physicalspaces = Tuple(map(untomlify, x["physicalspaces"])) |
| 72 | + mps_virtualspaces = Tuple(map(untomlify, x["mps_virtualspaces"])) |
| 73 | + mpo_virtualspaces = Tuple(map(untomlify, x["mpo_virtualspaces"])) |
| 74 | + nonzero_keys = Tuple(map(Base.Fix1(map, Base.Fix1(map, Tuple)), x["nonzero_keys"])) |
| 75 | + return AC2Spec(physicalspaces, mps_virtualspaces, mpo_virtualspaces, nonzero_keys) |
| 76 | +end |
| 77 | + |
| 78 | +function Base.convert(::Type{AC2Spec{S₁}}, spec::AC2Spec{S₂}) where {S₁, S₂} |
| 79 | + return S₁ === S₂ ? spec : AC2Spec( |
| 80 | + S₁.(spec.physicalspaces), |
| 81 | + S₁.(spec.mps_virtualspaces), |
| 82 | + SumSpace{S₁}.(spec.mpo_virtualspaces), |
| 83 | + spec.nonzero_keys |
| 84 | + ) |
| 85 | +end |
0 commit comments