Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
cf42e16
Add `BPEnv`
lkdvos Jun 13, 2025
9765a5c
Add `BPEnv` constructors
lkdvos Jun 13, 2025
6a17656
Add BP contractions
lkdvos Jun 13, 2025
ccae695
Add BP VectorInterface support
lkdvos Jun 13, 2025
247aa59
Add BP nearest neighbor expectation values
lkdvos Jun 14, 2025
c00f847
Add bp normalization
lkdvos Jun 14, 2025
8b91621
Move contractions to separate file
lkdvos Jun 14, 2025
96c3535
Add BP fixed point
lkdvos Jun 14, 2025
48942df
Add `gauge_fix` function
lkdvos Jun 14, 2025
5f668b3
Remove repeated `import VectorInterface`
Yue-Zhengyuan Jun 18, 2025
3243ec8
Format
kshyatt Nov 18, 2025
baaa600
Kill ProductSpaceLike
kshyatt Nov 18, 2025
9b41f64
Try to add some simple tests
kshyatt Nov 18, 2025
32a8ecc
Add BP to the test workflow too and format
kshyatt Nov 18, 2025
9c47930
Death to VectorInterface
kshyatt Nov 18, 2025
60939e7
Some 0.7 updates
kshyatt Nov 18, 2025
d03e1f0
Format
kshyatt Nov 18, 2025
74b987e
Absorb sqrt(weights) into vertex tensors [skip ci]
Yue-Zhengyuan Nov 19, 2025
88824b6
Add docstring for BPEnv [skip ci]
Yue-Zhengyuan Nov 19, 2025
b216bc5
export BPEnv, BeliefPropagation
Yue-Zhengyuan Nov 20, 2025
feb9505
Fix bond mismatch and enforce Hermiticity in `bp_iteration`
Yue-Zhengyuan Nov 20, 2025
8cb1bb4
Add test to compare BP and SU fixed point
Yue-Zhengyuan Nov 20, 2025
b15a5a7
Fix BP gauge fixing
Yue-Zhengyuan Nov 20, 2025
9a94435
Fix formatting
Yue-Zhengyuan Nov 20, 2025
14675d4
Preserve virtual arrows with flip_svd
Yue-Zhengyuan Nov 22, 2025
1f5997b
Implement rotation of BPEnv
Yue-Zhengyuan Nov 22, 2025
8f3dbff
Merge remote-tracking branch 'upstream/master' into bp
Yue-Zhengyuan Nov 22, 2025
e5d17a8
Add BPEnv to CTMRGEnv conversion [skip ci]
Yue-Zhengyuan Nov 22, 2025
d45065b
Separate bp_fixedpoint and gauge_fix
Yue-Zhengyuan Nov 23, 2025
63e7884
Rename test file
Yue-Zhengyuan Nov 23, 2025
5f168f0
Add docstring for BPEnv constructors
Yue-Zhengyuan Nov 23, 2025
f56343c
Add Base.size
Yue-Zhengyuan Nov 23, 2025
d989a4c
Add BP expectation value test
Yue-Zhengyuan Nov 23, 2025
6c6a47c
Fix unitcell test
Yue-Zhengyuan Nov 23, 2025
21ce542
Merge branch 'master' into bp
lkdvos Dec 4, 2025
8480184
add some type properties, simplify CTMRGEnv converter
lkdvos Dec 4, 2025
c8a950b
make hermiticity an algorithm parameter
lkdvos Dec 4, 2025
d956d93
improve docstrings, add miniter
lkdvos Dec 4, 2025
0742297
normalize BP error criterion
lkdvos Dec 4, 2025
1515491
small fixes
lkdvos Dec 4, 2025
a27dca1
refactor gauge fixing
lkdvos Dec 4, 2025
e8cc860
improve type stability
lkdvos Dec 4, 2025
e7b2b26
initialize PEPS messages with identity
lkdvos Dec 4, 2025
0979971
return gauges
lkdvos Dec 4, 2025
a42e715
small fixes
lkdvos Dec 4, 2025
826ef10
Merge remote-tracking branch 'upstream/master' into bp
Yue-Zhengyuan Jan 6, 2026
590bdb4
Adapt to removal of flip_svd
Yue-Zhengyuan Jan 6, 2026
e4554f2
Separate BPGauge from BP
Yue-Zhengyuan Jan 7, 2026
3635a4c
Bring back `SUWeight(::BPEnv)`
Yue-Zhengyuan Jan 7, 2026
bba8163
Move `random_dual!` to utils; add fermion gauge fix test
Yue-Zhengyuan Jan 7, 2026
ea866df
Refactor BPEnv constructor
Yue-Zhengyuan Jan 7, 2026
37adcfb
Move trivial SU gauging to src
Yue-Zhengyuan Jan 7, 2026
bd34b9b
Add `BPEnv(::SUWeight)`
Yue-Zhengyuan Jan 7, 2026
c3b49f8
Change west, south message axis order
Yue-Zhengyuan Jan 8, 2026
11daeae
Temp. remove fermion gauging test; add non-hermitian test
Yue-Zhengyuan Jan 8, 2026
32a2f8f
Automatically check Hermiticity of messages when fixing gauge
Yue-Zhengyuan Jan 8, 2026
6c239e0
Add `posdef` option for BPEnv constructors
Yue-Zhengyuan Jan 8, 2026
ae0496f
Handle posdef-ness of fermionic messages
Yue-Zhengyuan Jan 8, 2026
9fcb13b
Fix BP for fermions with non-standard virtual arrows
Yue-Zhengyuan Jan 8, 2026
0b6fc6e
Update docstrings and error messages
Yue-Zhengyuan Jan 8, 2026
412726b
Update docstrings again
Yue-Zhengyuan Jan 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/PEPSKit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,13 @@ include("operators/models.jl")
include("environments/ctmrg_environments.jl")
include("environments/vumps_environments.jl")
include("environments/suweight.jl")
include("environments/bp_environments.jl")

