You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- The standard call `(p::TypeName)(t,u,du)` must be overloaded for the function
221
-
calculation. All other functions are optional.
222
-
223
-
Solvers can interface with ParameterizedFunctions as follows:
224
-
225
-
```julia
226
-
f.a # accesses the parameter a
227
-
f(t,u,du) # Call the function
228
-
f(t,u,params,du) # Call the function to calculate with parameters params (vector)
229
-
f(Val{:tgrad},t,u,J) # Call the explicit t-gradient function
230
-
f(Val{:a},t,u,2.0,du) # Call the explicit parameter function with a=2.0
231
-
f(Val{:deriv},Val{:a},t,u,2.0,df) # Call the explicit parameter derivative function with a=2.0
232
-
f(Val{:paramjac},t,u,params,J) # Call the explicit parameter Jacobian function
233
-
f(Val{:jac},t,u,J) # Call the explicit Jacobian function
234
-
f(Val{:expjac},t,u,γ,J) # Call the explicit exponential Jacobian function exp(γJ)
235
-
f(Val{:invjac},t,u,iJ) # Call the explicit Inverse Jacobian function
236
-
f(Val{:invW},t,u,γ,iW) # Call the explicit inverse Rosenbrock-W function (M - γJ)^(-1)
237
-
f(Val{:invW_t},t,u,γ,iW) # Call the explicit transformed inverse Rosenbrock-W function (M/γ - J)^(-1)
238
-
f(Val{:hes},t,u,H) # Call the explicit Hessian function
239
-
f(Val{:invhes},t,u,iH) # Call the explicit Inverse Hessian function
240
-
```
241
-
242
-
To test for whether certain overloads exist, the following functions are provided
243
-
by traits in [DiffEqBase.jl](https://github.com/JuliaDiffEq/DiffEqBase.jl):
244
-
245
-
```julia
246
-
has_jac(f)
247
-
has_expjac(f)
248
-
has_invjac(f)
249
-
has_tgrad(f)
250
-
has_hes(f)
251
-
has_invhes(f)
252
-
has_invW(f)
253
-
has_invW_t(f)
254
-
has_paramjac(f)
255
-
has_paramderiv(f)
256
-
```
257
-
258
-
These are compile-time checks and thus the inappropriate branches will compile
259
-
way when a function (usually an ODE/SDE solver) is dispatched on `f`. It is
260
-
requested that solvers should only use the explicit functions when they exist
261
-
to help with performance.
262
-
263
-
In addition, the following functions are provided:
264
-
265
-
-`param_values(f)` : Returns an array of the values for each of the parameters
266
-
-`num_params(f)` : Returns the number of parameters for `f`
267
-
268
-
## Internals: How it Works
269
-
270
-
This shows how to manually build a ParameterizedFunction to give to
271
-
a solver.
272
-
273
-
### Template
274
-
275
-
An example of explicitly defining a parameterized function is as follows. This serves
276
-
as a general template for doing so:
277
-
278
-
```julia
279
-
type LotkaVolterra <:AbstractParameterizedFunction{true}
280
-
a::Float64
281
-
b::Float64
282
-
end
283
-
f =LotkaVolterra(0.0,0.0)
284
-
(p::LotkaVolterra)(t,u,du) =begin
285
-
du[1] = p.a * u[1] - p.b * u[1]*u[2]
286
-
du[2] =-3* u[2] + u[1]*u[2]
287
-
end
288
-
```
289
-
290
-
### Explanation
291
-
292
-
Let's go step by step to see what this template does. The first part defines a
293
-
type:
294
-
295
-
```julia
296
-
type LotkaVolterra <:AbstractParameterizedFunction{true}
297
-
a::Float64
298
-
b::Float64
299
-
end
300
-
```
301
-
302
-
The fields are the parameters for our function. The abstract type is parameterized by whether the function is written in-place or not. Then we built the type:
303
-
304
-
```julia
305
-
f =LotkaVolterra(0.0,0.0)
306
-
```
307
-
308
-
We put in values for the parameters and told it that we will be defining each of
309
-
those functions. First we define the main overload. This is required even if none
310
-
of the other functions are provided. The function for the main overload is the
311
-
differential equation, so for the Lotka-Volterra equation:
312
-
313
-
```julia
314
-
(p::LotkaVolterra)(t,u,du) =begin
315
-
du[1] = p.a * u[1] - p.b * u[1]*u[2]
316
-
du[2] =-3* u[2] + u[1]*u[2]
317
-
end
318
-
```
319
-
320
-
Note how we represented the parameters in the equation. If you did this and set
321
-
the booleans to false, the result is `f` is a `ParameterizedFunction`,
322
-
but `f(t,u,du)` acts like the function:
323
-
324
-
```julia
325
-
functionf(t,u,du)
326
-
du[1] =0.0* u[1] -0.0* u[1]*u[2]
327
-
du[2] =-3* u[2] + u[1]*u[2]
328
-
end
329
-
```
330
-
331
-
At anytime the function parameters can be accessed by the fields (`f.a`, `f.b`).
332
-
333
108
### Extra Functions
334
109
335
110
#### Jacobian Function
@@ -360,43 +135,22 @@ function (p::LotkaVolterra)(::Type{Val{:invjac}},t,u,J)
360
135
end
361
136
```
362
137
363
-
#### Hessian and Inverse Hessian
364
-
365
-
These are the same as the Jacobians, except with value types `:hes` and `:invhes`.
366
-
367
-
#### Explicit Parameter Functions
368
-
369
-
For solvers which need to auto-differentiate parameters (local sensitivity analysis),
370
-
explicit parameter functions are required. For our example, we do the following:
371
-
372
-
```julia
373
-
function (p::LotkaVolterra)(::Type{Val{:a}},t,u,a,du)
374
-
du[1] = a * u[1] - p.b * u[1] * u[2]
375
-
du[2] =-3* u[2] +1* u[1] * u[2]
376
-
nothing
377
-
end
378
-
function (p::LotkaVolterra)(::Type{Val{:b}},t,u,b,du)
379
-
du[1] = p.a * u[1] - b * u[1] * u[2]
380
-
du[2] =-3* u[2] +1* u[1] * u[2]
381
-
nothing
382
-
end
383
-
```
384
-
385
-
#### Explicit Parameter Derivatives
138
+
#### Parameter Jacobian
386
139
387
140
For solvers which need parameters derivatives, specifying the functions can increase
388
141
performance. For our example, we allow the solvers to use the explicit derivatives
389
-
in the parameters `a` and `b` by:
390
-
391
-
```julia
392
-
function (p::LotkaVolterra)(::Type{Val{:deriv}},::Type{Val{:a}},t,u,a,du)
393
-
du[1] =1* u[1]
394
-
du[2] =1*0
395
-
nothing
396
-
end
397
-
function (p::LotkaVolterra)(::Type{Val{:deriv}},::Type{Val{:b}},t,u,b,du)
398
-
du[1] =-(u[1]) * u[2]
399
-
du[2] =1*0
400
-
nothing
142
+
in the parameters by:
143
+
144
+
```julia
145
+
function (p::LotkaVolterra)(::Type{Val{:paramjac}},J,u,p,t)
0 commit comments