Skip to content

Commit af679a3

Browse files
Merge pull request #12 from SciML/as/indexing-rework
feat!: indexing rework
2 parents cf0cfca + 7a5c62f commit af679a3

20 files changed

+565
-212
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: RecursiveArrayTools.jl, group: All}
21+
- {user: JuliaSymbolics, repo: Symbolics.jl, group: SymbolicIndexingInterface}
2122
steps:
2223
- uses: actions/checkout@v2
2324
- uses: julia-actions/setup-julia@v1

Project.toml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
11
name = "SymbolicIndexingInterface"
22
uuid = "2efcf032-c050-4f8e-a9bb-153293bab1f5"
33
authors = ["Aayush Sabharwal <[email protected]> and contributors"]
4-
version = "0.2.2"
5-
6-
[deps]
7-
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
4+
version = "0.3.0"
85

96
[compat]
10-
DocStringExtensions = "0.9"
117
julia = "1"
128

139
[extras]

docs/Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
44

55
[compat]
66
Documenter = "0.27"
7-
SymbolicIndexingInterface = "0.2"
7+
SymbolicIndexingInterface = "0.3"

docs/make.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ cp("./docs/Project.toml", "./docs/src/assets/Project.toml", force = true)
66
include("pages.jl")
77

88
makedocs(sitename = "SymbolicIndexingInterface.jl",
9-
authors = "Chris Rackauckas",
10-
modules = [SymbolicIndexingInterface],
11-
clean = true, doctest = false,
12-
format = Documenter.HTML(analytics = "UA-90474609-3",
13-
assets = ["assets/favicon.ico"],
14-
canonical = "https://docs.sciml.ai/SymbolicIndexingInterface/stable/"),
15-
pages = pages)
9+
authors = "Chris Rackauckas",
10+
modules = [SymbolicIndexingInterface],
11+
clean = true, doctest = false,
12+
format = Documenter.HTML(analytics = "UA-90474609-3",
13+
assets = ["assets/favicon.ico"],
14+
canonical = "https://docs.sciml.ai/SymbolicIndexingInterface/stable/"),
15+
pages = pages)
1616

1717
deploydocs(repo = "github.com/SciML/SymbolicIndexingInterface.jl.git";
18-
push_preview = true)
18+
push_preview = true)

docs/src/api.md

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,37 @@
11
# Interface Functions
22

3-
Default methods cast all symbols to `Symbol` before comparing.
3+
```@docs
4+
symbolic_container
5+
is_variable
6+
variable_index
7+
variable_symbols
8+
is_parameter
9+
parameter_index
10+
parameter_symbols
11+
is_independent_variable
12+
independent_variable_symbols
13+
is_observed
14+
observed
15+
is_time_dependent
16+
constant_structure
17+
parameter_values
18+
getp
19+
setp
20+
```
21+
22+
# Traits
423

524
```@docs
6-
independent_variables
7-
is_indep_sym
8-
states
9-
state_sym_to_index
10-
is_state_sym
11-
parameters
12-
param_sym_to_index
13-
is_param_sym
25+
ScalarSymbolic
26+
ArraySymbolic
27+
NotSymbolic
28+
symbolic_type
29+
hasname
30+
getname
1431
```
1532

16-
## Concrete Types
33+
# Types
1734