include("algorithms/contractions/ctmrg_contractions.jl")
include("algorithms/contractions/transfer.jl")
include("algorithms/contractions/localoperator.jl")
include("algorithms/contractions/vumps_contractions.jl")
include("algorithms/contractions/bp_contractions.jl")
include("algorithms/contractions/bondenv/benv_tools.jl")
include("algorithms/contractions/bondenv/gaugefix.jl")
include("algorithms/contractions/bondenv/als_solve.jl")
Expand All @@ -69,6 +71,8 @@ include("algorithms/ctmrg/simultaneous.jl")
include("algorithms/ctmrg/sequential.jl")
include("algorithms/ctmrg/gaugefix.jl")

include("algorithms/bp/beliefpropagation.jl")

include("algorithms/truncation/truncationschemes.jl")
include("algorithms/truncation/fullenv_truncation.jl")
include("algorithms/truncation/bond_truncation.jl")
Expand Down
138 changes: 138 additions & 0 deletions src/algorithms/bp/beliefpropagation.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
@kwdef struct BeliefPropagation
maxiter::Int = 10
tol::Float64 = 1.0e-6
verbosity::Int = 2
end

function gauge_fix(psi::InfinitePEPS, alg::BeliefPropagation, env::BPEnv = BPEnv(psi))
# Compute belief propagation fixed point solutions
env, err = bp_fixedpoint(env, InfiniteSquareNetwork(psi), alg)

# Bring PEPS to the Vidal gauge
sqrtmsgs = map(env.messages) do M
U, S, Vᴴ = tsvd!(M)
sqrtM = U * sdiag_pow(S, 1 / 2) * Vᴴ
isqrtM = U * sdiag_pow(S, -1 / 2) * Vᴴ
return sqrtM, isqrtM
end
Comment thread
Yue-Zhengyuan marked this conversation as resolved.
Outdated
bond_svds = map(eachcoordinate(psi, 1:2)) do (dir, r, c)
# TODO: would be more reasonable to define SOUTH as adjoint(NORTH)...
MM = sqrtmsgs[dir, r, c][1] * transpose(sqrtmsgs[mod1(dir + 2, 4), r, c][1])
U, S, Vᴴ = tsvd!(MM)
return U, S, Vᴴ
end
vertices = map(eachcoordinate(psi)) do (r, c)
isqrtM_north = sqrtmsgs[NORTH, _prev(r, end), c][2]
isqrtM_south = sqrtmsgs[SOUTH, _next(r, end), c][2]
isqrtM_east = sqrtmsgs[EAST, r, _next(c, end)][2]
isqrtM_west = sqrtmsgs[WEST, r, _prev(c, end)][2]

