Skip to content

Commit 0392ad5

Browse files
committed
Merge remote-tracking branch 'origin/master' into jumpsystems
2 parents 14d2551 + 98e6705 commit 0392ad5

16 files changed

+98
-352
lines changed

.github/workflows/TagBot.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ jobs:
88
steps:
99
- uses: JuliaRegistries/TagBot@v1
1010
with:
11-
token: ${{ secrets.GITHUB_TOKEN }}
11+
token: ${{ secrets.GITHUB_TOKEN }}
12+
ssh: ${{ secrets.DOCUMENTER_KEY }}

Project.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "ModelingToolkit"
22
uuid = "961ee093-0014-501f-94e3-6117800e7a78"
33
authors = ["Chris Rackauckas <[email protected]>"]
4-
version = "3.0.2"
4+
version = "3.1.1"
55

66
[deps]
77
ArrayInterface = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9"
@@ -19,6 +19,7 @@ SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
1919
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
2020
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
2121
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
22+
SymbolicUtils = "d1185830-fcd6-423d-90d6-eec64667417b"
2223
TreeViews = "a2a6695c-b41b-5b7d-aed9-dbfdeacea5d7"
2324
UnPack = "3a884ed6-31ef-47d7-9d2a-63182c4928ed"
2425
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"
@@ -35,6 +36,7 @@ NaNMath = "0.3"
3536
SafeTestsets = "0.0.1"
3637
SpecialFunctions = "0.7, 0.8, 0.9, 0.10"
3738
StaticArrays = "0.10, 0.11, 0.12"
39+
SymbolicUtils = "0.1.1, 0.2"
3840
TreeViews = "0.3"
3941
UnPack = "0.1"
4042
Unitful = "1.1"

docs/make.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,6 @@ makedocs(
2525
)
2626

2727
deploydocs(
28-
repo = "github.com/SciML/ModelingToolkit.jl.git"
28+
repo = "github.com/SciML/ModelingToolkit.jl.git";
29+
push_preview = true
2930
)

src/ModelingToolkit.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ include("systems/diffeqs/odesystem.jl")
8484
include("systems/diffeqs/sdesystem.jl")
8585
include("systems/diffeqs/abstractodesystem.jl")
8686
include("systems/diffeqs/first_order_transform.jl")
87-
include("systems/diffeqs/index_reduction.jl")
8887
include("systems/diffeqs/modelingtoolkitize.jl")
8988
include("systems/diffeqs/validation.jl")
9089

src/differentials.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ function expand_derivatives(O::Operation)
5252
end |> simplify_constants
5353
end
5454

55-
return O
55+
return simplify_constants(O)
5656
end
5757
expand_derivatives(x) = x
5858

src/simplify.jl

Lines changed: 40 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,52 @@
1-
function simplify_constants(O::Operation, shorten_tree)
2-
while true
3-
O′ = _simplify_constants(O, shorten_tree)
4-
if is_operation(O′)
5-
O′ = Operation(O′.op, simplify_constants.(O′.args, shorten_tree))
6-
end
7-
isequal(O, O′) && return O
8-
O = O′
1+
import SymbolicUtils
2+
import SymbolicUtils: FnType
3+
4+
# ModelingToolkit -> SymbolicUtils
5+
SymbolicUtils.istree(x::Operation) = true
6+
function SymbolicUtils.operation(x::Operation)
7+
if x.op isa Variable
8+
T = FnType{NTuple{length(x.args), Any}, vartype(x.op)}
9+
SymbolicUtils.Variable{T}(x.op.name)
10+
else
11+
x.op
912
end
1013
end
11-
simplify_constants(x, shorten_tree) = x
1214

13-
"""
14-
simplify_constants(x::Operation)
15+
# This is required to infer the right type for
16+
# Operation(Variable{Parameter{Number}}(:foo), [])
17+
# While keeping the metadata that the variable is a parameter.
18+
SymbolicUtils.promote_symtype(f::SymbolicUtils.Sym{FnType{X,Parameter{Y}}},
19+
xs...) where {X, Y} = Y
1520

16-
Simplifies the constants within an expression, for example removing equations
17-
multiplied by a zero and summing constant values.
18-
"""
19-
simplify_constants(x) = simplify_constants(x, true)
21+
SymbolicUtils.arguments(x::Operation) = x.args
2022

21-
Base.isone(x::Operation) = x.op == one || x.op == Constant && isone(x.args)
22-
const AC_OPERATORS = (*, +)
23+
# SymbolicUtils wants raw numbers
24+
SymbolicUtils.to_symbolic(x::Constant) = x.value
25+
SymbolicUtils.to_symbolic(x::Variable{T}) where {T} = SymbolicUtils.Sym{T}(x.name)
2326

24-
function _simplify_constants(O::Operation, shorten_tree)
25-
# Tree shrinking
26-
if shorten_tree && O.op AC_OPERATORS
27-
# Flatten tree
28-
idxs = findall(x -> is_operation(x) && x.op === O.op, O.args)
29-
if !isempty(idxs)
30-
keep_idxs = eachindex(O.args) .∉ (idxs,)
31-
args = Vector{Expression}[O.args[i].args for i in idxs]
32-
push!(args, O.args[keep_idxs])
33-
return Operation(O.op, vcat(args...))
34-
end
27+
# Optional types of vars
28+
# Once converted to SymbolicUtils Variable, a Parameter needs to hide its metadata
29+
_vartype(x::Variable{<:Parameter{T}}) where {T} = T
30+
_vartype(x::Variable{T}) where {T} = T
31+
SymbolicUtils.symtype(x::Variable) = _vartype(x) # needed for a()
32+
SymbolicUtils.symtype(x::SymbolicUtils.Sym{<:Parameter{T}}) where {T} = T
3533

