Skip to content

Commit

Permalink
finished implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
matbesancon committed Sep 5, 2023
1 parent 192286b commit 71910a4
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 8 deletions.
14 changes: 8 additions & 6 deletions src/afw.jl
Original file line number Diff line number Diff line change
Expand Up @@ -423,16 +423,17 @@ function lazy_afw_step(x, gradient, lmo, active_set, phi, epsilon, d; use_extra_
# compute new vertex with normal or weak oracle
if weak_separation
lazy_threshold = fast_dot(gradient, x) - phi / lazy_tolerance
(v, _) = compute_weak_separation_point(lmo, gradient, lazy_threshold)
tt = weaksep
(v, gap) = compute_weak_separation_point(lmo, gradient, lazy_threshold)
tt = gap == 0.0 ? regular : weaksep
else
v = compute_extreme_point(lmo, gradient)
gap = zero(eltype(v))
tt = regular
end
end
# Real dual gap promises enough progress.
grad_dot_fw_vertex = fast_dot(v, gradient)
dual_gap = grad_dot_x - grad_dot_fw_vertex
# Real dual gap promises enough progress.
if dual_gap >= phi / lazy_tolerance
gamma_max = one(a_lambda)
d = muladd_memory_mode(memory_mode, d, x, v)
Expand All @@ -441,6 +442,7 @@ function lazy_afw_step(x, gradient, lmo, active_set, phi, epsilon, d; use_extra_
fw_step_taken = true
index = -1
else # lower our expectation for progress.
@assert tt != weaksep
tt = dualstep
phi = min(dual_gap, phi / 2.0)
gamma_max = zero(a_lambda)
Expand All @@ -460,15 +462,15 @@ function afw_step(x, gradient, lmo, active_set, epsilon, d; memory_mode::MemoryE
away_gap = fast_dot(a, gradient) - grad_dot_x
(v, gap) = if weak_separation
# Condition for taking a FW step
# ⟨∇f, x-v⟩ ≥ gₐ
# ⟨∇f, x-v⟩ ≥ gₐ <=>
# ⟨∇f, v⟩ ≤ ⟨∇f, x⟩ - gₐ
# We ask for a bit more on the FW step
# We ask for a bit more progress on the FW step
# to promote away steps when we can (and therefore sparsity)
# ⟨∇f, v⟩ ≤ ⟨∇f, x⟩ - K gₐ
lazy_threshold = grad_dot_x - lazy_tolerance * away_gap
compute_weak_separation_point(lmo, gradient, lazy_threshold)
else
(compute_extreme_point(lmo, gradient), 0.0)
(compute_extreme_point(lmo, gradient), zero(away_gap))
end
dual_gap = grad_dot_x - fast_dot(v, gradient)
if dual_gap > away_gap && dual_gap >= epsilon
Expand Down
2 changes: 1 addition & 1 deletion src/pairwise.jl
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ function blended_pairwise_conditional_gradient(
else # dual step
# set to computed dual_gap for consistency between the lazy and non-lazy run.
# that is ok as we scale with the K = 2.0 default anyways
# we only update the dual gap if the step was regular (not lazy from discarded set)
# we only update the dual gap if the step was regular or weaksep (not lazy from discarded set)
if tt != lazylazy
@assert dual_gap + gap < phi
phi = dual_gap + gap
Expand Down
9 changes: 8 additions & 1 deletion test/weak_separation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ end
@test w == v
end

@testset "AFW with weak separation" begin
@testset "AFW and BPCG with weak separation" begin
n = 1000
# reference point to get an optimum on a face
ref_point = [0.6 + mod(idx, 2) for idx in 1:n]
Expand All @@ -88,5 +88,12 @@ end
tracking_weak = FrankWolfe.TrackingLMO(Hypercube())
x, v, primal, dual_gap, trajectory_weak, active_set_weak = FrankWolfe.away_frank_wolfe(f, grad!, tracking_weak, x0, verbose=false, weak_separation=true, lazy=lazy)
@test tracking_lmo.counter <= tracking_weak.counter

tracking_lmo = FrankWolfe.TrackingLMO(Hypercube())
x, v, primal, dual_gap, trajectory_exact, active_set_exact = FrankWolfe.blended_pairwise_conditional_gradient(f, grad!, tracking_lmo, x0, verbose=false, weak_separation=false, lazy=lazy)
tracking_weak = FrankWolfe.TrackingLMO(Hypercube())
x, v, primal, dual_gap, trajectory_weak, active_set_weak = FrankWolfe.blended_pairwise_conditional_gradient(f, grad!, tracking_weak, x0, verbose=false, weak_separation=true, lazy=lazy)
@test tracking_lmo.counter <= tracking_weak.counter

end
end

0 comments on commit 71910a4

Please sign in to comment.