From 6f8cfcc44be979d3c7525c26bc9fcaa858ad3a3c Mon Sep 17 00:00:00 2001 From: Chris Rackauckas Date: Thu, 11 Apr 2019 15:46:01 -0400 Subject: [PATCH 1/5] simplified interface for declaring parameters --- README.md | 16 +++++++++------- src/variables.jl | 13 ++++++++++--- test/derivatives.jl | 2 +- test/simplify.jl | 2 +- test/system_construction.jl | 10 +++++----- test/variable_parsing.jl | 9 +++++---- 6 files changed, 31 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 258123d3a9..55350b133a 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ and parameters. Therefore we label them as follows: using ModelingToolkit # Define some variables -@parameters t() σ() ρ() β() +@parameters t σ ρ β @variables x(t) y(t) z(t) @derivatives D'~t ``` @@ -80,8 +80,8 @@ state of the previous ODE. This is the nonlinear system defined by where the derivatives are zero. We use (unknown) variables for our nonlinear system. ```julia -@variables x() y() z() -@parameters σ() ρ() β() +@variables x y z +@parameters σ ρ β # Define a nonlinear system eqs = [0 ~ σ*(y-x), @@ -166,12 +166,14 @@ including and excluding empty parentheses. When in call format, variables are aliased to the given call, allowing implicit use of dependents for convenience. ```julia -@parameters t() α() σ +@dependent_parameters t() α() σ @variables w x(t) y() z(t, α, x) expr = x + y^α + σ(3) * (z - t) - w(t - 1) ``` +`@parameters` is a simplified tool for defining constant parameters, meaning +`@parameters t` is the same as `@dependent_parameters t()` ### Constants @@ -274,7 +276,7 @@ is accessible via a function-based interface. This means that all macros are syntactic sugar in some form. For example, the variable construction: ```julia -@parameters t() σ ρ() β() +@parameters t σ ρ β @variables x(t) y(t) z(t) @derivatives D'~t ``` @@ -297,8 +299,8 @@ D = Differential(t) The system building functions can handle intermediate calculations. For example, ```julia -@variables x() y() z() -@parameters σ() ρ() β() +@variables x y z +@parameters σ ρ β a = y - x eqs = [0 ~ σ*a, 0 ~ x*(ρ-z)-y, diff --git a/src/variables.jl b/src/variables.jl index c1f773dbcc..c6ad07f248 100644 --- a/src/variables.jl +++ b/src/variables.jl @@ -1,4 +1,4 @@ -export Variable, @variables, @parameters +export Variable, @variables, @parameters, @dependent_parameters struct Variable <: Function @@ -29,7 +29,7 @@ Base.convert(::Type{Expr}, c::Constant) = c.value # Build variables more easily -function _parse_vars(macroname, known, x) +function _parse_vars(macroname, known, x, add_call = true) ex = Expr(:block) var_names = Symbol[] # if parsing things in the form of @@ -50,7 +50,11 @@ function _parse_vars(macroname, known, x) expr = :($var_name = $Variable($(Meta.quot(var_name)); known = $known)($(_var.args[2:end]...))) else var_name = _var - expr = :($var_name = $Variable($(Meta.quot(var_name)); known = $known)) + if add_call + expr = :($var_name = $Variable($(Meta.quot(var_name)); known = $known)()) + else + expr = :($var_name = $Variable($(Meta.quot(var_name)); known = $known)) + end end push!(var_names, var_name) @@ -65,3 +69,6 @@ end macro parameters(xs...) esc(_parse_vars(:parameters, true, xs)) end +macro dependent_parameters(xs...) + esc(_parse_vars(:parameters, true, xs, false)) +end diff --git a/test/derivatives.jl b/test/derivatives.jl index 1569420da6..194184fca1 100644 --- a/test/derivatives.jl +++ b/test/derivatives.jl @@ -2,7 +2,7 @@ using ModelingToolkit using Test # Derivatives -@parameters t() σ() ρ() β() +@parameters t σ ρ β @variables x(t) y(t) z(t) @derivatives D'~t D2''~t Dx'~x diff --git a/test/simplify.jl b/test/simplify.jl index 0f723fa1ce..be6c1554df 100644 --- a/test/simplify.jl +++ b/test/simplify.jl @@ -1,7 +1,7 @@ using ModelingToolkit using Test -@parameters t() +@parameters t @variables x(t) y(t) z(t) null_op = 0*t diff --git a/test/system_construction.jl b/test/system_construction.jl index 2126a2b5b2..88f27e9e98 100644 --- a/test/system_construction.jl +++ b/test/system_construction.jl @@ -2,7 +2,7 @@ using ModelingToolkit using Test # Define some variables -@parameters t() σ() ρ() β() +@parameters t σ ρ β @variables x(t) y(t) z(t) @derivatives D'~t @@ -60,7 +60,7 @@ fwt(FW, u, p, 0.2, 0.1) du ≈ [11, -3, -7] end - @parameters σ + @dependent_parameters σ eqs = [D(x) ~ σ(t-1)*(y-x), D(y) ~ x*(ρ-z)-y, D(z) ~ x*y - β*z] @@ -127,7 +127,7 @@ test_nlsys_inference("standard", ns, (x, y, z), (σ, ρ, β)) end @derivatives D'~t -@parameters A() B() C() +@parameters A B C _x = y / C eqs = [D(x) ~ -A*x, D(y) ~ A*x - B*_x] @@ -140,8 +140,8 @@ de = ODESystem(eqs) end # Now nonlinear system with only variables -@variables x() y() z() -@parameters σ() ρ() β() +@variables x y z +@parameters σ ρ β # Define a nonlinear system eqs = [0 ~ σ*(y-x), diff --git a/test/variable_parsing.jl b/test/variable_parsing.jl index 2b51bbd68b..8a2af68f5d 100644 --- a/test/variable_parsing.jl +++ b/test/variable_parsing.jl @@ -1,7 +1,7 @@ using ModelingToolkit using Test -@parameters t() +@parameters t @variables x(t) y(t) # test multi-arg @variables z(t) # test single-arg x1 = Variable(:x)(t) @@ -12,10 +12,11 @@ z1 = Variable(:z)(t) @test isequal(z1, z) @parameters begin - t() - s() - σ + t + s end +@dependent_parameters σ + t1 = Variable(:t; known = true)() s1 = Variable(:s; known = true)() σ1 = Variable(:σ; known = true) From 006e459c5560d779f971d65890356a7c6b787779 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Sat, 13 Apr 2019 07:13:06 -0400 Subject: [PATCH 2/5] change to implicit () + (..) for uncalled --- README.md | 10 ++++++---- src/variables.jl | 18 ++++++++---------- test/system_construction.jl | 2 +- test/variable_parsing.jl | 2 +- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 55350b133a..87bc964518 100644 --- a/README.md +++ b/README.md @@ -166,14 +166,16 @@ including and excluding empty parentheses. When in call format, variables are aliased to the given call, allowing implicit use of dependents for convenience. ```julia -@dependent_parameters t() α() σ -@variables w x(t) y() z(t, α, x) +@parameters t α σ(..) +@variables w(..) x(t) y() z(t, α, x) expr = x + y^α + σ(3) * (z - t) - w(t - 1) ``` -`@parameters` is a simplified tool for defining constant parameters, meaning -`@parameters t` is the same as `@dependent_parameters t()` +Note that `@parameters` and `@variables` implicitly add `()` to values that +are not given a call. The former specifies the values as known, while the +latter specifies it as unknown. `(..)` signifies that the value should be +left uncalled. ### Constants diff --git a/src/variables.jl b/src/variables.jl index c6ad07f248..a8bb1fef1c 100644 --- a/src/variables.jl +++ b/src/variables.jl @@ -29,7 +29,7 @@ Base.convert(::Type{Expr}, c::Constant) = c.value # Build variables more easily -function _parse_vars(macroname, known, x, add_call = true) +function _parse_vars(macroname, known, x) ex = Expr(:block) var_names = Symbol[] # if parsing things in the form of @@ -47,14 +47,15 @@ function _parse_vars(macroname, known, x, add_call = true) if iscall var_name = _var.args[1] - expr = :($var_name = $Variable($(Meta.quot(var_name)); known = $known)($(_var.args[2:end]...))) - else - var_name = _var - if add_call - expr = :($var_name = $Variable($(Meta.quot(var_name)); known = $known)()) - else + if _var.args[end] == :.. expr = :($var_name = $Variable($(Meta.quot(var_name)); known = $known)) + else + expr = :($var_name = $Variable($(Meta.quot(var_name)); known = $known)($(_var.args[2:end]...))) end + else + # Implicit 0-args call + var_name = _var + expr = :($var_name = $Variable($(Meta.quot(var_name)); known = $known)()) end push!(var_names, var_name) @@ -69,6 +70,3 @@ end macro parameters(xs...) esc(_parse_vars(:parameters, true, xs)) end -macro dependent_parameters(xs...) - esc(_parse_vars(:parameters, true, xs, false)) -end diff --git a/test/system_construction.jl b/test/system_construction.jl index 88f27e9e98..5b550393f4 100644 --- a/test/system_construction.jl +++ b/test/system_construction.jl @@ -60,7 +60,7 @@ fwt(FW, u, p, 0.2, 0.1) du ≈ [11, -3, -7] end - @dependent_parameters σ + @parameters σ(..) eqs = [D(x) ~ σ(t-1)*(y-x), D(y) ~ x*(ρ-z)-y, D(z) ~ x*y - β*z] diff --git a/test/variable_parsing.jl b/test/variable_parsing.jl index 8a2af68f5d..d406bdd5a8 100644 --- a/test/variable_parsing.jl +++ b/test/variable_parsing.jl @@ -15,7 +15,7 @@ z1 = Variable(:z)(t) t s end -@dependent_parameters σ +@parameters σ(..) t1 = Variable(:t; known = true)() s1 = Variable(:s; known = true)() From 30931ca830cab18e0208723a45812296630fc5bf Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Sat, 13 Apr 2019 08:06:04 -0400 Subject: [PATCH 3/5] add parameter call finding helper --- src/ModelingToolkit.jl | 1 + src/equations.jl | 11 +++++++++++ src/variables.jl | 2 +- test/find_parameter_calls.jl | 14 ++++++++++++++ test/runtests.jl | 1 + 5 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 test/find_parameter_calls.jl diff --git a/src/ModelingToolkit.jl b/src/ModelingToolkit.jl index e5cf37f202..bda7e36667 100644 --- a/src/ModelingToolkit.jl +++ b/src/ModelingToolkit.jl @@ -3,6 +3,7 @@ module ModelingToolkit export Operation, Expression export calculate_jacobian, generate_jacobian, generate_function export independent_variables, dependent_variables, parameters +export find_parameter_calls export @register diff --git a/src/equations.jl b/src/equations.jl index ffaa222021..cb107d1c43 100644 --- a/src/equations.jl +++ b/src/equations.jl @@ -10,3 +10,14 @@ Base.:(==)(a::Equation, b::Equation) = isequal((a.lhs, a.rhs), (b.lhs, b.rhs)) Base.:~(lhs::Expression, rhs::Expression) = Equation(lhs, rhs) Base.:~(lhs::Expression, rhs::Number ) = Equation(lhs, rhs) Base.:~(lhs::Number , rhs::Expression) = Equation(lhs, rhs) + +function find_parameter_calls(O::Operation,p_calls=Variable[]) + if O.op isa Variable && O.op.known && !isempty(O.args) + push!(p_calls,O.op) + find_parameter_calls.(O.args,(p_calls,)) + else + find_parameter_calls.(O.args,(p_calls,)) + end + p_calls +end +find_parameter_calls(O,p_calls) = nothing diff --git a/src/variables.jl b/src/variables.jl index a8bb1fef1c..2b9dfeced7 100644 --- a/src/variables.jl +++ b/src/variables.jl @@ -1,4 +1,4 @@ -export Variable, @variables, @parameters, @dependent_parameters +export Variable, @variables, @parameters struct Variable <: Function diff --git a/test/find_parameter_calls.jl b/test/find_parameter_calls.jl new file mode 100644 index 0000000000..b019ba398d --- /dev/null +++ b/test/find_parameter_calls.jl @@ -0,0 +1,14 @@ +using ModelingToolkit +using Test + +# Define some variables +@parameters t σ ρ β, α(..) +@variables x(t) y(t) z(t) +@derivatives D'~t + +eq1 = D(x) ~ σ*(y-x) +eq2 = D(x) ~ α(t-2)*(y-x) + +find_parameter_calls(eq1.rhs,Variable[]) +r = find_parameter_calls(eq2.rhs,Variable[]) +!isempty(r) && r[1].name == :α diff --git a/test/runtests.jl b/test/runtests.jl index 00a80ece02..a05ec6d922 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -3,4 +3,5 @@ using ModelingToolkit, Test @testset "Parsing Test" begin include("variable_parsing.jl") end @testset "Differentiation Test" begin include("derivatives.jl") end @testset "Simplify Test" begin include("simplify.jl") end +@testset "Parameter Call Finding Test" begin include("find_parameter_calls.jl") end @testset "System Construction Test" begin include("system_construction.jl") end From deca13258095253e1bb1eb6256c910893e296bb7 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Sat, 13 Apr 2019 08:43:52 -0400 Subject: [PATCH 4/5] fix test --- test/find_parameter_calls.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/find_parameter_calls.jl b/test/find_parameter_calls.jl index b019ba398d..e66aa649a5 100644 --- a/test/find_parameter_calls.jl +++ b/test/find_parameter_calls.jl @@ -2,7 +2,7 @@ using ModelingToolkit using Test # Define some variables -@parameters t σ ρ β, α(..) +@parameters t σ ρ β α(..) @variables x(t) y(t) z(t) @derivatives D'~t From 0a1b3c2d20c063567bcac90991190b646b0c5779 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Sat, 13 Apr 2019 11:55:47 -0400 Subject: [PATCH 5/5] remove parameter call finding --- src/ModelingToolkit.jl | 1 - src/equations.jl | 11 ----------- test/find_parameter_calls.jl | 14 -------------- test/runtests.jl | 1 - 4 files changed, 27 deletions(-) delete mode 100644 test/find_parameter_calls.jl diff --git a/src/ModelingToolkit.jl b/src/ModelingToolkit.jl index bda7e36667..e5cf37f202 100644 --- a/src/ModelingToolkit.jl +++ b/src/ModelingToolkit.jl @@ -3,7 +3,6 @@ module ModelingToolkit export Operation, Expression export calculate_jacobian, generate_jacobian, generate_function export independent_variables, dependent_variables, parameters -export find_parameter_calls export @register diff --git a/src/equations.jl b/src/equations.jl index cb107d1c43..ffaa222021 100644 --- a/src/equations.jl +++ b/src/equations.jl @@ -10,14 +10,3 @@ Base.:(==)(a::Equation, b::Equation) = isequal((a.lhs, a.rhs), (b.lhs, b.rhs)) Base.:~(lhs::Expression, rhs::Expression) = Equation(lhs, rhs) Base.:~(lhs::Expression, rhs::Number ) = Equation(lhs, rhs) Base.:~(lhs::Number , rhs::Expression) = Equation(lhs, rhs) - -function find_parameter_calls(O::Operation,p_calls=Variable[]) - if O.op isa Variable && O.op.known && !isempty(O.args) - push!(p_calls,O.op) - find_parameter_calls.(O.args,(p_calls,)) - else - find_parameter_calls.(O.args,(p_calls,)) - end - p_calls -end -find_parameter_calls(O,p_calls) = nothing diff --git a/test/find_parameter_calls.jl b/test/find_parameter_calls.jl deleted file mode 100644 index e66aa649a5..0000000000 --- a/test/find_parameter_calls.jl +++ /dev/null @@ -1,14 +0,0 @@ -using ModelingToolkit -using Test - -# Define some variables -@parameters t σ ρ β α(..) -@variables x(t) y(t) z(t) -@derivatives D'~t - -eq1 = D(x) ~ σ*(y-x) -eq2 = D(x) ~ α(t-2)*(y-x) - -find_parameter_calls(eq1.rhs,Variable[]) -r = find_parameter_calls(eq2.rhs,Variable[]) -!isempty(r) && r[1].name == :α diff --git a/test/runtests.jl b/test/runtests.jl index a05ec6d922..00a80ece02 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -3,5 +3,4 @@ using ModelingToolkit, Test @testset "Parsing Test" begin include("variable_parsing.jl") end @testset "Differentiation Test" begin include("derivatives.jl") end @testset "Simplify Test" begin include("simplify.jl") end -@testset "Parameter Call Finding Test" begin include("find_parameter_calls.jl") end @testset "System Construction Test" begin include("system_construction.jl") end