diff --git a/src/ProximalAlgorithms.jl b/src/ProximalAlgorithms.jl index db83764..72f9b33 100644 --- a/src/ProximalAlgorithms.jl +++ b/src/ProximalAlgorithms.jl @@ -39,9 +39,11 @@ function run(solver::ProximalAlgorithm{I, T})::Tuple{I, T} where {I, T} # [...] # end # + if verbose(solver) display(solver) end for (it, point) in enumerate(solver) if verbose(solver, it) display(solver, it) end end + if verbose(solver) display(solver, it) end return (it, point) end diff --git a/src/algorithms/DouglasRachford.jl b/src/algorithms/DouglasRachford.jl index e410745..8c9b0a6 100644 --- a/src/algorithms/DouglasRachford.jl +++ b/src/algorithms/DouglasRachford.jl @@ -13,6 +13,7 @@ struct DRSIterator{I <: Integer, R <: Real, T <: BlockArray{R}} <: ProximalAlgor maxit::I tol::R verbose::I + verbose_freq::I y::T r::T z::T @@ -22,13 +23,13 @@ end ################################################################################ # Constructor(s) -function DRSIterator(x0::BlockArray{R}; f=Zero(), g=Zero(), gamma::R=1.0, maxit::I=10000, tol::R=1e-4, verbose=1) where {I, R} +function DRSIterator(x0::BlockArray{R}; f=Zero(), g=Zero(), gamma::R=1.0, maxit::I=10000, tol::R=1e-4, verbose=1, verbose_freq = 100) where {I, R} y = blockcopy(x0) r = blockcopy(x0) z = blockcopy(x0) FPR_x = blockcopy(x0) FPR_x .= Inf - return DRSIterator{I, R, typeof(x0)}(x0, f, g, gamma, maxit, tol, verbose, y, r, z, FPR_x) + return DRSIterator{I, R, typeof(x0)}(x0, f, g, gamma, maxit, tol, verbose, verbose_freq, y, r, z, FPR_x) end ################################################################################ @@ -38,9 +39,23 @@ maxit(sol::DRSIterator) = sol.maxit converged(sol::DRSIterator, it) = blockmaxabs(sol.FPR_x)/sol.gamma <= sol.tol -verbose(sol::DRSIterator, it) = sol.verbose > 0 +verbose(sol::DRSIterator) = sol.verbose > 0 +verbose(sol::DRSIterator, it) = sol.verbose > 0 && (sol.verbose == 2 ? true : (it == 1 || it%sol.verbose_freq == 0)) -display(sol::DRSIterator, it) = println("$(it) $(blockmaxabs(sol.FPR_x)/sol.gamma)") +function display(sol::DRSIterator) + @printf("%6s | %10s | %10s |\n ", "it", "gamma", "fpr") + @printf("------|------------|------------|\n") +end + +function display(sol::DRSIterator, it) + @printf("%6d | %7.4e | %7.4e |\n", it, sol.gamma, blockmaxabs(sol.FPR_x)/sol.gamma) +end + +function Base.show(io::IO, sol::DRSIterator) + println(io, "Douglas-Rachford Splitting" ) + println(io, "fpr : $(blockmaxabs(sol.FPR_x))") + print( io, "gamma : $(sol.gamma)") +end ################################################################################ # Initialization diff --git a/src/algorithms/ForwardBackward.jl b/src/algorithms/ForwardBackward.jl index f0f738e..69e6152 100644 --- a/src/algorithms/ForwardBackward.jl +++ b/src/algorithms/ForwardBackward.jl @@ -21,6 +21,7 @@ mutable struct FBSIterator{I <: Integer, R <: Real, T <: BlockArray{R}} <: Proxi adaptive::Bool fast::Bool verbose::I + verbose_freq::I theta::R # extrapolation parameter y # gradient step z # proximal-gradient step @@ -42,7 +43,7 @@ end ################################################################################ # Constructor -function FBSIterator(x0::T; fs=Zero(), As=Identity(blocksize(x0)), fq=Zero(), Aq=Identity(blocksize(x0)), g=Zero(), gamma::R=-1.0, maxit::I=10000, tol::R=1e-4, adaptive=false, fast=false, verbose=1) where {I, R, T} +function FBSIterator(x0::T; fs=Zero(), As=Identity(blocksize(x0)), fq=Zero(), Aq=Identity(blocksize(x0)), g=Zero(), gamma::R=-1.0, maxit::I=10000, tol::R=1e-4, adaptive=false, fast=false, verbose=1, verbose_freq = 100) where {I, R, T} n = blocksize(x0) mq = size(Aq, 1) ms = size(As, 1) @@ -59,7 +60,7 @@ function FBSIterator(x0::T; fs=Zero(), As=Identity(blocksize(x0)), fq=Zero(), Aq Aqz_prev = blockzeros(mq) Asz_prev = blockzeros(ms) gradfq_Aqz_prev = blockzeros(mq) - FBSIterator{I, R, T}(x, fs, As, fq, Aq, g, gamma, maxit, tol, adaptive, fast, verbose, 1.0, y, z, z_prev, FPR_x, Aqx, Asx, gradfq_Aqx, gradfs_Asx, 0.0, 0.0, 0.0, At_gradf_Ax, Aqz_prev, Asz_prev, gradfq_Aqz_prev) + FBSIterator{I, R, T}(x, fs, As, fq, Aq, g, gamma, maxit, tol, adaptive, fast, verbose, verbose_freq, 1.0, y, z, z_prev, FPR_x, Aqx, Asx, gradfq_Aqx, gradfs_Asx, 0.0, 0.0, 0.0, At_gradf_Ax, Aqz_prev, Asz_prev, gradfq_Aqz_prev) end ################################################################################ @@ -69,10 +70,22 @@ maxit(sol::FBSIterator) = sol.maxit converged(sol::FBSIterator, it) = blockmaxabs(sol.FPR_x)/sol.gamma <= sol.tol -verbose(sol::FBSIterator, it) = sol.verbose > 0 +verbose(sol::FBSIterator) = sol.verbose > 0 +verbose(sol::FBSIterator, it) = sol.verbose > 0 && (sol.verbose == 2 ? true : (it == 1 || it%sol.verbose_freq == 0)) + +function display(sol::FBSIterator) + @printf("%6s | %10s | %10s |\n ", "it", "gamma", "fpr") + @printf("------|------------|------------|\n") +end function display(sol::FBSIterator, it) - println("$(it) $(sol.gamma) $(blockmaxabs(sol.FPR_x)/sol.gamma)") + @printf("%6d | %7.4e | %7.4e |\n", it, sol.gamma, blockmaxabs(sol.FPR_x)/sol.gamma) +end + +function Base.show(io::IO, sol::FBSIterator) + println(io, (sol.fast ? "Fast " : "")*"Forward-Backward Splitting" ) + println(io, "fpr : $(blockmaxabs(sol.FPR_x))") + print( io, "gamma : $(sol.gamma)") end ################################################################################ diff --git a/src/algorithms/Template.jl b/src/algorithms/Template.jl index f4880f4..e003606 100644 --- a/src/algorithms/Template.jl +++ b/src/algorithms/Template.jl @@ -20,10 +20,16 @@ maxit(sol::TemplateIterator) = sol.maxit converged(sol::TemplateIterator, it) = false +verbose(sol::TemplateIterator) = true verbose(sol::TemplateIterator, it) = true +display(sol::TemplateIterator) = println("its ") display(sol::TemplateIterator, it) = println("$(it) iterations performed") +function Base.show(io::IO, sol::TemplateIterator) + print(io, "Template Solver" ) +end + ################################################################################ # Initialization diff --git a/src/algorithms/ZeroFPR.jl b/src/algorithms/ZeroFPR.jl index 55caf85..7037165 100644 --- a/src/algorithms/ZeroFPR.jl +++ b/src/algorithms/ZeroFPR.jl @@ -13,6 +13,7 @@ mutable struct ZeroFPRIterator{I <: Integer, R <: Real, T <: BlockArray} <: Prox tol::R adaptive::Bool verbose::I + verbose_freq::I alpha::R sigma::R tau::R @@ -38,7 +39,7 @@ end ################################################################################ # Constructor -function ZeroFPRIterator(x0::T; fs=Zero(), As=Identity(blocksize(x0)), fq=Zero(), Aq=Identity(blocksize(x0)), g=Zero(), gamma::R=-1.0, maxit::I=10000, tol::R=1e-4, adaptive=false, memory=10, verbose=1, alpha=0.95, sigma=0.5) where {I, R, T} +function ZeroFPRIterator(x0::T; fs=Zero(), As=Identity(blocksize(x0)), fq=Zero(), Aq=Identity(blocksize(x0)), g=Zero(), gamma::R=-1.0, maxit::I=10000, tol::R=1e-4, adaptive=false, memory=10, verbose=1, verbose_freq=100, alpha=0.95, sigma=0.5) where {I, R, T} n = blocksize(x0) mq = size(Aq, 1) ms = size(As, 1) @@ -52,7 +53,7 @@ function ZeroFPRIterator(x0::T; fs=Zero(), As=Identity(blocksize(x0)), fq=Zero() gradfs_Asx = blockzeros(ms) At_gradf_Ax = blockzeros(n) d = blockzeros(x0) - ZeroFPRIterator{I, R, T}(x, fs, As, fq, Aq, g, gamma, maxit, tol, adaptive, verbose, alpha, sigma, 0.0, y, xbar, LBFGS(x, memory), FPR_x, Aqx, Asx, gradfq_Aqx, gradfs_Asx, 0.0, 0.0, 0.0, At_gradf_Ax, 0.0, 0.0, [], [], d) + ZeroFPRIterator{I, R, T}(x, fs, As, fq, Aq, g, gamma, maxit, tol, adaptive, verbose, verbose_freq, alpha, sigma, 0.0, y, xbar, LBFGS(x, memory), FPR_x, Aqx, Asx, gradfq_Aqx, gradfs_Asx, 0.0, 0.0, 0.0, At_gradf_Ax, 0.0, 0.0, [], [], d) end ################################################################################ @@ -62,10 +63,23 @@ maxit(sol::ZeroFPRIterator) = sol.maxit converged(sol::ZeroFPRIterator, it) = blockmaxabs(sol.FPR_x)/sol.gamma <= sol.tol -verbose(sol::ZeroFPRIterator, it) = sol.verbose > 0 +verbose(sol::ZeroFPRIterator) = sol.verbose > 0 +verbose(sol::ZeroFPRIterator, it) = sol.verbose > 0 && (sol.verbose == 2 ? true : (it == 1 || it%sol.verbose_freq == 0)) +function display(sol::ZeroFPRIterator) + @printf("%6s | %10s | %10s | %10s | %10s |\n ", "it", "gamma", "fpr", "tau", "FBE") + @printf("------|------------|------------|------------|------------|\n") +end function display(sol::ZeroFPRIterator, it) - println("$(it) $(sol.gamma) $(blockmaxabs(sol.FPR_x)/sol.gamma) $(blockmaxabs(sol.d)) $(sol.tau) $(sol.FBE_x)") + @printf("%6d | %7.4e | %7.4e | %7.4e | %7.4e | \n", it, sol.gamma, blockmaxabs(sol.FPR_x)/sol.gamma, sol.tau, sol.FBE_x) +end + +function Base.show(io::IO, sol::ZeroFPRIterator) + println(io, "ZeroFPR" ) + println(io, "fpr : $(blockmaxabs(sol.FPR_x))") + println(io, "gamma : $(sol.gamma)") + println(io, "tau : $(sol.tau)") + print( io, "FBE : $(sol.FBE_x)") end ################################################################################ diff --git a/test/test_l1logreg_small.jl b/test/test_l1logreg_small.jl index 1dd30e7..9d41035 100644 --- a/test/test_l1logreg_small.jl +++ b/test/test_l1logreg_small.jl @@ -20,6 +20,7 @@ x0 = zeros(n) @time it, x, sol = ProximalAlgorithms.FBS(x0; fs=f, As=A, g=g, tol=1e-6, adaptive=true) @test vecnorm(x - x_star, Inf) <= 1e-4 @test it == 1658 +println(sol) # Fast/Adaptive @@ -27,6 +28,7 @@ x0 = zeros(n) @time it, x, sol = ProximalAlgorithms.FBS(x0; fs=f, As=A, g=g, tol=1e-6, adaptive=true, fast=true) @test vecnorm(x - x_star, Inf) <= 1e-4 @test it == 473 +println(sol) # ZeroFPR/Adaptive @@ -34,3 +36,4 @@ x0 = zeros(n) @time it, x, sol = ProximalAlgorithms.ZeroFPR(x0; fs=f, As=A, g=g, tol=1e-6, adaptive=true) @test vecnorm(x - x_star, Inf) <= 1e-4 @test it == 19 +println(sol) diff --git a/test/test_lasso_small.jl b/test/test_lasso_small.jl index ef67d9d..d673d36 100644 --- a/test/test_lasso_small.jl +++ b/test/test_lasso_small.jl @@ -21,6 +21,7 @@ x0 = zeros(n) @time it, x, sol = ProximalAlgorithms.FBS(x0; fq=f, Aq=A, g=g, gamma=1.0/norm(A)^2) @test vecnorm(x - x_star, Inf) <= 1e-4 @test it == 140 +println(sol) # Nonfast/Adaptive @@ -28,6 +29,7 @@ x0 = zeros(n) @time it, x, sol = ProximalAlgorithms.FBS(x0; fq=f, Aq=A, g=g, adaptive=true) @test vecnorm(x - x_star, Inf) <= 1e-4 @test it == 247 +println(sol) # Fast/Nonadaptive @@ -35,6 +37,7 @@ x0 = zeros(n) @time it, x, sol = ProximalAlgorithms.FBS(x0; fq=f, Aq=A, g=g, gamma=1.0/norm(A)^2, fast=true) @test vecnorm(x - x_star, Inf) <= 1e-4 @test it == 94 +println(sol) # Fast/Adaptive @@ -42,6 +45,7 @@ x0 = zeros(n) @time it, x, sol = ProximalAlgorithms.FBS(x0; fq=f, Aq=A, g=g, adaptive=true, fast=true) @test vecnorm(x - x_star, Inf) <= 1e-4 @test it == 156 +println(sol) # ZeroFPR/Nonadaptive @@ -49,6 +53,7 @@ x0 = zeros(n) @time it, x, sol = ProximalAlgorithms.ZeroFPR(x0; fq=f, Aq=A, g=g, gamma=1.0/norm(A)^2) @test vecnorm(x - x_star, Inf) <= 1e-4 @test it == 8 +println(sol) # ZeroFPR/Adaptive @@ -56,9 +61,11 @@ x0 = zeros(n) @time it, x, sol = ProximalAlgorithms.ZeroFPR(x0; fq=f, Aq=A, g=g, adaptive=true) @test vecnorm(x - x_star, Inf) <= 1e-4 @test it == 10 +println(sol) # Douglas-Rachford x0 = zeros(n) @time it, x, sol = ProximalAlgorithms.DRS(x0; f=f2, g=g, gamma=10.0/norm(A)^2) @test vecnorm(x - x_star, Inf) <= 1e-4 +println(sol) diff --git a/test/test_lasso_small_split_f.jl b/test/test_lasso_small_split_f.jl index c5484d4..8ba5cfe 100644 --- a/test/test_lasso_small_split_f.jl +++ b/test/test_lasso_small_split_f.jl @@ -24,6 +24,7 @@ x0 = ProximalAlgorithms.blockzeros(x_star) @time it, x, sol = ProximalAlgorithms.FBS(x0; fq=f, Aq=opA, g=g, gamma=1.0/norm(A)^2) @test vecnorm(x .- x_star, Inf) <= 1e-4 @test it == 140 +println(sol) # Nonfast/Adaptive @@ -31,6 +32,7 @@ x0 = ProximalAlgorithms.blockzeros(x_star) @time it, x, sol = ProximalAlgorithms.FBS(x0; fq=f, Aq=opA, g=g, adaptive=true) @test vecnorm(x .- x_star, Inf) <= 1e-4 @test it == 247 +println(sol) # Fast/Nonadaptive @@ -38,6 +40,7 @@ x0 = ProximalAlgorithms.blockzeros(x_star) @time it, x, sol = ProximalAlgorithms.FBS(x0; fq=f, Aq=opA, g=g, gamma=1.0/norm(A)^2, fast=true) @test vecnorm(x .- x_star, Inf) <= 1e-4 @test it == 94 +println(sol) # Fast/Adaptive @@ -45,6 +48,7 @@ x0 = ProximalAlgorithms.blockzeros(x_star) @time it, x, sol = ProximalAlgorithms.FBS(x0; fq=f, Aq=opA, g=g, adaptive=true, fast=true) @test vecnorm(x .- x_star, Inf) <= 1e-4 @test it == 156 +println(sol) # ZeroFPR/Nonadaptive @@ -52,6 +56,7 @@ x0 = ProximalAlgorithms.blockzeros(x_star) @time it, x, sol = ProximalAlgorithms.ZeroFPR(x0; fq=f, Aq=opA, g=g, gamma=1.0/norm(A)^2) @test vecnorm(x - x_star, Inf) <= 1e-4 @test it == 8 +println(sol) # ZeroFPR/Adaptive @@ -59,3 +64,4 @@ x0 = ProximalAlgorithms.blockzeros(x_star) @time it, x, sol = ProximalAlgorithms.ZeroFPR(x0; fq=f, Aq=opA, g=g, adaptive=true) @test vecnorm(x - x_star, Inf) <= 1e-4 @test it == 10 +println(sol) diff --git a/test/test_lasso_small_split_x.jl b/test/test_lasso_small_split_x.jl index a023570..f379ef2 100644 --- a/test/test_lasso_small_split_x.jl +++ b/test/test_lasso_small_split_x.jl @@ -31,6 +31,7 @@ x0 = ProximalAlgorithms.blockzeros(x_star) @time it, x, sol = ProximalAlgorithms.FBS(x0; fq=f, Aq=opA, g=g, gamma=1.0/norm(A)^2) @test ProximalAlgorithms.blockmaxabs(x .- x_star) <= 1e-4 @test it == 140 +println(sol) # Nonfast/Adaptive @@ -38,6 +39,7 @@ x0 = ProximalAlgorithms.blockzeros(x_star) @time it, x, sol = ProximalAlgorithms.FBS(x0; fq=f, Aq=opA, g=g, adaptive=true) @test ProximalAlgorithms.blockmaxabs(x .- x_star) <= 1e-4 @test it == 247 +println(sol) # Fast/Nonadaptive @@ -45,6 +47,7 @@ x0 = ProximalAlgorithms.blockzeros(x_star) @time it, x, sol = ProximalAlgorithms.FBS(x0; fq=f, Aq=opA, g=g, gamma=1.0/norm(A)^2, fast=true) @test ProximalAlgorithms.blockmaxabs(x .- x_star) <= 1e-4 @test it == 94 +println(sol) # Fast/Adaptive @@ -52,6 +55,7 @@ x0 = ProximalAlgorithms.blockzeros(x_star) @time it, x, sol = ProximalAlgorithms.FBS(x0; fq=f, Aq=opA, g=g, adaptive=true, fast=true) @test ProximalAlgorithms.blockmaxabs(x .- x_star) <= 1e-4 @test it == 156 +println(sol) # ZeroFPR/Adaptive @@ -59,3 +63,5 @@ x0 = ProximalAlgorithms.blockzeros(x_star) @time it, x, sol = ProximalAlgorithms.ZeroFPR(x0; fq=f, Aq=opA, g=g, adaptive=true) @test ProximalAlgorithms.blockmaxabs(x .- x_star) <= 1e-4 @test it == 10 +println(sol) + diff --git a/test/test_template.jl b/test/test_template.jl index b66e789..c2351f9 100644 --- a/test/test_template.jl +++ b/test/test_template.jl @@ -2,3 +2,4 @@ x0 = randn(10) it, x, sol = ProximalAlgorithms.Template(x0) @test it == 10 @test norm(x - x0) == 0.0 +println(sol)