3KX1xU2bCC / artifacts /source /author-utils.jl
DineshAI's picture
Add five-claim Frank-Wolfe executed evidence
f8ded0c verified
Raw
History Blame Contribute Delete
3.51 kB
using Plots
using LinearAlgebra
using FrankWolfe
# ==============================================================================
# FRANK-WOLFE VERIFICATION
# ==============================================================================
"""
run_frank_wolfe_experiment(r_start, s_start, p_opt, iterations)
Run Frank-Wolfe algorithm starting from a reconstructed initial point.
Given the theoretical (r, s) coordinates, reconstruct the actual starting point x0
and verify the convergence behavior matches the theoretical predictions.
Returns: (path, gaps, x0) where path is the trajectory and gaps are the objective values.
"""
function run_frank_wolfe_experiment(r_start, s_start, p_opt, iterations)
println("-"^60)
println("FORWARD SIMULATION: Verifying with Frank-Wolfe")
# 1. Reconstruction x0 from (r, s) coordinates
theta0 = -s_start^2 * (r_start + 1) - sqrt((1 - s_start^2 * (r_start + 1)^2) * (1 - s_start^2))
q = [1.0, 0.0] # orthogonal to p_opt
c0 = theta0 * p_opt + sqrt(1 - theta0^2) * q
x0 = p_opt + r_start * c0
println(" Starting point x0: $(Float64.(x0))")
println(" Distance to optimum: $(Float64(norm(x0 - p_opt)))")
# 2. Setup problem: min ||x - p_opt||^2 over unit ball
f(x) = norm(x - p_opt)^2
function grad!(storage, x)
storage .= 2 * (x - p_opt)
end
lmo = FrankWolfe.LpNormBallLMO{2}(1.0)
path = [x0]
gaps = Float64[f(x0)]
function path_callback(state, args...)
push!(path, copy(state.x))
push!(gaps, f(state.x))
end
# 3. Run Frank-Wolfe
println(" Running $iterations iterations...")
FrankWolfe.frank_wolfe(f, grad!, lmo, x0;
callback=path_callback,
max_iteration=iterations,
verbose=true,
print_iter=100
)
println(" Final gap: $(gaps[end])")
println("-"^60)
return path, gaps, x0
end
# ==============================================================================
# PLOTTING UTILITIES
# ==============================================================================
"""
plot_trajectory_2d(path, p_opt; title="Trajectory of the worst-case instance")
Plot the Frank-Wolfe trajectory on the unit ball in 2D.
"""
function plot_trajectory_2d(path, p_opt; title="Trajectory of the worst-case instance")
# Unit circle
theta = range(0, 2pi, length=200)
circle_x = cos.(theta)
circle_y = sin.(theta)
xs = [Float64(pt[1]) for pt in path]
ys = [Float64(pt[2]) for pt in path]
plt = plot(circle_x, circle_y,
aspect_ratio=:equal,
label="Unit Ball",
linecolor=:black,
size=(600, 600),
title=title,
ticks=false,
axis=false,
)
plot!(xs, ys, label="Trajectory", color=:blue, marker=:circle, markersize=3)
scatter!([p_opt[1]], [p_opt[2]], label="Optimum p", color=:red, markersize=6)
return plt
end
"""
plot_convergence(gaps; title="Convergence Rate")
Plot the convergence of the Frank-Wolfe algorithm with O(1/t^2) reference.
"""
function plot_convergence(gaps; title="Convergence Rate")
t_range = 1:length(gaps)
plt = plot(t_range, gaps,
yaxis=:log, xaxis=:log,
label="f(x_t)",
title=title,
xlabel="Iteration t",
ylabel="Gap",
linewidth=2
)
# O(1/t^2) reference line
ref = [gaps[1] * t^-2 for t in t_range]
plot!(t_range, ref, linestyle=:dash, color=:red, label="O(1/t²) Reference")
return plt
end