|
1 | 1 | @kwdef struct BeliefPropagation |
2 | 2 | maxiter::Int = 10 |
| 3 | + tol::Float64 = 1e-6 |
| 4 | + verbosity::Int = 2 |
| 5 | +end |
| 6 | + |
| 7 | +function bp_fixedpoint(env::BPEnv, network::InfiniteSquareNetwork, alg::BeliefPropagation) |
| 8 | + log = MPSKit.IterLog("BP") |
| 9 | + ϵ = Inf |
| 10 | + |
| 11 | + return LoggingExtras.withlevel(; alg.verbosity) do |
| 12 | + @infov 1 loginit!(log, ϵ) |
| 13 | + iter = 0 |
| 14 | + while true |
| 15 | + iter += 1 |
| 16 | + env′ = bp_iteration(network, env, alg) |
| 17 | + ϵ = oftype(ϵ, tr_distance(env, env′)) |
| 18 | + env = env′ |
| 19 | + |
| 20 | + if ϵ < alg.tol |
| 21 | + @infov 2 logfinish!(log, iter, ϵ) |
| 22 | + return env, ϵ |
| 23 | + end |
| 24 | + if iter ≥ alg.maxiter |
| 25 | + @warnv 1 logcancel!(log, iter, ϵ) |
| 26 | + return env, ϵ |
| 27 | + end |
| 28 | + |
| 29 | + @infov 3 logiter!(log, iter, ϵ) |
| 30 | + end |
| 31 | + end |
3 | 32 | end |
4 | 33 |
|
5 | 34 | function bp_iteration(network::InfiniteSquareNetwork, env::BPEnv, alg::BeliefPropagation) |
@@ -43,3 +72,16 @@ function update_message(I::CartesianIndex{3}, network::InfiniteSquareNetwork, en |
43 | 72 | throw(ArgumentError("Invalid direction $dir")) |
44 | 73 | end |
45 | 74 | end |
| 75 | + |
| 76 | +function tr_distance(A::BPEnv, B::BPEnv) |
| 77 | + return sum(zip(A.messages, B.messages)) do (a, b) |
| 78 | + return trnorm(add(a, b, -inv(tr(b)), inv(tr(a)))) |
| 79 | + end |
| 80 | +end |
| 81 | + |
| 82 | +function trnorm(M::AbstractTensorMap, p::Real=1) |
| 83 | + return TensorKit._norm(svdvals(M), p, zero(real(scalartype(M)))) |
| 84 | +end |
| 85 | +function trnorm!(M::AbstractTensorMap, p::Real=1) |
| 86 | + return TensorKit._norm(svdvals!(M), p, zero(real(scalartype(M)))) |
| 87 | +end |
0 commit comments