Skip to content

ZIB-IOL/AbsSmoothFrankWolfe.jl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AbsSmoothFrankWolfe.jl

CI DOI

This package is a toolbox for Abs-Smooth Frank-Wolfe algorithm.

Overview

Abs-Smooth Frank-Wolfe algorithms are designed to solve optimization problems of the form $\min\limits_{x\in C}$ $f(x)$ , for convex compact $C$ and an abs-smooth function $f$.

Installation

The most recent release is available via the julia package manager, e.g., with

using Pkg
Pkg.add("AbsSmoothFrankWolfe")

or the main branch:

Pkg.add(url="https://github.com/ZIB-IOL/AbsSmoothFrankWolfe.jl")

Getting started

Let's say we want to minimize the LASSO problem: $\frac{1}{2}|Ax - y|_2^2 + \rho |x|_1$, subjected to simple box constraints. This is what the code looks like:

julia> using AbsSmoothFrankWolfe,FrankWolfe,LinearAlgebra,JuMP,HiGHS

julia> import MathOptInterface

julia> const MOI = MathOptInterface

julia> n = 5 # choose lenght(x)

julia> p = 3 # choose lenght(y)

julia> rho = 0.5

julia> A = rand(p,n) # randomly choose matrix A

julia> y = rand(p) # randomly choose y

#define the LASSO function
julia>  function f(x)
	
 	return 0.5*(norm(A*x - y))^2 + rho*norm(x)

 end

# evaluation point x_base
julia> x_base = ones(n)*1.0

# box constraints
julia> lb_x = [-5 for in in x_base]

julia> ub_x = [5 for in in x_base]

# call the abs-linear form of f
julia> abs_normal_form = AbsSmoothFrankWolfe.abs_linear(x_base,f)

# gradient formula in terms of abs-linearization
julia> alf_a = abs_normal_form.Y

julia> alf_b = abs_normal_form.J 

julia> z = abs_normal_form.z 

julia> s = abs_normal_form.num_switches

julia> sigma_z = AbsSmoothFrankWolfe.signature_vec(s,z)

julia> function grad!(storage, x)
    c = vcat(alf_a', alf_b'.* sigma_z)
    @. storage = c
end

# define the model using JuMP with HiGHS as inner solver
julia> o = Model(HiGHS.Optimizer)

julia> MOI.set(o, MOI.Silent(), true)

julia> @variable(o, lb_x[i] <= x[i=1:n] <= ub_x[i])

# initialise dual gap
julia> dualgap_asfw = Inf

# abs-smooth lmo
julia> lmo_as = AbsSmoothFrankWolfe.AbsSmoothLMO(o, x_base, f, n, s, lb_x, ub_x, dualgap_asfw)

# define termination criteria using Frank-Wolfe 'callback' function
julia> function make_termination_callback(state)
 return function callback(state,args...)
  return state.lmo.dualgap_asfw[1] > 1e-2
 end
end

julia> callback = make_termination_callback(FrankWolfe.CallbackState)

# call abs-smooth-frank-wolfe
julia> x, v, primal, dual_gap, traj_data = AbsSmoothFrankWolfe.as_frank_wolfe(
    f, 
    grad!, 
    lmo_as, 
    x_base;
    gradient = ones(n+s),
    line_search = FrankWolfe.FixedStep(1.0),
    callback=callback,
    verbose=true
)

Beyond those presented in the documentation, more test problems can be found in the examples folder.