Skip to content

Commit 14632a1

Browse files
committed
Merge branch 'master' into myb/obs
2 parents 8641bcf + 24d5041 commit 14632a1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+909
-721
lines changed

.github/workflows/Downstream.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ jobs:
1818
os: [ubuntu-latest]
1919
package:
2020
- {user: SciML, repo: Catalyst.jl, group: All}
21+
- {user: SciML, repo: CellMLToolkit.jl, group: All}
2122
- {user: SciML, repo: NeuralPDE.jl, group: NNPDE}
2223
- {user: SciML, repo: DataDrivenDiffEq.jl, group: Standard}
2324

Project.toml

Lines changed: 6 additions & 5 deletions
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 = "5.13.6"
4+
version = "5.14.2"
55

66
[deps]
77
AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c"
@@ -51,7 +51,7 @@ Distributions = "0.23, 0.24"
5151
DocStringExtensions = "0.7, 0.8"
5252
IfElse = "0.1"
5353
LabelledArrays = "1.3"
54-
Latexify = "0.11, 0.12, 0.13, 0.14"
54+
Latexify = "0.11, 0.12, 0.13, 0.14, 0.15"
5555
LightGraphs = "1.3"
5656
MacroTools = "0.5"
5757
NaNMath = "0.3"
@@ -65,8 +65,8 @@ SciMLBase = "1.3"
6565
Setfield = "0.7"
6666
SpecialFunctions = "0.7, 0.8, 0.9, 0.10, 1.0"
6767
StaticArrays = "0.10, 0.11, 0.12, 1.0"
68-
SymbolicUtils = "0.8.3, 0.9"
69-
Symbolics = "0.1.8"
68+
SymbolicUtils = "0.11.0"
69+
Symbolics = "0.1.14"
7070
UnPack = "0.1, 1.0"
7171
Unitful = "1.1"
7272
julia = "1.2"
@@ -81,7 +81,8 @@ OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
8181
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
8282
SteadyStateDiffEq = "9672c7b4-1e72-59bd-8a11-6ac3964bc41f"
8383
StochasticDiffEq = "789caeaf-c7a9-5a7d-9973-96adeb23e2a0"
84+
Sundials = "c3572dad-4567-51f8-b174-8c6c989267f4"
8485
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
8586

8687
[targets]
87-
test = ["BenchmarkTools", "ForwardDiff", "GalacticOptim", "NonlinearSolve", "OrdinaryDiffEq", "Optim", "Random", "SteadyStateDiffEq", "Test", "StochasticDiffEq"]
88+
test = ["BenchmarkTools", "ForwardDiff", "GalacticOptim", "NonlinearSolve", "OrdinaryDiffEq", "Optim", "Random", "SteadyStateDiffEq", "Test", "StochasticDiffEq", "Sundials"]

