From 1431f9013b0228141f3ab557faaf17176a0bc3ad Mon Sep 17 00:00:00 2001 From: Benjamin Chung Date: Tue, 12 Nov 2024 16:44:06 -0800 Subject: [PATCH 1/4] Document build_explicit_observed_function and allow user-defined array construction --- src/systems/diffeqs/odesystem.jl | 33 ++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/systems/diffeqs/odesystem.jl b/src/systems/diffeqs/odesystem.jl index 29423baf5e..ba3a4977ba 100644 --- a/src/systems/diffeqs/odesystem.jl +++ b/src/systems/diffeqs/odesystem.jl @@ -411,8 +411,32 @@ ODESystem(eq::Equation, args...; kwargs...) = ODESystem([eq], args...; kwargs... """ $(SIGNATURES) -Build the observed function assuming the observed equations are all explicit, -i.e. there are no cycles. +Generates a function that computes the observed value(s) `ts` in the system `sys` assuming that there are no cycles in the equations. + +The return value will be either: +* a single function if the input is a scalar or if the input is a Vector but `return_inplace` is false +* the out of place and in-place functions `(ip, oop)` if `return_inplace` is true and the input is a `Vector` + +The function(s) will be: +* `RuntimeGeneratedFunction`s by default, +* A Julia `Expr` if `expression` is true, +* A directly evaluated Julia function in the module `eval_module` if `eval_expression` is true + +The signatures will be of the form `g(...)` with arguments: +* `output` for in-place functions +* `unknowns` if `params_only` is `false` +* `inputs` if `inputs` is an array of symbolic inputs that should be available in `ts` +* `p...` unconditionally; note that in the case of `MTKParameters` more than one parameters argument may be present, so it must be splatted +* `t` if the system is time-dependent; for example `NonlinearSystem` will not have `t` +For example, a function `g(op, unknowns, p, inputs, t)` will be the in-place function generated if `return_inplace` is true, `ts` is a vector, an array of inputs `inputs` is given, and `params_only` is false for a time-dependent system. + +Options not otherwise specified are: +* `output_type = Array` the type of the array generated by the out-of-place vector-valued function +* `checkbounds = true` checks bounds if true when destructuring parameters +* `op = Operator` sets the recursion terminator for the walk done by `vars` to identify the variables that appear in `ts`. See the documentation for `vars` for more detail. +* `throw = true` if true, throw an error when generating a function for `ts` that reference variables that do not exist +* `drop_expr` is deprecated. +* `mkarray`; only used if the output is an array (that is, `!isscalar(ts)`). Called as `mkarray(ts, output_type)` where `ts` are the expressions to put in the array and `output_type` is the argument of the same name passed to build_explicit_observed_function. """ function build_explicit_observed_function(sys, ts; inputs = nothing, @@ -426,7 +450,8 @@ function build_explicit_observed_function(sys, ts; return_inplace = false, param_only = false, op = Operator, - throw = true) + throw = true, + mkarray = MakeArray) is_tuple = ts isa Tuple if is_tuple ts = collect(ts) @@ -582,7 +607,7 @@ function build_explicit_observed_function(sys, ts; elseif is_tuple MakeTuple(Tuple(ts)) else - MakeArray(ts, output_type) + mkarray(ts, output_type) end oop_fn = Func(args, [], pre(Let(obsexprs, From dbf06cd421c29ce21185df2cd1668952cb88fc96 Mon Sep 17 00:00:00 2001 From: Benjamin Chung Date: Thu, 14 Nov 2024 17:17:11 -0800 Subject: [PATCH 2/4] Remove deprecated argument to build_explicit_observed_function --- src/systems/diffeqs/odesystem.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/systems/diffeqs/odesystem.jl b/src/systems/diffeqs/odesystem.jl index ba3a4977ba..1f333b5e91 100644 --- a/src/systems/diffeqs/odesystem.jl +++ b/src/systems/diffeqs/odesystem.jl @@ -445,8 +445,7 @@ function build_explicit_observed_function(sys, ts; eval_module = @__MODULE__, output_type = Array, checkbounds = true, - drop_expr = drop_expr, - ps = parameters(sys), + ps = parameters(sys), return_inplace = false, param_only = false, op = Operator, From 7b73213151436cb3c02f687a4c9d35eaaba9fa7f Mon Sep 17 00:00:00 2001 From: Benjamin Chung Date: Thu, 14 Nov 2024 17:17:29 -0800 Subject: [PATCH 3/4] Reformat docstring --- src/systems/diffeqs/odesystem.jl | 58 ++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 22 deletions(-) diff --git a/src/systems/diffeqs/odesystem.jl b/src/systems/diffeqs/odesystem.jl index 1f333b5e91..b60220aeea 100644 --- a/src/systems/diffeqs/odesystem.jl +++ b/src/systems/diffeqs/odesystem.jl @@ -409,34 +409,48 @@ end ODESystem(eq::Equation, args...; kwargs...) = ODESystem([eq], args...; kwargs...) """ -$(SIGNATURES) + build_explicit_observed_function(sys, ts; kwargs...) -> Function(s) + +Generates a function that computes the observed value(s) `ts` in the system `sys`, while making the assumption that there are no cycles in the equations. + +## Arguments +- `sys`: The system for which to generate the function +- `ts`: The symbolic observed values whose value should be computed + +## Keywords +- `return_inplace = false`: If true and the observed value is a vector, then return both the in place and out of place methods. +- `expression = false`: Generates a Julia `Expr`` computing the observed value if `expression` is true +- `eval_expression = false`: If true and `expression = false`, evaluates the returned function in the module `eval_module` +- `output_type = Array` the type of the array generated by a out-of-place vector-valued function +- `param_only = false` if true, only allow the generated function to access system parameters +- `inputs = nothing` additinoal symbolic variables that should be provided to the generated function +- `checkbounds = true` checks bounds if true when destructuring parameters +- `op = Operator` sets the recursion terminator for the walk done by `vars` to identify the variables that appear in `ts`. See the documentation for `vars` for more detail. +- `throw = true` if true, throw an error when generating a function for `ts` that reference variables that do not exist. +- `mkarray`; only used if the output is an array (that is, `!isscalar(ts)`). Called as `mkarray(ts, output_type)` where `ts` are the expressions to put in +the array and `output_type` is the argument of the same name passed to build_explicit_observed_function. + +## Returns -Generates a function that computes the observed value(s) `ts` in the system `sys` assuming that there are no cycles in the equations. - The return value will be either: -* a single function if the input is a scalar or if the input is a Vector but `return_inplace` is false -* the out of place and in-place functions `(ip, oop)` if `return_inplace` is true and the input is a `Vector` +* a single function `f_oop` if the input is a scalar or if the input is a Vector but `return_inplace` is false +* the out of place and in-place functions `(f_ip, f_oop)` if `return_inplace` is true and the input is a `Vector` -The function(s) will be: +The function(s) `f_oop` (and potentially `f_ip`) will be: * `RuntimeGeneratedFunction`s by default, * A Julia `Expr` if `expression` is true, -* A directly evaluated Julia function in the module `eval_module` if `eval_expression` is true +* A directly evaluated Julia function in the module `eval_module` if `eval_expression` is true and `expression` is false. The signatures will be of the form `g(...)` with arguments: -* `output` for in-place functions -* `unknowns` if `params_only` is `false` -* `inputs` if `inputs` is an array of symbolic inputs that should be available in `ts` -* `p...` unconditionally; note that in the case of `MTKParameters` more than one parameters argument may be present, so it must be splatted -* `t` if the system is time-dependent; for example `NonlinearSystem` will not have `t` -For example, a function `g(op, unknowns, p, inputs, t)` will be the in-place function generated if `return_inplace` is true, `ts` is a vector, an array of inputs `inputs` is given, and `params_only` is false for a time-dependent system. - -Options not otherwise specified are: -* `output_type = Array` the type of the array generated by the out-of-place vector-valued function -* `checkbounds = true` checks bounds if true when destructuring parameters -* `op = Operator` sets the recursion terminator for the walk done by `vars` to identify the variables that appear in `ts`. See the documentation for `vars` for more detail. -* `throw = true` if true, throw an error when generating a function for `ts` that reference variables that do not exist -* `drop_expr` is deprecated. -* `mkarray`; only used if the output is an array (that is, `!isscalar(ts)`). Called as `mkarray(ts, output_type)` where `ts` are the expressions to put in the array and `output_type` is the argument of the same name passed to build_explicit_observed_function. + +- `output` for in-place functions +- `unknowns` if `param_only` is `false` +- `inputs` if `inputs` is an array of symbolic inputs that should be available in `ts` +- `p...` unconditionally; note that in the case of `MTKParameters` more than one parameters argument may be present, so it must be splatted +- `t` if the system is time-dependent; for example `NonlinearSystem` will not have `t` + +For example, a function `g(op, unknowns, p..., inputs, t)` will be the in-place function generated if `return_inplace` is true, `ts` is a vector, +an array of inputs `inputs` is given, and `param_only` is false for a time-dependent system. """ function build_explicit_observed_function(sys, ts; inputs = nothing, @@ -445,7 +459,7 @@ function build_explicit_observed_function(sys, ts; eval_module = @__MODULE__, output_type = Array, checkbounds = true, - ps = parameters(sys), + ps = parameters(sys), return_inplace = false, param_only = false, op = Operator, From 14996d7db8065c3716e8ad54333bbe5cbbf7af45 Mon Sep 17 00:00:00 2001 From: Benjamin Chung Date: Thu, 14 Nov 2024 17:59:02 -0800 Subject: [PATCH 4/4] Fix docstring to account for tuples --- src/systems/diffeqs/odesystem.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/systems/diffeqs/odesystem.jl b/src/systems/diffeqs/odesystem.jl index b60220aeea..5ad275906d 100644 --- a/src/systems/diffeqs/odesystem.jl +++ b/src/systems/diffeqs/odesystem.jl @@ -427,7 +427,7 @@ Generates a function that computes the observed value(s) `ts` in the system `sys - `checkbounds = true` checks bounds if true when destructuring parameters - `op = Operator` sets the recursion terminator for the walk done by `vars` to identify the variables that appear in `ts`. See the documentation for `vars` for more detail. - `throw = true` if true, throw an error when generating a function for `ts` that reference variables that do not exist. -- `mkarray`; only used if the output is an array (that is, `!isscalar(ts)`). Called as `mkarray(ts, output_type)` where `ts` are the expressions to put in +- `mkarray`; only used if the output is an array (that is, `!isscalar(ts)` and `ts` is not a tuple, in which case the result will always be a tuple). Called as `mkarray(ts, output_type)` where `ts` are the expressions to put in the array and `output_type` is the argument of the same name passed to build_explicit_observed_function. ## Returns