|
2 | 2 | parameter_values(p) |
3 | 3 |
|
4 | 4 | Return an indexable collection containing the value of each parameter in `p`. |
| 5 | +
|
| 6 | +If this function is called with an `AbstractArray`, it will return the same array. |
5 | 7 | """ |
6 | 8 | function parameter_values end |
7 | 9 |
|
| 10 | +parameter_values(arr::AbstractArray) = arr |
| 11 | + |
8 | 12 | """ |
9 | 13 | set_parameter!(sys, val, idx) |
10 | 14 |
|
|
22 | 26 | """ |
23 | 27 | getp(sys, p) |
24 | 28 |
|
25 | | -Return a function that takes an integrator or solution of `sys`, and returns the value of |
26 | | -the parameter `p`. Note that `p` can be a direct numerical index or a symbolic value. |
| 29 | +Return a function that takes an array representing the parameter vector or an integrator |
| 30 | +or solution of `sys`, and returns the value of the parameter `p`. Note that `p` can be a |
| 31 | +direct numerical index or a symbolic value, or an array/tuple of the aforementioned. |
| 32 | +
|
27 | 33 | Requires that the integrator or solution implement [`parameter_values`](@ref). This function |
28 | 34 | typically does not need to be implemented, and has a default implementation relying on |
29 | 35 | [`parameter_values`](@ref). |
30 | 36 | """ |
31 | 37 | function getp(sys, p) |
32 | 38 | symtype = symbolic_type(p) |
33 | 39 | elsymtype = symbolic_type(eltype(p)) |
34 | | - if symtype != NotSymbolic() |
35 | | - return _getp(sys, symtype, p) |
36 | | - else |
37 | | - return _getp(sys, elsymtype, p) |
38 | | - end |
| 40 | + _getp(sys, symtype, elsymtype, p) |
39 | 41 | end |
40 | 42 |
|
41 | | -function _getp(sys, ::NotSymbolic, p) |
| 43 | +function _getp(sys, ::NotSymbolic, ::NotSymbolic, p) |
42 | 44 | return function getter(sol) |
43 | 45 | return parameter_values(sol)[p] |
44 | 46 | end |
45 | 47 | end |
46 | 48 |
|
47 | | -function _getp(sys, ::ScalarSymbolic, p) |
| 49 | +function _getp(sys, ::ScalarSymbolic, ::SymbolicTypeTrait, p) |
48 | 50 | idx = parameter_index(sys, p) |
49 | 51 | return function getter(sol) |
50 | 52 | return parameter_values(sol)[idx] |
51 | 53 | end |
52 | 54 | end |
53 | 55 |
|
54 | | -function _getp(sys, ::ScalarSymbolic, p::Union{Tuple, AbstractArray}) |
55 | | - idxs = parameter_index.((sys,), p) |
56 | | - return function getter(sol) |
57 | | - return getindex.((parameter_values(sol),), idxs) |
| 56 | +for (t1, t2) in [ |
| 57 | + (ArraySymbolic, Any), |
| 58 | + (ScalarSymbolic, Any), |
| 59 | + (NotSymbolic, Union{<:Tuple, <:AbstractArray}), |
| 60 | +] |
| 61 | + @eval function _getp(sys, ::NotSymbolic, ::$t1, p::$t2) |
| 62 | + getters = getp.((sys,), p) |
| 63 | + |
| 64 | + return function getter(sol) |
| 65 | + map(g -> g(sol), getters) |
| 66 | + end |
58 | 67 | end |
59 | 68 | end |
60 | 69 |
|
61 | | -function _getp(sys, ::ArraySymbolic, p) |
| 70 | +function _getp(sys, ::ArraySymbolic, ::NotSymbolic, p) |
62 | 71 | return getp(sys, collect(p)) |
63 | 72 | end |
64 | 73 |
|
65 | 74 | """ |
66 | 75 | setp(sys, p) |
67 | 76 |
|
68 | | -Return a function that takes an integrator of `sys` and a value, and sets |
69 | | -the parameter `p` to that value. Note that `p` can be a direct numerical index or a |
70 | | -symbolic value. Requires that the integrator implement [`parameter_values`](@ref) and the |
71 | | -returned collection be a mutable reference to the parameter vector in the integrator. In |
| 77 | +Return a function that takes an array representing the parameter vector or an integrator |
| 78 | +or problem of `sys`, and a value, and sets the parameter `p` to that value. Note that `p` |
| 79 | +can be a direct numerical index or a symbolic value. |
| 80 | +
|
| 81 | +Requires that the integrator implement [`parameter_values`](@ref) and the returned |
| 82 | +collection be a mutable reference to the parameter vector in the integrator. In |
72 | 83 | case `parameter_values` cannot return such a mutable reference, or additional actions |
73 | 84 | need to be performed when updating parameters, [`set_parameter!`](@ref) must be |
74 | 85 | implemented. |
75 | 86 | """ |
76 | 87 | function setp(sys, p) |
77 | 88 | symtype = symbolic_type(p) |
78 | 89 | elsymtype = symbolic_type(eltype(p)) |
79 | | - if symtype != NotSymbolic() |
80 | | - return _setp(sys, symtype, p) |
81 | | - else |
82 | | - return _setp(sys, elsymtype, p) |
83 | | - end |
| 90 | + _setp(sys, symtype, elsymtype, p) |
84 | 91 | end |
85 | 92 |
|
86 | | -function _setp(sys, ::NotSymbolic, p) |
| 93 | +function _setp(sys, ::NotSymbolic, ::NotSymbolic, p) |
87 | 94 | return function setter!(sol, val) |
88 | 95 | set_parameter!(sol, val, p) |
89 | 96 | end |
90 | 97 | end |
91 | 98 |
|
92 | | -function _setp(sys, ::ScalarSymbolic, p) |
| 99 | +function _setp(sys, ::ScalarSymbolic, ::SymbolicTypeTrait, p) |
93 | 100 | idx = parameter_index(sys, p) |
94 | 101 | return function setter!(sol, val) |
95 | 102 | set_parameter!(sol, val, idx) |
96 | 103 | end |
97 | 104 | end |
98 | 105 |
|
99 | | -function _setp(sys, ::ScalarSymbolic, p::Union{Tuple, AbstractArray}) |
100 | | - idxs = parameter_index.((sys,), p) |
101 | | - return function setter!(sol, val) |
102 | | - set_parameter!.((sol,), val, idxs) |
| 106 | +for (t1, t2) in [ |
| 107 | + (ArraySymbolic, Any), |
| 108 | + (ScalarSymbolic, Any), |
| 109 | + (NotSymbolic, Union{<:Tuple, <:AbstractArray}), |
| 110 | +] |
| 111 | + @eval function _setp(sys, ::NotSymbolic, ::$t1, p::$t2) |
| 112 | + setters = setp.((sys,), p) |
| 113 | + return function setter!(sol, val) |
| 114 | + map((s!, v) -> s!(sol, v), setters, val) |
| 115 | + end |
103 | 116 | end |
104 | 117 | end |
105 | 118 |
|
106 | | -function _setp(sys, ::ArraySymbolic, p) |
| 119 | +function _setp(sys, ::ArraySymbolic, ::NotSymbolic, p) |
107 | 120 | return setp(sys, collect(p)) |
108 | 121 | end |
0 commit comments