docs/src/basics/ContextualVariables.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ the `@variable` which is defined by
77
[Symbolics.jl](https://github.com/JuliaSymbolics/Symbolics.jl). For example:
88

99
```julia
10-
@variabes x y(x)
10+
@variables x y(x)
1111
```
1212

1313
This is used for the "normal" variable of a given system, like the states of a

docs/src/tutorials/ode_modeling.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ But if you want to just see some code and run, here's an example:
1313
```julia
1414
using ModelingToolkit
1515

16-
@variables t, x(t) RHS(t) # independent and dependent variables
16+
@variables t x(t) RHS(t) # independent and dependent variables
1717
@parameters τ # parameters
1818
D = Differential(t) # define an operator for the differentiation w.r.t. time
1919

@@ -51,7 +51,7 @@ first set the forcing function to a constant value.
5151
```julia
5252
using ModelingToolkit
5353

54-
@variables t, x(t) # independent and dependent variables
54+
@variables t x(t) # independent and dependent variables
5555
@parameters τ # parameters
5656
D = Differential(t) # define an operator for the differentiation w.r.t. time
5757

docs/src/tutorials/tearing_parallelism.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ function connect_heat(ps...)
3737
end
3838

3939
# Basic electric components
40-
const t = Sym{ModelingToolkit.Parameter{Real}}(:t)
40+
@parameters t
4141
const D = Differential(t)
4242
function Pin(;name)
4343
@variables v(t) i(t)

test/rc_model.jl renamed to examples/electrical_components.jl

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@ using Test
22
using ModelingToolkit, OrdinaryDiffEq
33

44
# Basic electric components
5-
const t = Sym{ModelingToolkit.Parameter{Real}}(:t)
5+
@parameters t
66
function Pin(;name)
77
@variables v(t) i(t)
88
ODESystem(Equation[], t, [v, i], [], name=name, defaults=[v=>1.0, i=>1.0])
99
end
1010

11-
function Ground(name)
11+
function Ground(;name)
1212
@named g = Pin()
1313
eqs = [g.v ~ 0]
1414
ODESystem(eqs, t, [], [], systems=[g], name=name)
1515
end
1616

17-
function ConstantVoltage(name; V = 1.0)
17+
function ConstantVoltage(;name, V = 1.0)
1818
val = V
1919
@named p = Pin()
2020
@named n = Pin()
@@ -26,7 +26,7 @@ function ConstantVoltage(name; V = 1.0)
2626
ODESystem(eqs, t, [], [V], systems=[p, n], defaults=Dict(V => val), name=name)
2727
end
2828

29-
function Resistor(name; R = 1.0)
29+
function Resistor(;name, R = 1.0)
3030
val = R
3131
@named p = Pin()
3232
@named n = Pin()
@@ -40,7 +40,7 @@ function Resistor(name; R = 1.0)
4040
ODESystem(eqs, t, [v], [R], systems=[p, n], defaults=Dict(R => val), name=name)
4141
end
4242

43-
function Capacitor(name; C = 1.0)
43+
function Capacitor(;name, C = 1.0)
4444
val = C
4545
@named p = Pin()
4646
@named n = Pin()
@@ -55,15 +55,23 @@ function Capacitor(name; C = 1.0)
5555
ODESystem(eqs, t, [v], [C], systems=[p, n], defaults=Dict(C => val), name=name)
5656
end
5757

58-
R = 1.0
59-
C = 1.0
60-
V = 1.0
61-
resistor = Resistor(:resistor, R=R)
62-
capacitor = Capacitor(:capacitor, C=C)
63-
source = ConstantVoltage(:source, V=V)
64-
ground = Ground(:ground)
58+
function Inductor(; name, L = 1.0)
59+
val = L
60+
@named p = Pin()
61+
@named n = Pin()
62+
@variables v(t) i(t)
63+
@parameters L
64+
D = Differential(t)
65+
eqs = [
66+
v ~ p.v - n.v
67+
0 ~ p.i + n.i
68+
i ~ p.i
69+
D(i) ~ v / L
70+
]
71+
ODESystem(eqs, t, [v, i], [L], systems=[p, n], defaults=Dict(L => val), name=name)
72+
end
6573

66-
function connect(ps...)
74+
function connect_pins(ps...)
6775
eqs = [
6876
0 ~ sum(p->p.i, ps) # KCL
6977
]
@@ -74,10 +82,3 @@ function connect(ps...)
7482

7583
return eqs
7684
end
77-
rc_eqs = [
78-
connect(source.p, resistor.p)
79-
connect(resistor.n, capacitor.p)
80-
connect(capacitor.n, source.n, ground.g)
81-
]
82-
83-
rc_model = ODESystem(rc_eqs, t, systems=[resistor, capacitor, source, ground], name=:rc)

examples/rc_model.jl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
include("electrical_components.jl")
2+
3+
R = 1.0
4+
C = 1.0
5+
V = 1.0
6+
@named resistor = Resistor(R=R)
7+
@named capacitor = Capacitor(C=C)
8+
@named source = ConstantVoltage(V=V)
9+
@named ground = Ground()
10+
11+
rc_eqs = [
12+
connect_pins(source.p, resistor.p)
13+
connect_pins(resistor.n, capacitor.p)
14+
connect_pins(capacitor.n, source.n, ground.g)
15+
]
16+
17+
@named rc_model = ODESystem(rc_eqs, t, systems=[resistor, capacitor, source, ground])

examples/serial_inductor.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
include("electrical_components.jl")
2+
3+
@named source = ConstantVoltage(V=10.0)
4+
@named resistor = Resistor(R=1.0)
5+
@named inductor1 = Inductor(L=1.0e-2)
6+
@named inductor2 = Inductor(L=2.0e-2)
7+
@named ground = Ground()
8+
9+
eqs = [
10+
connect_pins(source.p, resistor.p)
11+
connect_pins(resistor.n, inductor1.p)
12+
connect_pins(inductor1.n, inductor2.p)
13+
connect_pins(source.n, inductor2.n, ground.g)
14+
]
15+
16+
@named ll_model = ODESystem(eqs, t, systems=[source, resistor, inductor1, inductor2, ground])

src/ModelingToolkit.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ include("structural_transformation/StructuralTransformations.jl")
137137
@reexport using .StructuralTransformations
138138

139139
export ODESystem, ODEFunction, ODEFunctionExpr, ODEProblemExpr
140+
export DAEFunctionExpr, DAEProblemExpr
140141
export SDESystem, SDEFunction, SDEFunctionExpr, SDESystemExpr
141142
export SystemStructure
142143
export JumpSystem
@@ -157,6 +158,7 @@ export Differential, expand_derivatives, @derivatives
157158
export IntervalDomain, ProductDomain, , CircleDomain
158159
export Equation, ConstrainedEquation
159160
export Term, Sym
161+
export SymScope, LocalScope, ParentScope, GlobalScope
160162
export independent_variable, states, parameters, equations, controls, observed, structure
161163
export structural_simplify
162164

src/bipartite_graph.jl

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,13 @@ badjlist = [[1,2,5,6],[3,4,6]]
6666
bg = BipartiteGraph(7, fadjlist, badjlist)
6767
```
6868
"""
69-
mutable struct BipartiteGraph{I<:Integer,M} <: LightGraphs.AbstractGraph{I}
69+
mutable struct BipartiteGraph{I<:Integer,F<:Vector{Vector{I}},B<:Union{Vector{Vector{I}},I},M} <: LightGraphs.AbstractGraph{I}
7070
ne::Int
71-
fadjlist::Vector{Vector{I}} # `fadjlist[src] => dsts`
72-
badjlist::Vector{Vector{I}} # `badjlist[dst] => srcs`
71+
fadjlist::F # `fadjlist[src] => dsts`
72+
badjlist::B # `badjlist[dst] => srcs` or `ndsts`
7373
metadata::M
7474
end
75-
BipartiteGraph(ne::Integer, fadj::AbstractVector, badj::AbstractVector) = BipartiteGraph(ne, fadj, badj, nothing)
75+
BipartiteGraph(ne::Integer, fadj::AbstractVector, badj::Union{AbstractVector,Integer}=maximum(maximum, fadj); metadata=nothing) = BipartiteGraph(ne, fadj, badj, metadata)
7676

7777
"""
7878
```julia
@@ -93,16 +93,16 @@ $(SIGNATURES)
9393
9494
Build an empty `BipartiteGraph` with `nsrcs` sources and `ndsts` destinations.
9595
"""
96-
function BipartiteGraph(nsrcs::T, ndsts::T; metadata=nothing) where T
96+
function BipartiteGraph(nsrcs::T, ndsts::T, backedge::Val{B}=Val(true); metadata=nothing) where {T,B}
9797
fadjlist = map(_->T[], 1:nsrcs)
98-
badjlist = map(_->T[], 1:ndsts)
98+
badjlist = B ? map(_->T[], 1:ndsts) : ndsts
9999
BipartiteGraph(0, fadjlist, badjlist, metadata)
100100
end
101101

102102
Base.eltype(::Type{<:BipartiteGraph{I}}) where I = I
103103
function Base.empty!(g::BipartiteGraph)
104104
foreach(empty!, g.fadjlist)
105-
foreach(empty!, g.badjlist)
105+
g.badjlist isa AbstractVector && foreach(empty!, g.badjlist)
106106
g.ne = 0
107107
if g.metadata !== nothing
108108
foreach(empty!, g.metadata)
@@ -111,17 +111,22 @@ function Base.empty!(g::BipartiteGraph)
111111
end
112112
Base.length(::BipartiteGraph) = error("length is not well defined! Use `ne` or `nv`.")
113113

114+
@noinline throw_no_back_edges() = throw(ArgumentError("The graph has no back edges."))
115+
114116
if isdefined(LightGraphs, :has_contiguous_vertices)
115117
LightGraphs.has_contiguous_vertices(::Type{<:BipartiteGraph}) = false
116118
end
117119
LightGraphs.is_directed(::Type{<:BipartiteGraph}) = false
118120
LightGraphs.vertices(g::BipartiteGraph) = (𝑠vertices(g), 𝑑vertices(g))
119121
𝑠vertices(g::BipartiteGraph) = axes(g.fadjlist, 1)
120-
𝑑vertices(g::BipartiteGraph) = axes(g.badjlist, 1)
122+
𝑑vertices(g::BipartiteGraph) = g.badjlist isa AbstractVector ? axes(g.badjlist, 1) : Base.OneTo(g.badjlist)
121123
has_𝑠vertex(g::BipartiteGraph, v::Integer) = v in 𝑠vertices(g)
122124
has_𝑑vertex(g::BipartiteGraph, v::Integer) = v in 𝑑vertices(g)
123125
𝑠neighbors(g::BipartiteGraph, i::Integer, with_metadata::Val{M}=Val(false)) where M = M ? zip(g.fadjlist[i], g.metadata[i]) : g.fadjlist[i]
124-
𝑑neighbors(g::BipartiteGraph, j::Integer, with_metadata::Val{M}=Val(false)) where M = M ? zip(g.badjlist[j], (g.metadata[i][j] for i in g.badjlist[j])) : g.badjlist[j]
126+
function 𝑑neighbors(g::BipartiteGraph, j::Integer, with_metadata::Val{M}=Val(false)) where M
127+
g.badjlist isa AbstractVector || throw_no_back_edges()
128+
M ? zip(g.badjlist[j], (g.metadata[i][j] for i in g.badjlist[j])) : g.badjlist[j]
129+
end
125130
LightGraphs.ne(g::BipartiteGraph) = g.ne
126131
LightGraphs.nv(g::BipartiteGraph) = sum(length, vertices(g))
127132
LightGraphs.edgetype(g::BipartiteGraph{I}) where I = BipartiteEdge{I}
@@ -145,7 +150,6 @@ const NO_METADATA = NoMetadata()
145150
LightGraphs.add_edge!(g::BipartiteGraph, i::Integer, j::Integer, md=NO_METADATA) = add_edge!(g, BipartiteEdge(i, j), md)
146151
function LightGraphs.add_edge!(g::BipartiteGraph, edge::BipartiteEdge, md=NO_METADATA)
147152
@unpack fadjlist, badjlist = g
148-
verts = vertices(g)
149153
s, d = src(edge), dst(edge)
150154
(has_𝑠vertex(g, s) && has_𝑑vertex(g, d)) || error("edge ($edge) out of range.")
151155
@inbounds list = fadjlist[s]
@@ -157,15 +161,21 @@ function LightGraphs.add_edge!(g::BipartiteGraph, edge::BipartiteEdge, md=NO_MET
157161
end
158162

159163
g.ne += 1
160-
@inbounds list = badjlist[d]
161-
index = searchsortedfirst(list, s)
162-
insert!(list, index, s)
164+
if badjlist isa AbstractVector
165+
@inbounds list = badjlist[d]
166+
index = searchsortedfirst(list, s)
167+
insert!(list, index, s)
168+
end
163169
return true # edge successfully added
164170
end
165171

166172
function LightGraphs.add_vertex!(g::BipartiteGraph{T}, type::VertType) where T
167173
if type === DST
168-
push!(g.badjlist, T[])
174+
if g.badjlist isa AbstractVector
175+
push!(g.badjlist, T[])
176+
else
177+
g.badjlist += 1
178+
end
169179
elseif type === SRC
170180
push!(g.fadjlist, T[])
171181
else

0 commit comments

Comments
 (0)