Skip to content

Commit

Permalink
Merge pull request #10 from ZIB-IOL/v0.1.2
Browse files Browse the repository at this point in the history
V0.1.2
  • Loading branch information
matbesancon authored Mar 12, 2024
2 parents dd6125a + a8340b5 commit 7a694ca
Show file tree
Hide file tree
Showing 12 changed files with 178 additions and 305 deletions.
2 changes: 1 addition & 1 deletion .JuliaFormatter.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
margin = 100
margin = 128
import_to_using = false
whitespace_in_kwargs = false
annotate_untyped_fields_with_any = true
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "BellPolytopes"
uuid = "38bdb6f4-c11c-4b2a-9c62-3601ea4ec58a"
authors = ["ZIB AISST"]
version = "0.1.1"
version = "0.1.2"

[deps]
Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa"
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://zib-iol.github.io/BellPolytopes.jl/dev/)
[![Build Status](https://github.com/zib-iol/BellPolytopes.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/zib-iol/BellPolytopes.jl/actions/workflows/CI.yml?query=branch%3Amain)
[![Genie Downloads](https://shields.io/endpoint?url=https://pkgs.genieframework.com/api/v1/badge/BellPolytopes)](https://pkgs.genieframework.com?packages=BellPolytopes)

This package addresses the membership problem for local polytopes: it constructs Bell inequalities and local models in multipartite Bell scenarios with binary outcomes.

Expand Down
5 changes: 1 addition & 4 deletions examples/CHSH.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@ println("Lower bound")
println(lower_bound) # 0.7071
println("Local model")
display(local_model.x)
println(
local_model.x ==
sum(local_model.weights[i] * local_model.atoms[i] for i in 1:length(local_model)),
) # true
println(local_model.x == sum(local_model.weights[i] * local_model.atoms[i] for i in 1:length(local_model))) # true

println()

Expand Down
9 changes: 3 additions & 6 deletions examples/GHZ.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,15 @@ println(lower_bound_infinite) # 0.46515...
println()

println("Lower bound")
println(lower_bound) # 0.4931
println(lower_bound) # 0.49315
println("Local model")
display(local_model.x[:, :, 1])
println(
local_model.x ==
sum(local_model.weights[i] * local_model.atoms[i] for i in 1:length(local_model)),
) # true
println(local_model.x == sum(local_model.weights[i] * local_model.atoms[i] for i in 1:length(local_model))) # true

println()

println("Upper bound")
println(upper_bound) # 0.49317...
println(upper_bound) # 0.4932
println("Bell inequality")
display(bell_inequality[:, :, 1])

Expand Down
15 changes: 5 additions & 10 deletions examples/Werner.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,10 @@ N = 2 # bipartite scenario
measurements_vec = polyhedronisme("../polyhedra/polyhedronisme-SASuSAuO.obj", 33)
rho = rho_singlet() # shared state
p = correlation_tensor(measurements_vec, N; rho=rho, marg=false)
x, ds, primal, dual_gap, traj_data, as, M, β = bell_frank_wolfe(
p;
v0=1 / sqrt(2),
verbose=3,
epsilon=1e-4,
lazy_tolerance=0.5,
mode_last=0,
nb_last=10^6,
)
# v_c ≤ 0.704826 (heuristic local bound)
x, ds, primal, dual_gap, traj_data, as, M, β =
bell_frank_wolfe(p; v0=1 / sqrt(2), verbose=3, epsilon=1e-4, mode_last=0, nb_last=10^6)
# v_c ≤ 0.704914
# As such, the function above gets this last bound heuristically
# Change mode_last to 1 to check the exact bound (takes a few minutes)

println()
27 changes: 9 additions & 18 deletions src/BellPolytopes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ using Tullio

export bell_frank_wolfe, local_bound, nonlocality_threshold
include("quantum_utils.jl")
export ketbra, qubit_mes, polygonXY_vec, HQVNB17_vec, rho_singlet, rho_GHZ, rho_W
export ketbra, qubit_mes, povm, polygonXY_vec, HQVNB17_vec, rho_singlet, rho_GHZ, rho_W
export cube_vec, octahedron_vec, icosahedron_vec, dodecahedron_vec
include("types.jl")
export correlation_matrix, correlation_tensor
export correlation_matrix, correlation_tensor, probability_tensor
include("fw_methods.jl")
include("utils.jl")
export polyhedronisme, shrinking_squared
Expand Down Expand Up @@ -56,7 +56,7 @@ Optional arguments:
"""
function bell_frank_wolfe(
p::Array{T, N};
marg::Bool=N == 2 ? false : true,
marg::Bool=N != 2,
v0=one(T),
epsilon=1e-7,
verbose=0,
Expand Down Expand Up @@ -90,7 +90,7 @@ function bell_frank_wolfe(
println("\nVisibility: ", v0)
end
# symmetry detection
if p reynolds_permutedims(p)
if p reynolds_permutedims(p, BellCorrelationsLMO(p))
reynolds = reynolds_permutedims
if sym === nothing # respect the user choice if sym is false
sym = true
Expand Down Expand Up @@ -154,14 +154,7 @@ function bell_frank_wolfe(
active_set = FrankWolfe.ActiveSet(x0)
else
if active_set isa ActiveSetStorage
active_set = load_active_set(
active_set;
type=TD,
sym=sym,
marg=marg,
use_array=use_array,
reynolds=reynolds,
)
active_set = load_active_set(active_set, TD; sym=sym, marg=marg, use_array=use_array, reynolds=reynolds)
end
active_set_link_lmo!(active_set, lmo)
active_set_reinitialise!(active_set)
Expand Down Expand Up @@ -243,8 +236,8 @@ function bell_frank_wolfe(
if verbose 2 && mode_last 0
@printf(" Dual gap: %.2e\n", dual_gap)
@printf(" Time: %.2e\n", time / 1e9)
println()
end
println()
if primal > dual_gap
@printf("v_c ≤ %f\n", β)
else
Expand All @@ -264,15 +257,13 @@ No symmetry detection is implemented yet, used mostly for pedagogy and tests.
"""
function local_bound(
M::Array{T, N};
marg::Bool=false,
mode::Int=1,
sym::Bool=false,
nb::Int=10^5,
verbose=false,
) where {T <: Number} where {N}
ds = FrankWolfe.compute_extreme_point(
BellCorrelationsLMO(M; mode=mode, nb=nb),
-M;
verbose=verbose,
)
ds = FrankWolfe.compute_extreme_point(BellCorrelationsLMO(M; marg=marg, mode=mode, sym=sym, nb=nb), -M; verbose=verbose)
return FrankWolfe.fast_dot(M, ds), ds
end

Expand Down
37 changes: 25 additions & 12 deletions src/fw_methods.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,13 @@ function FrankWolfe.compute_extreme_point(
lmo::BellCorrelationsLMO{T, 2, 1, IsSymmetric, HasMarginals},
A::Array{T, 2};
verbose=false,
last=false,
initialise=true,
kwargs...,
) where {T <: Number} where {IsSymmetric} where {HasMarginals}
if IsSymmetric && last
A .= lmo.reynolds(A, lmo)
end
ax = [ones(T, lmo.m) for n in 1:2]
sc = zero(T)
axm = [zeros(T, lmo.m) for n in 1:2]
Expand Down Expand Up @@ -78,9 +82,13 @@ function FrankWolfe.compute_extreme_point(
lmo::BellCorrelationsLMO{T, 3, 1, IsSymmetric, HasMarginals},
A::Array{T, 3};
verbose=false,
last=false,
initialise=true,
kwargs...,
) where {T <: Number} where {IsSymmetric} where {HasMarginals}
if IsSymmetric && last
A .= lmo.reynolds(A, lmo)
end
ax = [ones(T, lmo.m) for n in 1:3]
sc = zero(T)
axm = [zeros(T, lmo.m) for n in 1:3]
Expand Down Expand Up @@ -123,9 +131,13 @@ function FrankWolfe.compute_extreme_point(
lmo::BellCorrelationsLMO{T, 4, 1, IsSymmetric, HasMarginals},
A::Array{T, 4};
verbose=false,
last=false,
initialise=true,
kwargs...,
) where {T <: Number} where {IsSymmetric} where {HasMarginals}
if IsSymmetric && last
A .= lmo.reynolds(A, lmo)
end
ax = [ones(T, lmo.m) for n in 1:4]
sc = zero(T)
axm = [zeros(T, lmo.m) for n in 1:4]
Expand Down Expand Up @@ -172,9 +184,13 @@ function FrankWolfe.compute_extreme_point(
lmo::BellCorrelationsLMO{T, 5, 1, IsSymmetric, HasMarginals},
A::Array{T, 5};
verbose=false,
last=false,
initialise=true,
kwargs...,
) where {T <: Number} where {IsSymmetric} where {HasMarginals}
if IsSymmetric && last
A .= lmo.reynolds(A, lmo)
end
ax = [ones(T, lmo.m) for n in 1:5]
sc = zero(T)
axm = [zeros(T, lmo.m) for n in 1:5]
Expand Down Expand Up @@ -225,9 +241,13 @@ function FrankWolfe.compute_extreme_point(
lmo::BellCorrelationsLMO{T, 6, 1, IsSymmetric, HasMarginals},
A::Array{T, 6};
verbose=false,
last=false,
initialise=true,
kwargs...,
) where {T <: Number} where {IsSymmetric} where {HasMarginals}
if IsSymmetric && last
A .= lmo.reynolds(A, lmo)
end
ax = [ones(T, lmo.m) for n in 1:6]
sc = zero(T)
axm = [zeros(T, lmo.m) for n in 1:6]
Expand Down Expand Up @@ -289,10 +309,11 @@ function FrankWolfe.compute_extreme_point(
) where {T <: Number} where {N} where {IsSymmetric} where {HasMarginals}
@warn("This function is naive and should not be used for actual computations.")
if IsSymmetric && last
A .= lmo.reynolds(A; lmo=lmo)
A .= lmo.reynolds(A, lmo)
end
# the approach with the λa here is very naive and only allows pedagogical support for very small cases
ds = BellCorrelationsDS([ones(T, lmo.m) for n in 1:N], lmo; initialise=false)
sc = zero(T)
axm = [zeros(T, lmo.m) for n in 1:N]
scm = typemax(T)
m = HasMarginals ? lmo.m - 1 : lmo.m
Expand Down Expand Up @@ -526,11 +547,9 @@ function FrankWolfe.muladd_memory_mode(
) where {AT <: BellCorrelationsDS{T, N}} where {T <: Number} where {N}
d[1] = Inf
if a.hash > v.hash
@inbounds d[2] =
((a.gap - a.dotp) - (v.gap - v.dotp)) / (a.dot[a.hash] + v.dot[v.hash] - 2a.dot[v.hash])
@inbounds d[2] = ((a.gap - a.dotp) - (v.gap - v.dotp)) / (a.dot[a.hash] + v.dot[v.hash] - 2a.dot[v.hash])
else
@inbounds d[2] =
((a.gap - a.dotp) - (v.gap - v.dotp)) / (a.dot[a.hash] + v.dot[v.hash] - 2v.dot[a.hash])
@inbounds d[2] = ((a.gap - a.dotp) - (v.gap - v.dotp)) / (a.dot[a.hash] + v.dot[v.hash] - 2v.dot[a.hash])
end
return d
end
Expand Down Expand Up @@ -563,12 +582,6 @@ function FrankWolfe.perform_line_search(
return min(max(d[2], 0), gamma_max)
else
# return min(max((FrankWolfe.fast_dot(gradient, x) - (d[1] - d[2])) * inv(FrankWolfe.fast_dot(x, x) + d[3]), 0), gamma_max)
return min(
max(
FrankWolfe.fast_dot(gradient, d) * inv(line_search.L * FrankWolfe.fast_dot(d, d)),
0,
),
gamma_max,
)
return min(max(FrankWolfe.fast_dot(gradient, d) * inv(line_search.L * FrankWolfe.fast_dot(d, d)), 0), gamma_max)
end
end
Loading

2 comments on commit 7a694ca

@matbesancon
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator register()

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/102732

Tip: Release Notes

Did you know you can add release notes too? Just add markdown formatted text underneath the comment after the text
"Release notes:" and it will be added to the registry PR, and if TagBot is installed it will also be added to the
release that TagBot creates. i.e.

@JuliaRegistrator register

Release notes:

## Breaking changes

- blah

To add them here just re-invoke and the PR will be updated.

Tagging

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.1.2 -m "<description of version>" 7a694cacd7fd9808942f1fddea40ea8c9457c072
git push origin v0.1.2

Please sign in to comment.