src/Logger.jl

changeset 34
22a64e826ee7
equal deleted inserted replaced
33:a60d2f12ef93 34:22a64e826ee7
1 #
2 # This module implements logging of intermediate computational results for
3 # generating convergence graphs, etc.
4 #
5
6 """
7 Logging routines for intermediate computational results.
8 Includes `Log`, `log!`, `if_log!`, and `write_log`.
9 """
10 module Logger
11
12 import DelimitedFiles: writedlm
13
14 ##############
15 # Our exports
16 ##############
17
18 export Log,
19 log!,
20 if_log!,
21 write_log
22
23 ##########
24 # Logging
25 ##########
26
27 """
28 `struct Log{T}`
29
30 A log of items of type `T` along with log configuration.
31 The constructor takes no arguments; create the log with `Log{T}()` for `T` your
32 data type, e.g., `Float64`.
33 """
34 struct Log{T}
35 log :: Dict{Int, T}
36
37 Log{T}() where T = new{T}(Dict{Int, T}())
38 end
39
40 """
41 `if_log!(f :: Functdion, log :: Log{T}, i :: Int)`
42
43 If based on the log settings, `i` is a verbose iteration, store the value of `f()`
44 in the log at index `i`. Typically to be used with `do`-notation:
45
46 ```julia
47 if_log!(log, iteration) do
48 # calculate value to be logged
49 end
50 ```
51 """
52 function if_log!(f :: Function, log :: Log{T}, i :: Int) where T
53 if mod(i, log.verbose_iterations)==0
54 log!(f, log, i)
55 #printstyled("$(i): $(val)\n", color=:light_black)
56 end
57 end
58
59 """
60 `log!(f :: Function, log :: Log{T}, i :: Int) `
61
62 Store the value `f()` in the log at index `i`.
63 """
64 function log!(f :: Function, log :: Log{T}, i :: Int) where T
65 val = f()
66 push!(log.log, i => val)
67 end
68
69 ##############
70 # Data export
71 ##############
72
73 """
74 `write_log(filename :: AbstractString, log :: Log{T})`
75
76 Write a `Log{T}` as a CSV file using `DelimitedFiles`.
77 If T is a structural type, the field names are used as header fields.
78 Otherwise a single `value` field is attempted to be written.
79 """
80 function write_log(filename :: AbstractString, log :: Log{T}) where T
81 k = fieldnames(T)
82 @assert(:iter ∉ k)
83
84 open(filename, "w") do io
85 # Write header
86 writedlm(io, isempty(k) ? [:iter :value] : ((:iter, k...),))
87 # Write values
88 iters = sort(collect(keys(log.log)))
89 for i ∈ iters
90 v = log.log[i]
91 writedlm(io, isempty(k) ? [i v] : ((i, (getfield(v, j) for j ∈ k)...),))
92 end
93 end
94 end
95
96 end # module

mercurial