1835
```@docs
1936
SymbolCache
20-
```
37+
```

docs/src/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# SymbolicIndexingInterface.jl: Arrays of Arrays and Even Deeper
22

33
SymbolicIndexingInterface.jl is a set of interface functions for handling containers
4-
of symbolic variables. It also contains one such container: `SymbolCache`.
4+
of symbolic variables.
55

66
## Installation
77

src/SymbolicIndexingInterface.jl

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
module SymbolicIndexingInterface
22

3-
using DocStringExtensions
3+
export ScalarSymbolic, ArraySymbolic, NotSymbolic, symbolic_type, hasname, getname
4+
include("trait.jl")
45

6+
export is_variable, variable_index, variable_symbols, is_parameter, parameter_index,
7+
parameter_symbols, is_independent_variable, independent_variable_symbols, is_observed,
8+
observed, is_time_dependent, constant_structure, symbolic_container
59
include("interface.jl")
6-
include("symbolcache.jl")
710

8-
export independent_variables, is_indep_sym, states, state_sym_to_index, is_state_sym,
9-
parameters, param_sym_to_index, is_param_sym, observed, observed_sym_to_index,
10-
is_observed_sym, get_state_dependencies, get_observed_dependencies,
11-
get_deps_of_observed, SymbolCache, unknown_states
11+
export SymbolCache
12+
include("symbol_cache.jl")
13+
14+
export parameter_values, getp, setp
15+
include("parameter_indexing.jl")
1216

1317
end

src/interface.jl

Lines changed: 59 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,162 +1,112 @@
11
"""
2-
$(TYPEDSIGNATURES)
2+
symbolic_container(p)
33
4-
Get an iterable over the independent variables for the given system. Default to an empty
5-
vector.
6-
"""
7-
function independent_variables end
8-
independent_variables(::Any) = []
4+
Using `p`, return an object that implements the symbolic indexing interface. In case `p`
5+
itself implements the interface, `p` can be returned as-is. All symbolic indexing interface
6+
methods fall back to calling the same method on `symbolic_container(p)`, so this may be
7+
used for trivial implementations of the interface that forward all calls to another object.
98
9+
This is also used by [`ParameterIndexingProxy`](@ref)
1010
"""
11-
$(TYPEDSIGNATURES)
11+
function symbolic_container end
1212

13-
Check if the given sym is an independent variable in the given system. Default to checking
14-
if the given `sym` exists in the iterable returned by `independent_variables`.
1513
"""
16-
function is_indep_sym end
17-
18-
function is_indep_sym(store, sym)
19-
any(isequal(Symbol(sym)), Symbol.(independent_variables(store)))
20-
end
14+
is_variable(sys, sym)
2115
16+
Check whether the given `sym` is a variable in `sys`.
2217
"""
23-
$(TYPEDSIGNATURES)
18+
is_variable(sys, sym) = is_variable(symbolic_container(sys), sym)
2419

25-
Get an iterable over the states for the given system. Default to an empty vector.
2620
"""
27-
function states end
28-
29-
states(::Any) = []
21+
variable_index(sys, sym, [i])
3022
23+
Return the index of the given variable `sym` in `sys`, or `nothing` otherwise. If
24+
[`constant_structure`](@ref) is `false`, this accepts the current time index as an
25+
additional parameter `i`.
3126
"""
32-
$(TYPEDSIGNATURES)
27+
variable_index(sys, sym) = variable_index(symbolic_container(sys), sym)
28+
variable_index(sys, sym, i) = variable_index(symbolic_container(sys), sym, i)
3329

34-
Get an iterable over the unknown states for the given system. Default to an empty vector.
3530
"""
36-
function unknown_states end
37-
38-
unknown_states(::Any) = []
31+
variable_symbols(sys, [i])
3932
33+
Return a vector of the symbolic variables being solved for in the system `sys`. If
34+
`constant_structure(sys) == false` this accepts an additional parameter indicating
35+
the current time index. The returned vector should not be mutated.
4036
"""
41-
$(TYPEDSIGNATURES)
37+
variable_symbols(sys) = variable_symbols(symbolic_container(sys))
38+
variable_symbols(sys, i) = variable_symbols(symbolic_container(sys), i)
4239

43-
Find the index of the given sym in the given system. Default to the index of the first
44-
symbol in the iterable returned by `states` which matches the given `sym`. Return
45-
`nothing` if the given `sym` does not match.
4640
"""
47-
function state_sym_to_index end
48-
49-
function state_sym_to_index(store, sym)
50-
findfirst(isequal(Symbol(sym)), Symbol.(states(store)))
51-
end
41+
is_parameter(sys, sym)
5242
43+
Check whether the given `sym` is a parameter in `sys`.
5344
"""
54-
$(TYPEDSIGNATURES)
45+
is_parameter(sys, sym) = is_parameter(symbolic_container(sys), sym)
5546

56-
Check if the given sym is a state variable in the given system. Default to checking if
57-
the value returned by `state_sym_to_index` is not `nothing`.
5847
"""
59-
function is_state_sym end
60-
61-
is_state_sym(store, sym) = !isnothing(state_sym_to_index(store, sym))
48+
parameter_index(sys, sym)
6249
50+
Return the index of the given parameter `sym` in `sys`, or `nothing` otherwise.
6351
"""
64-
$(TYPEDSIGNATURES)
52+
parameter_index(sys, sym) = parameter_index(symbolic_container(sys), sym)
6553

66-
Get an iterable over the parameters variables for the given system. Default to an empty
67-
vector.
6854
"""
69-
function parameters end
70-
71-
parameters(::Any) = []
55+
parameter_symbols(sys)
7256
57+
Return a vector of the symbolic parameters of the given system `sys`. The returned
58+
vector should not be mutated.
7359
"""
74-
$(TYPEDSIGNATURES)
60+
parameter_symbols(sys) = parameter_symbols(symbolic_container(sys))
7561

76-
Find the index of the given sym in the given system. Default to the index of the first
77-
symbol in the iterable retruned by `parameters` which matches the given `sym`. Return
78-
`nothing` if the given `sym` does not match.
7962
"""
80-
function param_sym_to_index end
81-
82-
param_sym_to_index(store, sym) = findfirst(isequal(Symbol(sym)), Symbol.(parameters(store)))
63+
is_independent_variable(sys, sym)
8364
65+
Check whether the given `sym` is an independent variable in `sys`. The returned vector
66+
should not be mutated.
8467
"""
85-
$(TYPEDSIGNATURES)
68+
is_independent_variable(sys, sym) = is_independent_variable(symbolic_container(sys), sym)
8669

87-
Check if the given sym is a parameter variable in the given system. Default
88-
to checking if the value returned by `param_sym_to_index` is not `nothing`.
8970
"""
90-
function is_param_sym end
91-
92-
is_param_sym(store, sym) = !isnothing(param_sym_to_index(store, sym))
71+
independent_variable_symbols(sys)
9372
73+
Return a vector of the symbolic independent variables of the given system `sys`.
9474
"""
95-
$(TYPEDSIGNATURES)
75+
independent_variable_symbols(sys) = independent_variable_symbols(symbolic_container(sys))
9676

97-
Get an iterable over the observed variable expressions for the given system.
98-
Default to an empty vector.
9977
"""
100-
function observed end
101-
102-
observed(::Any) = []
78+
is_observed(sys, sym)
10379
80+
Check whether the given `sym` is an observed value in `sys`.
10481
"""
105-
$(TYPEDSIGNATURES)
82+
is_observed(sys, sym) = is_observed(symbolic_container(sys), sym)
10683

107-
Check if the given sym is an observed variable in the given system. Default
108-
to checking if the value returned by `observed_sym_to_index` is not `nothing`.
10984
"""
110-
function is_observed_sym end
85+
observed(sys, sym, [states])
11186
112-
is_observed_sym(store, sym) = !isnothing(observed_sym_to_index(store, sym))
87+
Return the observed function of the given `sym` in `sys`. The returned function should
88+
have the signature `(u, p) -> [values...]` where `u` and `p` is the current state and
89+
parameter vector. If `istimedependent(sys) == true`, the function should accept
90+
the current time `t` as its third parameter. If `constant_structure(sys) == false`,
91+
accept a third parameter which can either be a vector of symbols indicating the order
92+
of states or a time index which identifies the order of states.
11393
94+
See also: [`is_time_dependent`](@ref), [`constant_structure`](@ref)
11495
"""
115-
$(TYPEDSIGNATURES)
96+
observed(sys, sym) = observed(symbolic_container(sys), sym)
97+
observed(sys, sym, states) = observed(symbolic_container(sys), sym, states)
11698

117-
Find the index of the given sym in the given system. Default to the index of the first
118-
symbol in the iterable returned by `states` which matches the given `sym`. Return
119-
`nothing` if the given `sym` does not match.
12099
"""
121-
function observed_sym_to_index end
122-
123-
function observed_sym_to_index(store, sym)
124-
findfirst(o -> isequal(sym, o.lhs), observed(store))
125-
end
100+
is_time_dependent(sys)
126101
102+
Check if `sys` has time as (one of) its independent variables.
127103
"""
128-
$(TYPEDSIGNATURES)
104+
is_time_dependent(sys) = is_time_dependent(symbolic_container(sys))
129105

130-
Return a list of the dependent state variables of an observed variable. Default to returning
131-
an empty list.
132106
"""
133-
function get_state_dependencies end
107+
constant_structure(sys)
134108
135-
get_state_dependencies(store, sym) = []
136-
137-
"""
138-
$(TYPEDSIGNATURES)
139-
140-
Return a list of the dependent observed variables of an observed variable. Default to returning
141-
an empty list.
142-
"""
143-
function get_observed_dependencies end
144-
145-
get_observed_dependencies(store, sym) = []
146-
147-
"""
148-
$(TYPEDSIGNATURES)
149-
150-
Return a list of the dependent state variables of all observed equations of the system.
151-
Default to returning an empty list.
109+
Check if `sys` has a constant structure. Constant structure systems do not change the
110+
number of variables or parameters over time.
152111
"""
153-
function get_deps_of_observed end
154-
155-
function get_deps_of_observed(store)
156-
obs = observed(store)
157-
deps = mapreduce(vcat, obs, init = []) do eq
158-
get_state_dependencies(store, eq.lhs)
159-
end |> unique
160-
161-
return deps
162-
end
112+
constant_structure(sys) = constant_structure(symbolic_container(sys))

0 commit comments

Comments
 (0)