Examples using Wolff cluster sampling method
Magnetization as a function of temperature
First load some packages
import IsingModels as Ising
using Statistics, CairoMakie, Random
Random.seed!(1) # make reproducibleFirst example.
βs = 0:0.025:1
fig = Figure(resolution=(600,400))
ax = Axis(fig[1,1], xlabel="β", ylabel="m")
lines!(ax, 0:0.01:1, Ising.onsager_magnetization, color=:black, label="analytical")
mavg = zeros(length(βs))
mstd = zeros(length(βs))
σ = bitrand(32, 32)
for (k,β) in enumerate(βs)
σ_t, M, E = Ising.wolff!(σ, β, steps=10^3)
m = abs.(M[(length(M) ÷ 2):end]) / length(σ)
mavg[k] = mean(m)
mstd[k] = std(m)
end
scatter!(ax, βs, mavg, color=:blue, markersize=5, label="MC, L=30")
errorbars!(ax, βs, mavg, mstd/2, color=:blue, whiskerwidth=5)
mavg = zeros(length(βs))
mstd = zeros(length(βs))
σ = bitrand(64, 64)
for (k,β) in enumerate(βs)
σ_t, M, E = Ising.wolff!(σ, β, steps=10^3)
m = abs.(M[(length(M) ÷ 2):end]) / length(σ)
mavg[k] = mean(m)
mstd[k] = std(m)
end
scatter!(ax, βs, mavg, color=:red, markersize=5, label="MC, L=70")
errorbars!(ax, βs, mavg, mstd/2, color=:red, whiskerwidth=5)
axislegend(ax, position=:rb)
figTypical Wolff clusters at criticality
import IsingModels as Ising
using Random, Colors, ColorSchemes, CairoMakie
Random.seed!(56) # reproducibility
β = Ising.βc
σ = bitrand(512, 512)
Ising.metropolis!(σ, β; steps=10^7)
Ising.wolff!(σ, β, steps=500)
cluster = Ising.wolff_cluster(σ, CartesianIndex(256, 256), Ising.wolff_padd(β))
fig = Figure(resolution=(700, 350))
ax = Axis(fig[1,1], title="spins")
hmap = heatmap!(ax, σ, colormap=cgrad([:purple, :orange], [0.5]; categorical=true))
hidedecorations!(ax)
ax = Axis(fig[1,2], title="cluster")
hmap = heatmap!(ax, cluster, colormap=cgrad([:white, :black], [0.5]; categorical=true))
hidedecorations!(ax)
figAverage size of Wolff's clusters as a function of temperature
import IsingModels as Ising
using Random, Statistics, Colors, ColorSchemes, CairoMakie
Random.seed!(1) # make reproducible
Ts = 0:0.2:5
βs = inv.(Ts)
fig = Figure(resolution=(600,400))
ax = Axis(fig[1,1], xlabel=L"temperature $T$", ylabel=L"average Wolff's cluster size / $N$")
clavg = zeros(length(βs))
clstd = zeros(length(βs))
σ = bitrand(32, 32)
for (k,β) in enumerate(βs)
σ_t, M, E = Ising.wolff!(σ, β, steps=10^3)
cluster_size = abs.(M[2:end] - M[1:(end - 1)]) .÷ 2
clavg[k] = mean(cluster_size / length(σ))
clstd[k] = std(cluster_size / length(σ))
end
scatter!(ax, Ts, clavg, color=:blue, markersize=5, label="L=30")
lines!(ax, Ts, clavg, color=:blue)
errorbars!(ax, Ts, clavg, clstd/2, color=:blue, whiskerwidth=5)
clavg = zeros(length(βs))
clstd = zeros(length(βs))
σ = bitrand(64, 64)
for (k,β) in enumerate(βs)
σ_t, M, E = Ising.wolff!(σ, β, steps=10^3)
cluster_size = abs.(M[2:end] - M[1:(end - 1)]) .÷ 2
clavg[k] = mean(cluster_size / length(σ))
clstd[k] = std(cluster_size / length(σ))
end
scatter!(ax, Ts, clavg, color=:red, markersize=5, label="L=70")
lines!(ax, Ts, clavg, color=:red)
errorbars!(ax, Ts, clavg, clstd/2, color=:red, whiskerwidth=5)
vlines!(ax, [1 / Ising.βc], label=L"Onsager's $T_c$", color=:black, linestyle=:dash)
axislegend(ax, position=:rt)
figWolff explores configurations efficiently at the critical temperature
The following example shows how at the critical temperature, the Metropolis sampler gets stuck in particular cluster structures. In contrast the Wolff algorihm explores diverse states.
using Statistics, CairoMakie, Random
import IsingModels as Ising
Random.seed!(3) # reproducibility
L = 128
N = L^2
σ_t_metro, M_metro, E_metro = Ising.metropolis!(falses(L, L), Ising.βc; steps=10^6, save_interval=2*10^5)
σ_t_wolff, M_wolff, E_wolff = Ising.wolff!(falses(L, L), Ising.βc, steps=10^4, save_interval=2*10^3)
fig = Figure(resolution=(1000, 800))
for t in 1:size(σ_t_metro, 3)
ax = Axis(fig[1,1][1,t], title="t=$t, metropolis")
heatmap!(ax, σ_t_metro[:,:,t], colorrange=(0,1), colormap=cgrad([:purple, :orange], [0.5]; categorical=true))
hidedecorations!(ax)
end
for t in 1:size(σ_t_wolff, 3)
ax = Axis(fig[1,1][2,t], title="t=$t, wolff")
heatmap!(ax, σ_t_wolff[:,:,t], colorrange=(0,1), colormap=cgrad([:purple, :orange], [0.5]; categorical=true))
hidedecorations!(ax)
end
ax = Axis(fig[2,1][1,1], title="magnetization")
lines!(ax, M_wolff[1:10:end] / N, label="wolff")
lines!(ax, M_metro[1:1000:end] / N, label="metropolis", linewidth=2, color=:red)
ylims!(ax, (-1,1))
ax = Axis(fig[2,1][1,2], title="energy")
lines!(ax, E_wolff[1:10:end] / N, label="wolff")
lines!(ax, E_metro[1:1000:end] / N, label="metropolis", linewidth=2, color=:red)
axislegend(ax, position = :rb)
figBinder's parameter
As the system size grows, the crossing point of the different curves is the critical temperature.
using Statistics, CairoMakie, Random
import IsingModels as Ising
Random.seed!(1) # make reproducible
Ts = 2.2:0.01:2.3
βs = inv.(Ts)
fig = Figure(resolution=(600, 400))
ax = Axis(fig[1,1], xlabel=L"temperature $T$ ($=1/\beta$)", ylabel="Binder parameter")
@time for (L, color) in zip([4, 8, 16, 32], [:green, :orange, :blue, :red])
U = zeros(length(βs))
σ = bitrand(L, L)
for (k, β) in enumerate(βs)
σ_t, M, E = Ising.wolff!(σ, β, steps=10^5)
U[k] = (3 - mean(M.^4) / mean(M.^2)^2) / 2
end
scatter!(ax, Ts, U, color=color, markersize=5, label=L"L=%$L")
lines!(ax, Ts, U, color=color, markersize=5)
end
vlines!(ax, [1 / Ising.βc], label=L"Onsager's $T_c$", color=:black, linestyle=:dash)
axislegend(ax, position=:lb)
figHeat capacity vs. exact expression
using Statistics, CairoMakie, Random
import IsingModels as Ising
Random.seed!(1) # make reproducible
Ts = 1.8:0.01:3
βs = inv.(Ts)
fig = Figure(resolution=(800, 400))
ax = Axis(fig[1,1], xlabel=L"temperature $T$ ($=1/\beta$)", ylabel="heat capacity", limits=(extrema(Ts)..., 0,2))
@time for (L, color) in zip([4, 8, 16, 32], [:green, :orange, :blue, :red])
C = zeros(length(βs))
for (k, β) in enumerate(βs)
σ = bitrand(L, L)
σ_t, M, E = Ising.wolff!(σ, β, steps=10^5)
C[k] = β^2/length(σ) * var(E)
end
scatter!(ax, Ts, C, color=color, markersize=5, label=L"L=%$L")
end
lines!(ax, Ts, Ising.onsager_heat_capacity.(βs), color=:black, label="exact")
vlines!(ax, [1 / Ising.βc], label=L"Onsager's $T_c$", color=:black, linestyle=:dash)
Legend(fig[1,2], ax)
figInternal energy vs. exact expression
using Statistics, CairoMakie, Random
import IsingModels as Ising
Random.seed!(1) # make reproducible
Ts = 1.8:0.05:3
βs = inv.(Ts)
fig = Figure(resolution=(800, 400))
ax = Axis(fig[1,1], xlabel=L"temperature $T$ ($=1/\beta$)", ylabel="internal energy")
@time for (L, color) in zip([4, 8, 16, 32], [:green, :orange, :blue, :red])
Eavg = zeros(length(βs))
Estd = zeros(length(βs))
for (k, β) in enumerate(βs)
σ = bitrand(L, L)
σ_t, M, E = Ising.wolff!(σ, β, steps=10^5)
Eavg[k] = mean(E / length(σ))
Estd[k] = std(E / length(σ))
end
scatter!(ax, Ts, Eavg, color=color, markersize=5, label=L"L=%$L")
errorbars!(ax, Ts, Eavg, Estd/2, color=color, whiskerwidth=5)
end
lines!(ax, Ts, Ising.onsager_internal_energy.(βs), color=:black, label="exact")
vlines!(ax, [1 / Ising.βc], label=L"Onsager's $T_c$", color=:black, linestyle=:dash)
Legend(fig[1,2], ax)
figThis page was generated using Literate.jl.