Wed, 22 Dec 2021 11:14:38 +0200
Add metaprogramming tools and fast multidimensional loops.
# # This module implements logging of intermediate computational results for # generating convergence graphs, etc. # """ Logging routines for intermediate computational results. Includes `Log`, `log!`, `if_log!`, and `write_log`. """ module Logger import DelimitedFiles: writedlm ############## # Our exports ############## export Log, log!, if_log!, write_log ########## # Logging ########## """ `struct Log{T}` A log of items of type `T` along with log configuration. The constructor takes no arguments; create the log with `Log{T}()` for `T` your data type, e.g., `Float64`. """ struct Log{T} log :: Dict{Int, T} Log{T}() where T = new{T}(Dict{Int, T}()) end """ `if_log!(f :: Functdion, log :: Log{T}, i :: Int)` If based on the log settings, `i` is a verbose iteration, store the value of `f()` in the log at index `i`. Typically to be used with `do`-notation: ```julia if_log!(log, iteration) do # calculate value to be logged end ``` """ function if_log!(f :: Function, log :: Log{T}, i :: Int) where T if mod(i, log.verbose_iterations)==0 log!(f, log, i) #printstyled("$(i): $(val)\n", color=:light_black) end end """ `log!(f :: Function, log :: Log{T}, i :: Int) ` Store the value `f()` in the log at index `i`. """ function log!(f :: Function, log :: Log{T}, i :: Int) where T val = f() push!(log.log, i => val) end ############## # Data export ############## """ `write_log(filename :: AbstractString, log :: Log{T})` Write a `Log{T}` as a CSV file using `DelimitedFiles`. If T is a structural type, the field names are used as header fields. Otherwise a single `value` field is attempted to be written. """ function write_log(filename :: AbstractString, log :: Log{T}) where T k = fieldnames(T) @assert(:iter ∉ k) open(filename, "w") do io # Write header writedlm(io, isempty(k) ? [:iter :value] : ((:iter, k...),)) # Write values iters = sort(collect(keys(log.log))) for i ∈ iters v = log.log[i] writedlm(io, isempty(k) ? [i v] : ((i, (getfield(v, j) for j ∈ k)...),)) end end end end # module