Skip to content

Commit f0a25b0

Browse files
authoredJun 30, 2023
Upgrade to ProximalAlgorithms v0.5 and AbstractOperators v0.3 (#40)
* drop support for ForwardBackward optimizer; * add support for PANOCplus; * stabilize unstable unit test; * bump upper version limit on DSP.
1 parent d3a2f64 commit f0a25b0

13 files changed

+136
-139
lines changed
 

‎Project.toml

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "StructuredOptimization"
22
uuid = "46cd3e9d-64ff-517d-a929-236bc1a1fc9d"
3-
version = "0.3.0"
3+
version = "0.4.0-ci+20230622"
44

55
[deps]
66
AbstractOperators = "d9c5613a-d543-52d8-9afd-8f241a8c3f1c"
@@ -12,11 +12,11 @@ ProximalOperators = "a725b495-10eb-56fe-b38b-717eba820537"
1212
RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd"
1313

1414
[compat]
15-
AbstractOperators = "0.1 - 0.2"
16-
DSP = "0.5.1 - 0.6"
15+
AbstractOperators = "0.3"
16+
DSP = "0.5.1 - 0.7"
1717
FFTW = "1"
18-
ProximalAlgorithms = "0.3 - 0.4"
19-
ProximalOperators = "0.8 - 0.14"
18+
ProximalAlgorithms = "0.5"
19+
ProximalOperators = "0.15"
2020
RecursiveArrayTools = "1 - 2"
2121
julia = "1.4"
2222

‎docs/src/solvers.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ You can pick the algorithm to use as `Solver` object from the
2323
package. Currently, the following algorithms are supported.
2424

2525
```@docs
26-
ForwardBackward
2726
ZeroFPR
2827
PANOC
28+
PANOCplus
2929
```
3030

3131

‎src/StructuredOptimization.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ using AbstractOperators
66
using ProximalOperators
77
using ProximalAlgorithms
88

9-
import ProximalAlgorithms:ForwardBackward, ZeroFPR, PANOC
10-
export ForwardBackward, ZeroFPR, PANOC
9+
import ProximalAlgorithms: ZeroFPR, PANOC, PANOCplus
10+
export ZeroFPR, PANOC, PANOCplus
1111

1212
include("syntax/syntax.jl")
1313
include("calculus/precomposeNonlinear.jl") # TODO move to ProximalOperators?

‎src/arraypartition.jl

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import ProximalOperators
22
import RecursiveArrayTools
33

44
@inline function ProximalOperators.prox(
5-
h::ProximalOperators.ProximableFunction,
5+
h,
66
x::RecursiveArrayTools.ArrayPartition,
77
gamma...
88
)
@@ -13,7 +13,7 @@ import RecursiveArrayTools
1313
end
1414

1515
@inline function ProximalOperators.gradient(
16-
h::ProximalOperators.ProximableFunction,
16+
h,
1717
x::RecursiveArrayTools.ArrayPartition
1818
)
1919
# unwrap
@@ -24,13 +24,13 @@ end
2424

2525
@inline ProximalOperators.prox!(
2626
y::RecursiveArrayTools.ArrayPartition,
27-
h::ProximalOperators.ProximableFunction,
27+
h,
2828
x::RecursiveArrayTools.ArrayPartition,
2929
gamma...
3030
) = ProximalOperators.prox!(y.x, h, x.x, gamma...)
3131

3232
@inline ProximalOperators.gradient!(
3333
y::RecursiveArrayTools.ArrayPartition,
34-
h::ProximalOperators.ProximableFunction,
34+
h,
3535
x::RecursiveArrayTools.ArrayPartition
3636
) = ProximalOperators.gradient!(y.x, h, x.x)

‎src/calculus/precomposeNonlinear.jl

+5-5
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@ import ProximalOperators: gradient!, gradient # this can be removed when moved t
22

33
export PrecomposeNonlinear
44

5-
struct PrecomposeNonlinear{P <: ProximableFunction,
5+
struct PrecomposeNonlinear{P,
66
T <: AbstractOperator,
7-
D <: AbstractArray,
7+
D <: AbstractArray,
88
C <: AbstractArray
9-
} <: ProximableFunction
10-
g::P
9+
}
10+
g::P
1111
G::T
1212
bufD::D
1313
bufC::C
1414
bufC2::C
1515
end
1616

17-
function PrecomposeNonlinear(g::P, G::T) where {P, T}
17+
function PrecomposeNonlinear(g::P, G::T) where {P, T}
1818
t, s = domainType(G), size(G,2)
1919
bufD = eltype(s) <: Int ? zeros(t,s) : ArrayPartition(zeros.(t,s))
2020
t, s = codomainType(G), size(G,1)

‎src/solvers/build_solve.jl

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ julia> A, b = randn(10,4), randn(10);
1818
1919
julia> p = problem( ls(A*x - b ) , norm(x) <= 1 );
2020
21-
julia> StructuredOptimization.parse_problem(p, ForwardBackward());
21+
julia> StructuredOptimization.parse_problem(p, PANOCplus());
2222
```
2323
"""
2424
function parse_problem(terms::Tuple, solver::T) where T <: ForwardBackwardSolver
@@ -65,14 +65,14 @@ julia> A, b = randn(10,4), randn(10);
6565
6666
julia> p = problem(ls(A*x - b ), norm(x) <= 1);
6767
68-
julia> solve(p, ForwardBackward());
68+
julia> solve(p, PANOCplus());
6969
7070
julia> ~x
7171
```
7272
"""
7373
function solve(terms::Tuple, solver::ForwardBackwardSolver)
7474
x, kwargs = parse_problem(terms, solver)
75-
x_star, it = solver(~x; kwargs...)
75+
x_star, it = solver(; x0 = ~x, kwargs...)
7676
~x .= x_star
7777
return x, it
7878
end

‎src/solvers/minimize.jl

+16-16
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ julia> @minimize ls(A*x-b) st x >= 0.;
2020
2121
julia> ~x # access array with solution
2222
23-
julia> @minimize ls(A*x-b) st norm(x) == 2.0 with ForwardBackward(fast=true);
23+
julia> @minimize ls(A*x-b) st norm(x) == 2.0 with PANOCplus();
2424
2525
julia> ~x # access array with solution
2626
```
@@ -29,28 +29,28 @@ Returns as output a tuple containing the optimization variables and the number
2929
of iterations spent by the solver algorithm.
3030
"""
3131
macro minimize(cf::Union{Expr, Symbol})
32-
cost = esc(cf)
32+
cost = esc(cf)
3333
return :(solve(problem($(cost)), default_solver()))
3434
end
3535

3636
macro minimize(cf::Union{Expr, Symbol}, s::Symbol, cstr::Union{Expr, Symbol})
37-
cost = esc(cf)
38-
if s == :(st)
39-
constraints = esc(cstr)
40-
return :(solve(problem($(cost), $(constraints)), default_solver()))
41-
elseif s == :(with)
42-
solver = esc(cstr)
37+
cost = esc(cf)
38+
if s == :(st)
39+
constraints = esc(cstr)
40+
return :(solve(problem($(cost), $(constraints)), default_solver()))
41+
elseif s == :(with)
42+
solver = esc(cstr)
4343
return :(solve(problem($(cost)), $(solver)))
44-
else
45-
error("wrong symbol after cost function! use `st` or `with`")
46-
end
44+
else
45+
error("wrong symbol after cost function! use `st` or `with`")
46+
end
4747
end
4848

4949
macro minimize(cf::Union{Expr, Symbol}, s::Symbol, cstr::Union{Expr, Symbol}, w::Symbol, slv::Union{Expr, Symbol})
50-
cost = esc(cf)
51-
s != :(st) && error("wrong symbol after cost function! use `st`")
52-
constraints = esc(cstr)
53-
w != :(with) && error("wrong symbol after constraints! use `with`")
54-
solver = esc(slv)
50+
cost = esc(cf)
51+
s != :(st) && error("wrong symbol after cost function! use `st`")
52+
constraints = esc(cstr)
53+
w != :(with) && error("wrong symbol after constraints! use `with`")
54+
solver = esc(slv)
5555
return :(solve(problem($(cost), $(constraints)), $(solver)))
5656
end

‎src/solvers/solvers_options.jl

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
using ProximalAlgorithms
22

3-
const ForwardBackwardSolver = Union{
4-
ProximalAlgorithms.ForwardBackward,
5-
ProximalAlgorithms.ZeroFPR,
6-
ProximalAlgorithms.PANOC,
7-
}
3+
const ForwardBackwardSolver = ProximalAlgorithms.IterativeAlgorithm
84

95
const default_solver = ProximalAlgorithms.PANOC

‎src/syntax/terms/proximalOperators_bind.jl

+49-49
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import LinearAlgebra: norm
44
export norm
55

66
"""
7-
norm(x::AbstractExpression, p=2, [q,] [dim=1])
7+
norm(x::AbstractExpression, p=2, [q,] [dim=1])
88
99
Returns the norm of `x`.
1010
@@ -28,41 +28,41 @@ where ``\\mathbf{x}_i`` is the ``i``-th column if `dim == 1` (or row if `dim ==
2828
2929
"""
3030
function norm(ex::AbstractExpression, p::Real=2)
31-
if p == 0
32-
f = NormL0()
33-
elseif p == 1
34-
f = NormL1()
35-
elseif p == 2
36-
f = NormL2()
37-
elseif p == Inf
38-
f = NormLinf()
39-
else
40-
error("function not implemented")
41-
end
42-
return Term(f, ex)
31+
if p == 0
32+
f = NormL0()
33+
elseif p == 1
34+
f = NormL1()
35+
elseif p == 2
36+
f = NormL2()
37+
elseif p == Inf
38+
f = NormLinf()
39+
else
40+
error("function not implemented")
41+
end
42+
return Term(f, ex)
4343
end
4444

4545
# Nuclear norm
4646
function norm(ex::AbstractExpression, ::typeof(*))
47-
return Term(NuclearNorm(), ex)
47+
return Term(NuclearNorm(), ex)
4848
end
4949

5050
# Mixed Norm
5151
function norm(ex::AbstractExpression, p1::Int, p2::Int, dim::Int = 1 )
52-
if p1 == 2 && p2 == 1
53-
f = NormL21(1.0,dim)
54-
else
55-
error("function not implemented")
56-
end
57-
return Term(f, ex)
52+
if p1 == 2 && p2 == 1
53+
f = NormL21(1.0,dim)
54+
else
55+
error("function not implemented")
56+
end
57+
return Term(f, ex)
5858
end
5959

6060
# Least square terms
6161

6262
export ls
6363

6464
"""
65-
ls(x::AbstractExpression)
65+
ls(x::AbstractExpression)
6666
6767
Returns the squared norm (least squares) of `x`:
6868
@@ -77,20 +77,20 @@ ls(ex) = Term(SqrNormL2(), ex)
7777
import Base: ^
7878

7979
function (^)(t::Term{T1,T2,T3}, exp::Integer) where {T1, T2 <: NormL2, T3}
80-
if exp == 2
81-
# The coefficient 2.0 is due to the fact that SqrNormL2 divides by 2.0
82-
return t.lambda^2*Term(SqrNormL2(2.0), t.A)
83-
else
84-
error("function not implemented")
85-
end
80+
if exp == 2
81+
# The coefficient 2.0 is due to the fact that SqrNormL2 divides by 2.0
82+
return t.lambda^2*Term(SqrNormL2(2.0), t.A)
83+
else
84+
error("function not implemented")
85+
end
8686
end
8787

8888
# HingeLoss
8989

9090
export hingeloss
9191

9292
"""
93-
hingeloss(x::AbstractExpression, y::Array)
93+
hingeloss(x::AbstractExpression, y::Array)
9494
9595
Applies the Hinge loss function
9696
```math
@@ -106,7 +106,7 @@ Term(HingeLoss(b), ex)
106106
export sqrhingeloss
107107

108108
"""
109-
sqrhingeloss(x::AbstractExpression, y::Array)
109+
sqrhingeloss(x::AbstractExpression, y::Array)
110110
111111
Applies the squared Hinge loss function
112112
```math
@@ -122,7 +122,7 @@ Term(SqrHingeLoss(b), ex)
122122
export crossentropy
123123

124124
"""
125-
crossentropy(x::AbstractExpression, y::Array)
125+
crossentropy(x::AbstractExpression, y::Array)
126126
127127
Applies the cross entropy loss function:
128128
```math
@@ -138,7 +138,7 @@ Term(CrossEntropy(b), ex)
138138
export logisticloss
139139

140140
"""
141-
logbarrier(x::AbstractExpression, y::AbstractArray)
141+
logbarrier(x::AbstractExpression, y::AbstractArray)
142142
143143
Applies the logistic loss function:
144144
```math
@@ -154,7 +154,7 @@ Term(LogisticLoss(y, 1.0), ex)
154154
export logbarrier
155155

156156
"""
157-
logbarrier(x::AbstractExpression)
157+
logbarrier(x::AbstractExpression)
158158
159159
Applies the log barrier function:
160160
```math
@@ -169,7 +169,7 @@ Term(LogBarrier(1.0), ex)
169169
export huberloss
170170

171171
"""
172-
huberloss(x::AbstractExpression, ρ=1.0)
172+
huberloss(x::AbstractExpression, ρ=1.0)
173173
174174
Applies the Huber loss function:
175175
```math
@@ -185,7 +185,7 @@ Term(HuberLoss(rho), ex)
185185
import Base: maximum
186186

187187
"""
188-
maximum(x::AbstractExpression)
188+
maximum(x::AbstractExpression)
189189
190190
Applies the function:
191191
```math
@@ -198,7 +198,7 @@ Term(Maximum(), ex)
198198
export sumpositive
199199

200200
"""
201-
sumpositive(x::AbstractExpression, ρ=1.0)
201+
sumpositive(x::AbstractExpression, ρ=1.0)
202202
203203
Applies the function:
204204
```math
@@ -212,7 +212,7 @@ import LinearAlgebra: dot
212212
export dot
213213

214214
"""
215-
dot(c::AbstractVector, x::AbstractExpression)
215+
dot(c::AbstractVector, x::AbstractExpression)
216216
217217
Applies the function:
218218
```math
@@ -284,10 +284,10 @@ import Base: <=, >=, in
284284
(>=)(ub, ex::AbstractExpression) = Term(IndBox(-Inf, ub), ex)
285285

286286
function in(ex::AbstractExpression, bnds::AbstractArray)
287-
if length(bnds) != 2
288-
error("should provide 2 bounds!")
289-
end
290-
return Term(IndBox(bnds[1], bnds[2]), ex)
287+
if length(bnds) != 2
288+
error("should provide 2 bounds!")
289+
end
290+
return Term(IndBox(bnds[1], bnds[2]), ex)
291291
end
292292

293293
# Rank constraints
@@ -299,9 +299,9 @@ export rank
299299
# rank(X) <= r,
300300
# therefore here the parameter (1) doesn't really have a role.
301301
# We should probably fix this: it allows weird things in expressing problems.
302-
# Maybe we should have Rank <: ProximableFunction (with no prox! nor gradient!
302+
# Maybe we should have Rank (with no prox! nor gradient!
303303
# defined), that gives IndBallRank when combined with <=.
304-
struct Rank <: ProximableFunction end
304+
struct Rank end
305305
rank(ex::AbstractExpression) = Term(Rank(), ex)
306306

307307
import Base: <=
@@ -368,7 +368,7 @@ end
368368
import Base: conj
369369

370370
"""
371-
conj(t::Term)
371+
conj(t::Term)
372372
373373
Returns the convex conjugate transform of `t`:
374374
```math
@@ -388,19 +388,19 @@ julia> t = conj(norm(x,1))
388388
389389
"""
390390
function conj(t::Term)
391-
if typeof(operator(t)) <: Eye
392-
return Term(1.0,Conjugate(Postcompose(t.f,t.lambda)),t.A)
393-
else
394-
error("cannot perform convex conjugation")
395-
end
391+
if typeof(operator(t)) <: Eye
392+
return Term(1.0,Conjugate(Postcompose(t.f,t.lambda)),t.A)
393+
else
394+
error("cannot perform convex conjugation")
395+
end
396396

397397
end
398398

399399
# Moreau Envelope
400400
export smooth
401401

402402
"""
403-
smooth(t::Term, gamma = 1.0)
403+
smooth(t::Term, gamma = 1.0)
404404
405405
Smooths the nonsmooth term `t` using Moreau envelope:
406406

‎src/syntax/terms/term.jl

+27-27
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
struct Term{T1 <: Real, T2 <: ProximableFunction, T3 <: AbstractExpression}
2-
lambda::T1
3-
f::T2
4-
A::T3
5-
Term(lambda::T1, f::T2, ex::T3) where {T1,T2,T3} = new{T1,T2,T3}(lambda,f,ex)
1+
struct Term{T1 <: Real, T2, T3 <: AbstractExpression}
2+
lambda::T1
3+
f::T2
4+
A::T3
5+
Term(lambda::T1, f::T2, ex::T3) where {T1,T2,T3} = new{T1,T2,T3}(lambda,f,ex)
66
end
77

8-
function Term(f::T, ex::AbstractExpression) where {T<:ProximableFunction}
9-
A = convert(Expression,ex)
10-
Term(1,f, A)
8+
function Term(f, ex::AbstractExpression)
9+
A = convert(Expression,ex)
10+
Term(1,f, A)
1111
end
1212

1313
# Operations
@@ -28,12 +28,12 @@ import Base: +
2828
import Base: *
2929

3030
function (*)(a::T1, t::Term{T,T2,T3}) where {T1<:Real, T, T2, T3}
31-
coeff = *(promote(a,t.lambda)...)
32-
Term(coeff, t.f, t.A)
31+
coeff = *(promote(a,t.lambda)...)
32+
Term(coeff, t.f, t.A)
3333
end
3434

3535
function (*)(a::T1, t::T2) where {T1<:Real, N, T2 <: Tuple{Vararg{<:Term,N}} }
36-
return a.*t
36+
return a.*t
3737
end
3838

3939
# Properties
@@ -45,17 +45,17 @@ displacement(t::Term) = displacement(t.A)
4545

4646
#importing properties from ProximalOperators
4747
import ProximalOperators:
48-
is_affine,
49-
is_cone,
50-
is_convex,
51-
is_generalized_quadratic,
52-
is_prox_accurate,
53-
is_quadratic,
54-
is_separable,
55-
is_set,
56-
is_singleton,
57-
is_smooth,
58-
is_strongly_convex
48+
is_affine,
49+
is_cone,
50+
is_convex,
51+
is_generalized_quadratic,
52+
is_prox_accurate,
53+
is_quadratic,
54+
is_separable,
55+
is_set,
56+
is_singleton,
57+
is_smooth,
58+
is_strongly_convex
5959

6060
#importing properties from AbstractOperators
6161
is_f = [:is_linear,
@@ -72,11 +72,11 @@ is_f = [:is_linear,
7272
]
7373

7474
for f in is_f
75-
@eval begin
76-
import AbstractOperators: $f
77-
$f(t::Term) = $f(operator(t))
78-
$f(t::NTuple{N,Term}) where {N} = all($f.(t))
79-
end
75+
@eval begin
76+
import AbstractOperators: $f
77+
$f(t::Term) = $f(operator(t))
78+
$f(t::NTuple{N,Term}) where {N} = all($f.(t))
79+
end
8080
end
8181

8282
is_smooth(t::Term) = is_smooth(t.f)

‎test/test_build_minimize.jl

+5-4
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,26 @@ b = randn(5)
99
println("\nTesting @minimize \n")
1010
~x .= 0.
1111
~y .= 0.
12-
slv, = @minimize ls(A*x - B*y + b) st norm(x, 2) <= 1e4, norm(y, 1) <= 1.0 with ForwardBackward()
12+
slv, = @minimize ls(A*x - B*y + b) st norm(x, 2) <= 1e4, norm(y, 1) <= 1.0 with PANOCplus()
1313
~x .= 0.
14-
slv, = @minimize ls(A*x - b) st norm(x, 1) <= 1.0 with ForwardBackward()
14+
slv, = @minimize ls(A*x - b) st norm(x, 1) <= 1.0 with PANOCplus()
1515
~x .= 0.
1616
slv, = @minimize ls(A*x - b) st norm(x, 1) <= 1.0
1717
~x .= 0.
18-
slv, = @minimize ls(A*x - b) + norm(x, 1) with ForwardBackward()
18+
slv, = @minimize ls(A*x - b) + norm(x, 1) with PANOCplus()
1919
~x .= 0.
2020
slv, = @minimize ls(A*x - b) + norm(x, 1)
2121
~x .= 0.
2222
slv, = @minimize ls(A*x - b)
2323

2424
#TODO many many more tests
25+
Random.seed!(12345)
2526
x = Variable(5)
2627
A = randn(10, 5)
2728
b = randn(10)
2829

2930
println("\nTesting @minimize nonlinear \n")
30-
slv, = @minimize ls(sigmoid(A*x,10) - b)+norm(x,1) with ForwardBackward(tol = 1e-6)
31+
slv, = @minimize ls(sigmoid(A*x,10) - b)+norm(x,1) with PANOCplus(tol = 1e-6)
3132
xpg = copy(~x)
3233
~x .= 0.
3334
slv, = @minimize ls(sigmoid(A*x,10) - b)+norm(x,1) with ZeroFPR(tol = 1e-6)

‎test/test_usage.jl

+14-14
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ b = randn(m)
1515
lam1 = 0.2
1616
lam2 = 1.0
1717

18-
# Solve with FPG
18+
# Solve with PANOC+
1919

2020
x1_fpg = Variable(n1)
2121
x2_fpg = Variable(n2)
2222
expr = ls(A1*x1_fpg + A2*x2_fpg - b) + lam1*norm(x1_fpg, 1) + lam2*norm(x2_fpg, 2)
2323
prob = problem(expr)
24-
@time sol = solve(prob, ForwardBackward(fast=true, tol=1e-10, verbose=false,maxit=20000))
24+
@time sol = solve(prob, PANOCplus(tol=1e-10, verbose=false,maxit=20000))
2525

2626
# Solve with ZeroFPR
2727

@@ -86,17 +86,17 @@ b = A*x_star + A'\y_star
8686
x_pg = Variable(n)
8787
expr = ls(A*x_pg - b) + lam*norm(x_pg, 1)
8888
prob = problem(expr)
89-
@time sol = solve(prob, ForwardBackward(tol=1e-10, verbose=false))
89+
@time sol = solve(prob, PANOCplus(tol=1e-10, verbose=false))
9090

9191
@test norm(~x_pg - x_star, Inf) <= 1e-8
9292
@test norm(A'*(A*~x_pg - b) + lam*sign.(~x_pg)) <= 1e-6
9393

94-
# Solve with FPG
94+
# Solve with PANOC+
9595

9696
x_fpg = Variable(n)
9797
expr = ls(A*x_fpg - b) + lam*norm(x_fpg, 1)
9898
prob = problem(expr)
99-
@time sol = solve(prob, ForwardBackward(fast=true, tol=1e-10, verbose=false))
99+
@time sol = solve(prob, PANOCplus(tol=1e-10, verbose=false))
100100

101101
@test norm(~x_fpg - x_star, Inf) <= 1e-8
102102
@test norm(A'*(A*~x_fpg - b) + lam*sign.(~x_fpg)) <= 1e-6
@@ -139,14 +139,14 @@ b = A*x_orig + randn(m)
139139
x_pg = Variable(n)
140140
expr = smooth(norm(A*x_pg - b, 2)) + lam*norm(x_pg, 1)
141141
prob = problem(expr)
142-
@time sol = solve(prob, ForwardBackward(tol=1e-6, verbose=false))
142+
@time sol = solve(prob, PANOCplus(tol=1e-6, verbose=false))
143143

144-
# Solve with FPG
144+
# Solve with PANOC+
145145

146146
x_fpg = Variable(n)
147147
expr = smooth(norm(A*x_fpg - b, 2)) + lam*norm(x_fpg, 1)
148148
prob = problem(expr)
149-
@time sol = solve(prob, ForwardBackward(fast=true, tol=1e-6, verbose=false))
149+
@time sol = solve(prob, PANOCplus(tol=1e-6, verbose=false))
150150

151151
# Solve with ZeroFPR
152152

@@ -190,17 +190,17 @@ b = A*x_orig + randn(m)
190190
x_pg = Variable(n)
191191
expr = ls(A*x_pg - b)
192192
prob = problem(expr, x_pg in [lb, ub])
193-
@time sol = solve(prob, ForwardBackward(tol=1e-6, verbose=false))
193+
@time sol = solve(prob, PANOCplus(tol=1e-6, verbose=false))
194194

195195
@test norm(~x_pg - max.(lb, min.(ub, ~x_pg)), Inf) <= 1e-12
196196
@test norm(~x_pg - max.(lb, min.(ub, ~x_pg - A'*(A*~x_pg - b))), Inf)/(1+norm(~x_pg, Inf)) <= 1e-6
197197

198-
# Solve with FPG
198+
# Solve with PANOC+
199199

200200
x_fpg = Variable(n)
201201
expr = ls(A*x_fpg - b)
202202
prob = problem(expr, x_fpg in [lb, ub])
203-
@time sol = solve(prob, ForwardBackward(fast=true, tol=1e-6, verbose=false))
203+
@time sol = solve(prob, PANOCplus(tol=1e-6, verbose=false))
204204

205205
@test norm(~x_fpg - max.(lb, min.(ub, ~x_fpg)), Inf) <= 1e-12
206206
@test norm(~x_fpg - max.(lb, min.(ub, ~x_fpg - A'*(A*~x_fpg - b))), Inf)/(1+norm(~x_fpg, Inf)) <= 1e-6
@@ -264,17 +264,17 @@ b = A*x_star + A'\y_star
264264
x_pg = Variable(n)
265265
expr = ls(A*x_pg - b)
266266
prob = problem(expr, x_pg >= 0.0)
267-
@time sol = solve(prob, ForwardBackward(tol=1e-8, verbose=false))
267+
@time sol = solve(prob, PANOCplus(tol=1e-8, verbose=false))
268268

269269
@test all(~x_pg .>= 0.0)
270270
@test norm(~x_pg - x_star, Inf)/(1+norm(x_star, Inf)) <= 1e-8
271271

272-
# Solve with FPG
272+
# Solve with PANOC+
273273

274274
x_fpg = Variable(n)
275275
expr = ls(A*x_fpg - b)
276276
prob = problem(expr, x_fpg >= 0.0)
277-
@time sol = solve(prob, ForwardBackward(fast=true, tol=1e-8, verbose=false))
277+
@time sol = solve(prob, PANOCplus(tol=1e-8, verbose=false))
278278

279279
@test all(~x_fpg .>= 0.0)
280280
@test norm(~x_fpg - x_star, Inf)/(1+norm(x_star, Inf)) <= 1e-8

‎test/test_usage_small.jl

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
A = randn(3,5)
22
b = randn(3)
33

4-
x_pg = Variable(5)
5-
prob_pg = problem(ls(A*x_pg - b) + 1e-3*norm(x_pg, 1))
6-
sol_pg = solve(prob_pg, ForwardBackward())
7-
84
x_zfpr = Variable(5)
95
prob_zfpr = problem(ls(A*x_zfpr - b) + 1e-3*norm(x_zfpr, 1))
106
sol_zfpr = solve(prob_zfpr, ZeroFPR())
117

128
x_pnc = Variable(5)
139
prob_pnc = problem(ls(A*x_pnc - b) + 1e-3*norm(x_pnc, 1))
1410
sol_pnc = solve(prob_pnc, PANOC())
11+
12+
x_pncp = Variable(5)
13+
prob_pncp = problem(ls(A*x_pncp - b) + 1e-3*norm(x_pncp, 1))
14+
sol_pncp = solve(prob_pncp, PANOCplus())

0 commit comments

Comments
 (0)
Please sign in to comment.