U_north = bond_svds[NORTH, _prev(r, end), c][1]
U_east = bond_svds[EAST, r, _next(c, end)][1]
Vᴴ_south = bond_svds[NORTH, _next(r, end), c][3]
Vᴴ_west = bond_svds[EAST, r, _prev(c, end)][3]

@tensor contractcheck = true begin
A[d; DN DE DS DW] ≔
psi[r, c][d; DN1 DE1 DS1 DW1] *
(isqrtM_north[DN1; DN2] * U_north[DN2; DN]) *
(isqrtM_east[DE1; DE2] * U_east[DE2; DE]) *
(isqrtM_south[DS1; DS2] * Vᴴ_south[DS; DS2]) *
(isqrtM_west[DW1; DW2] * Vᴴ_west[DW; DW2])
end
return A
end
# TODO: decide on a convention here, possibly altering InfiniteWeightPEPS
weight_mats = SUWeight(
map(eachcoordinate(psi, 1:2)) do (dir, r, c)
if dir == 1 # horizontal direction
return bond_svds[EAST, r, _next(c, end)][2]
else # vertical direction
return bond_svds[NORTH, _prev(r, end), c][2]
end
end,
)
return InfiniteWeightPEPS(vertices, weight_mats)
end

function bp_fixedpoint(env::BPEnv, network::InfiniteSquareNetwork, alg::BeliefPropagation)
log = MPSKit.IterLog("BP")
ϵ = Inf

return LoggingExtras.withlevel(; alg.verbosity) do
@infov 1 loginit!(log, ϵ)
iter = 0
while true
iter += 1
env′ = bp_iteration(network, env, alg)
ϵ = oftype(ϵ, tr_distance(env, env′))
env = env′

if ϵ < alg.tol
@infov 2 logfinish!(log, iter, ϵ)
return env, ϵ
end
if iter ≥ alg.maxiter
@warnv 1 logcancel!(log, iter, ϵ)
return env, ϵ
end

@infov 3 logiter!(log, iter, ϵ)
end
end
end

function bp_iteration(network::InfiniteSquareNetwork, env::BPEnv, alg::BeliefPropagation)
messages = similar(env.messages)
for I in eachindex(IndexCartesian(), messages)
dir, row, col = Tuple(I)
if dir == NORTH
row += 1
elseif dir == EAST
col += 1
elseif dir == SOUTH
row -= 1
elseif dir == WEST
col -= 1
end
messages[dir, mod1(row, end), mod1(col, end)] = normalize!(
update_message(I, network, env)
)
end
return BPEnv(messages)
end

function update_message(I::CartesianIndex{3}, network::InfiniteSquareNetwork, env::BPEnv)
dir, row, col = Tuple(I)

A = network[row, col]
dir == SOUTH || (M_north = env.messages[NORTH, _prev(row, end), col])
dir == WEST || (M_east = env.messages[EAST, row, _next(col, end)])
dir == NORTH || (M_south = env.messages[SOUTH, _next(row, end), col])
dir == EAST || (M_west = env.messages[WEST, row, _prev(col, end)])

return if dir == NORTH
contract_north_message(A, M_west, M_north, M_east)
elseif dir == EAST
contract_east_message(A, M_north, M_east, M_south)
elseif dir == SOUTH
contract_south_message(A, M_east, M_south, M_west)
elseif dir == WEST
contract_west_message(A, M_south, M_west, M_north)
else
throw(ArgumentError("Invalid direction $dir"))
end
end

function tr_distance(A::BPEnv, B::BPEnv)
return sum(zip(A.messages, B.messages)) do (a, b)
return trnorm(add(a, b, -inv(tr(b)), inv(tr(a))))
end
end

function trnorm(M::AbstractTensorMap, p::Real = 1)
return TensorKit._norm(svdvals(M), p, zero(real(scalartype(M))))
end
function trnorm!(M::AbstractTensorMap, p::Real = 1)
return TensorKit._norm(svdvals!(M), p, zero(real(scalartype(M))))
end
Loading