36-
# Collapse constants
37-
idxs = findall(is_constant, O.args)
38-
if length(idxs) > 1
39-
other_idxs = eachindex(O.args) .∉ (idxs,)
40-
new_const = Constant(mapreduce(get, O.op, O.args[idxs]))
41-
args = push!(O.args[other_idxs], new_const)
34+
# returning Any causes SymbolicUtils to infer the type using `promote_symtype`
35+
# But we are OK with Number here for now I guess
36+
SymbolicUtils.symtype(x::Expression) = Number
4237

43-
length(args) == 1 && return first(args)
44-
return Operation(O.op, args)
45-
end
46-
end
47-
48-
if O.op === (*)
49-
# If any variable is `Constant(0)`, zero the whole thing
50-
any(iszero, O.args) && return Constant(0)
51-
52-
# If any variable is `Constant(1)`, remove that `Constant(1)` unless
53-
# they are all `Constant(1)`, in which case simplify to a single variable
54-
if any(isone, O.args)
55-
args = filter(!isone, O.args)
56-
57-
isempty(args) && return Constant(1)
58-
length(args) == 1 && return first(args)
59-
return Operation(O.op, args)
60-
end
61-
62-
return O
63-
end
64-
65-
if O.op === (^) && length(O.args) == 2 && iszero(O.args[2])
66-
return Constant(1)
67-
end
6838

69-
if O.op === (^) && length(O.args) == 2 && isone(O.args[2])
70-
return O.args[1]
71-
end
72-
73-
if O.op === (+) && any(iszero, O.args)
74-
# If there are Constant(0)s in a big `+` expression, get rid of them
75-
args = filter(!iszero, O.args)
76-
77-
isempty(args) && return Constant(0)
78-
length(args) == 1 && return first(args)
79-
return Operation(O.op, args)
80-
end
39+
# SymbolicUtils -> ModelingToolkit
8140

82-
if (O.op === (-) || O.op === (+) || O.op === (*)) && all(is_constant, O.args) && !isempty(O.args)
83-
v = O.args[1].value
84-
for i in 2:length(O.args)
85-
v = O.op(v, O.args[i].value)
86-
end
87-
return Constant(v)
88-
end
89-
90-
(O.op, length(O.args)) === (identity, 1) && return O.args[1]
91-
92-
(O.op, length(O.args)) === (-, 1) && return Operation(*, Expression[-1, O.args[1]])
41+
function simplify_constants(expr)
42+
SymbolicUtils.simplify(expr) |> to_mtk
43+
end
9344

94-
return O
45+
to_mtk(x) = x
46+
to_mtk(x::Number) = Constant(x)
47+
to_mtk(v::SymbolicUtils.Sym{T}) where {T} = Variable{T}(nameof(v))
48+
to_mtk(v::SymbolicUtils.Sym{FnType{X,Y}}) where {X,Y} = Variable{Y}(nameof(v))
49+
function to_mtk(expr::SymbolicUtils.Term)
50+
Operation(to_mtk(SymbolicUtils.operation(expr)),
51+
map(to_mtk, SymbolicUtils.arguments(expr)))
9552
end
96-
_simplify_constants(x, shorten_tree) = x
97-
_simplify_constants(x) = _simplify_constants(x, true)

src/systems/diffeqs/abstractodesystem.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ function calculate_massmatrix(sys::AbstractODESystem, simplify=true)
114114
end
115115
end
116116
M = simplify ? simplify_constants.(M) : M
117+
# M should only contain concrete numbers
118+
M = map(x->x isa Constant ? x.value : x, M)
117119
M == I ? I : M
118120
end
119121

src/systems/diffeqs/index_reduction.jl

Lines changed: 0 additions & 162 deletions
This file was deleted.

src/systems/diffeqs/sdesystem.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ function DiffEqBase.SDEProblem{iip}(sys::SDESystem,u0map,tspan,p=parammap;
168168
Generates an SDEProblem from an SDESystem and allows for automatically
169169
symbolically calculating numerical enhancements.
170170
"""
171-
function DiffEqBase.SDEProblem{iip}(sys::SDESystem,u0map,tspan,p=parammap;
171+
function DiffEqBase.SDEProblem{iip}(sys::SDESystem,u0map,tspan,parammap=DiffEqBase.NullParameters();
172172
version = nothing, tgrad=false,
173173
jac = false, Wfact = false,
174174
checkbounds = false, sparse = false,
@@ -182,3 +182,7 @@ function DiffEqBase.SDEProblem{iip}(sys::SDESystem,u0map,tspan,p=parammap;
182182
p = varmap_to_vars(parammap,parameters(sys))
183183
SDEProblem(f,f.g,u0,tspan,p;kwargs...)
184184
end
185+
186+
function DiffEqBase.SDEProblem(sys::SDESystem, args...; kwargs...)
187+
SDEProblem{true}(sys, args...; kwargs...)
188+
end

src/systems/nonlinear/nonlinearsystem.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ function generate_jacobian(sys::NonlinearSystem, vs = states(sys), ps = paramete
5353
if sparse
5454
jac = SparseArrays.sparse(jac)
5555
end
56-
return build_function(jac, convert.(Variable,vs), convert.(Variable,ps),
57-
conv = AbstractSysToExpr(sys))
56+
return build_function(jac, convert.(Variable,vs), convert.(Variable,ps);
57+
conv = AbstractSysToExpr(sys), kwargs...)
5858
end
5959

6060
function generate_function(sys::NonlinearSystem, vs = states(sys), ps = parameters(sys); kwargs...)

0 commit comments

Comments
 (0)