I thought I’d ask some questions about the Parameters
package here because hopefully the answers will be useful to others. (Maybe some answers actually will make their way to the Parameters
package documentation?)
Ok, so I work best by example, so here we go, let’s build a Para
type and a parameter container p
:
using Parameters
@with_kw struct Para
a = 1.0
b = 3.0 + im
end
p = Para()
I put two default values of different types in here. Well first thing I want is to have an eltype
function for this type, which promotes the type of every parameter (in other words here, I want eltype(p)
to be the promotion of the types of a
and b
). Just below is my current version of overloading eltype
to do that (please let me know how this could be done better):
function Base.:eltype(p::Para)
ot = Int # Starting somewhere
pnames = fieldnames(typeof(p))
for pname in pnames
ot = promote_type(ot, typeof(getfield(p, pname)))
end
return ot
end
eltype(p)
Then I want to convert p
to a vector and back. To convert it to a vector x
, I do the following (again, this works but I am not sure this is the correct way):
function para2vec(p::Para)
pnames = fieldnames(typeof(p))
np = length(pnames)
x = zeros(eltype(p), np)
for ix in 1:np
x[ix] = getfield(p, pnames[ix])
end
return x
end
x = para2vec(p)
Now the hard part for me is to convert x
into p
. Could someone jump in and help with that? I am guessing I could use the @pack
macro but I haven’t figured out how yet…
EDIT #1
Converting x
into p
is in fact just as simple as
p2 = Para(x...)
EDIT #2
Now I would like to write derivatives of a function f(u, p::Para)
w.r.t. p
. (u
is a vector of element-type :<Number
.) Right now I do it by hand, i.e., I write
function Dpf(u, p::Para)
@unpack a, b = p
Daf = # derivative of `f` w.r.t `a`
Dbf = # derivative of `f` w.r.t `b`
return [Daf Dbf]
end
But I am sure there is a better approach, something with more abstraction. I thought of creating a type for those derivatives, i.e. a container like
struct DerivativeWRTPara
Daf
Dbf
end
That would contain the same number of fields as the Para
type (so that there is an “automatic” correspondence between the types). I’m a bit afraid of exploring this avenue: is this stupid?