TLDR: I want to use Parameters.jl
and convert a fraction of its fields to a vector and back. I can convert to the vector, but I don’t know how to convert back - please help
Here is my MWE Para
type
using Parameters
@with_kw struct Para{T}
a::T = 1.0
b::T = 2.0
c::T = 3.0
end
with three parameters (a
, b
, and c
). Some examples of concrete Para
s:
julia> p1 = Para()
Para{Float64}
a: Float64 1.0
b: Float64 2.0
c: Float64 3.0
julia> p2 = Para(a = 4.0, c = 5.0)
Para{Float64}
a: Float64 4.0
b: Float64 2.0
c: Float64 5.0
Note that the Para
constructor nicely works by supplying it assignments (like a = 4.0
- Thanks to Parameters.jl
! ).
I want to optimize only a
and b
. For that, I want to create a vector of the values in a
and b
for a given Para
. So I create a tuple of the symbol names
optimizable_Para = (:a, :b)
which lists the “optimizable” parameters. To create the vector of the optimizable parameters, I have the function
function convert_Para_to_Vector(p::Para)
[getfield(p, s) for s in optimizable_Para]
end
Some examples of conversion from Para
to Vector
:
julia> x1 = convert_Para_to_Vector(p1)
2-element Array{Float64,1}:
1.0
2.0
julia> x2 = convert_Para_to_Vector(p2)
2-element Array{Float64,1}:
4.0
2.0
Now I want to do the opposite, i.e., create a Para
from a Vector
(and assign the default values to the parameters not listed in optimizable_Para
, the non-optimizable parameters).
Thus I am looking for a function convert_Vector_to_Para
that achieves
function convert_Vector_to_Para(x)
Para(a = x[1], b = x[2])
end
But, instead of explicitly writing the assignments (a = x[1], b = x[2]
), I would like to use the symbols in oPara
. So that if I change oPara
in the future, I don’t have to rewrite convert_Vector_to_Para
. I have not been able to figure how to do that so far… Please help?
My guess is I need a macro, but the closest I have been is via a function which does not work:
function convert_Vector_to_Para(x)
eval(Expr(:call, :Para, [Expr(:(=), oPara[i], x[i]) for i in 1:length(optimizable_Para)]...))
end