Line data Source code
1 : #
2 : # General helpers: I'm missing these in the standard library!
3 : #
4 : if VERSION < v"1.7"
5 : export findmin, argmin, findmax, argmax
6 :
7 0 : Base.findmin(f::Base.Generator) = mapreduce(reverse, min, enumerate(f))
8 0 : Base.argmin(f::Base.Generator) = findmin(f)[2]
9 :
10 0 : Base.findmax(f::Base.Generator) = mapreduce(reverse, max, enumerate(f))
11 0 : Base.argmax(f::Base.Generator) = findmax(f)[2]
12 : end
13 :
14 : #-----------------------------------------------------------------------------
15 :
16 9 : function _s2d_helper(s)
17 10 : (length(propertynames(s)) > 0) && return struct_to_dict(s)
18 :
19 7 : s
20 : end
21 :
22 : """
23 : d = struct_to_dict(s)
24 :
25 : Convert `struct` type (or named tuple) to `Dict`. Properties are converted
26 : recursively.
27 :
28 : One use case is testing implementations of `Base.copy` for a new
29 : `struct`: There is a generic equal comparison for `Dict`, and we can
30 : easily check that no fields where missed.
31 : """
32 5 : function struct_to_dict(s)
33 6 : Dict(key => _s2d_helper(getproperty(s, key)) for key in propertynames(s))
34 : end
35 :
36 : # NOTE: https://stackoverflow.com/questions/68852523/julia-struct-to-dict
37 :
38 : #-----------------------------------------------------------------------------
39 :
40 3 : f_helper(x) = x
41 2 : f_helper(d::Dict) = Dict(Symbol(k) => f_helper(v) for (k, v) in d)
42 :
43 : """
44 : d = symbolize_keys(dict)
45 :
46 : Recursively map keys in `dict::Dict` to `Symbol`s.
47 : """
48 1 : symbolize_keys(d::Dict) = f_helper(d)
49 :
50 : # NOTE: https://gist.github.com/oyd11/392bfdc4fabae3d7361b5e52c961edd8
51 :
52 : #-----------------------------------------------------------------------------
53 :
54 0 : decompose_vectype(v::AbstractVector{T}) where {T} = length(v), T
55 :
56 0 : decompose_vectype(::SVector{N, T}) where {N, T} = (N, T)
57 :
58 : """
59 : N, T = decompose_vectype(v)
60 :
61 : Get `eltype` and `length` from `v::AbstractVector`. The intended use
62 : is decomposing parameters of `SVector{N,T}` (at no cost).
63 : """ decompose_vectype
64 :
65 0 : function filled(::Type{SVector{N, T}}, xs...; fill) where {N, T}
66 0 : SVector(T.(xs)..., ntuple(_ -> T(fill), N-length(xs))...)
67 : end
68 :
69 0 : filled(x::SVector, xs...; fill) = filled(typeof(x), xs...; fill)
70 :
71 : """
72 : x = SVector(...)
73 : y = filled(typeof(x), [y1, y2, ...], fill=yend)
74 : y = filled(x, [y1, y2, ...], fill=yend)
75 :
76 : Construct an `SVector{T, N}` as given by `typeof(x)` with components
77 : `(y1, y2, ..., yend, ..., yend)`, i.e., set the first components and
78 : "fills" to match length `N`.
79 : """ filled
|