diff --git a/Project.toml b/Project.toml index 07f39014..04926483 100644 --- a/Project.toml +++ b/Project.toml @@ -4,6 +4,7 @@ version = "0.3.0" [deps] DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +Formatting = "59287772-0a20-5a39-b81b-1366585eb4c0" JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" LinearOperators = "5c8ed15e-5a4c-59e4-a42b-c7e8811fb125" diff --git a/src/SolverTools.jl b/src/SolverTools.jl index ed6ecde2..6fc001e6 100644 --- a/src/SolverTools.jl +++ b/src/SolverTools.jl @@ -13,6 +13,7 @@ using DataFrames, JLD2 include("auxiliary/blas.jl") include("auxiliary/bounds.jl") include("auxiliary/logger.jl") +include("auxiliary/solver-logger.jl") include("stats/stats.jl") # Algorithmic components. diff --git a/src/auxiliary/solver-logger.jl b/src/auxiliary/solver-logger.jl new file mode 100644 index 00000000..a37f9b59 --- /dev/null +++ b/src/auxiliary/solver-logger.jl @@ -0,0 +1,39 @@ +using Formatting + +export SolverLogger, header + +mutable struct SolverLogger + keys :: Vector{Symbol} + types :: Vector{DataType} + formatters :: Vector +end + +function SolverLogger(col_keys::Vector{Symbol}, col_types::Vector{DataType}) + formatters = [ + begin + fmt = get(formats, t, nothing) + if isnothing(fmt) + fmt = get(formats, supertype(t), "%10s") + end + len = match(r"\%([0-9]*)", fmt)[1] + (generate_formatter(fmt), generate_formatter("%$(len)s")) + end for t in col_types + ] + SolverLogger(col_keys, col_types, formatters) +end + +function header(logger::SolverLogger) + join([logger.formatters[i][2](string(x)) for (i,x) in enumerate(logger.keys)], " ") +end + +function log(logger::SolverLogger, args...) + if length(args) != length(logger.keys) + throw(ArgumentError("SolverLogger needs $(length(logger.keys)) arguments")) + end + join([ + ismissing(x) ? logger.formatters[i][2]("-") : logger.formatters[i][1](x) + for (i,x) in enumerate(args) + ], " ") +end + +(logger::SolverLogger)(args...) = log(logger, args...) \ No newline at end of file diff --git a/test.jl b/test.jl new file mode 100644 index 00000000..45c3bc17 --- /dev/null +++ b/test.jl @@ -0,0 +1,12 @@ +using SolverTools + +slug = SolverLogger( + [:f, :∇f, :iter, :status], + [Float64, Float64, Int, Symbol] +) + +@info header(slug) +@info SolverTools.log(slug, 1, 1, 1, missing) +@info SolverTools.log(slug, 1, 1, 2.0, missing) +@info SolverTools.log(slug, 1, missing, 2, "Step failure") +@info slug(1, 2, 3, "Step failure") \ No newline at end of file