Skip to content

Commit

Permalink
Merge pull request #12 from SciML/as/indexing-rework
Browse files Browse the repository at this point in the history
feat!: indexing rework
  • Loading branch information
ChrisRackauckas authored Dec 11, 2023
2 parents cf0cfca + 7a5c62f commit af679a3
Show file tree
Hide file tree
Showing 20 changed files with 565 additions and 212 deletions.
1 change: 1 addition & 0 deletions .github/workflows/Downstream.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ jobs:
os: [ubuntu-latest]
package:
- {user: SciML, repo: RecursiveArrayTools.jl, group: All}
- {user: JuliaSymbolics, repo: Symbolics.jl, group: SymbolicIndexingInterface}
steps:
- uses: actions/checkout@v2
- uses: julia-actions/setup-julia@v1
Expand Down
6 changes: 1 addition & 5 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
name = "SymbolicIndexingInterface"
uuid = "2efcf032-c050-4f8e-a9bb-153293bab1f5"
authors = ["Aayush Sabharwal <[email protected]> and contributors"]
version = "0.2.2"

[deps]
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
version = "0.3.0"

[compat]
DocStringExtensions = "0.9"
julia = "1"

[extras]
Expand Down
2 changes: 1 addition & 1 deletion docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"

[compat]
Documenter = "0.27"
SymbolicIndexingInterface = "0.2"
SymbolicIndexingInterface = "0.3"
16 changes: 8 additions & 8 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ cp("./docs/Project.toml", "./docs/src/assets/Project.toml", force = true)
include("pages.jl")

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

deploydocs(repo = "github.com/SciML/SymbolicIndexingInterface.jl.git";
push_preview = true)
push_preview = true)
39 changes: 28 additions & 11 deletions docs/src/api.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,37 @@
# Interface Functions

Default methods cast all symbols to `Symbol` before comparing.
```@docs
symbolic_container
is_variable
variable_index
variable_symbols
is_parameter
parameter_index
parameter_symbols
is_independent_variable
independent_variable_symbols
is_observed
observed
is_time_dependent
constant_structure
parameter_values
getp
setp
```

# Traits

```@docs
independent_variables
is_indep_sym
states
state_sym_to_index
is_state_sym
parameters
param_sym_to_index
is_param_sym
ScalarSymbolic
ArraySymbolic
NotSymbolic
symbolic_type
hasname
getname
```

## Concrete Types
# Types

```@docs
SymbolCache
```
```
2 changes: 1 addition & 1 deletion docs/src/index.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# SymbolicIndexingInterface.jl: Arrays of Arrays and Even Deeper

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

## Installation

Expand Down
16 changes: 10 additions & 6 deletions src/SymbolicIndexingInterface.jl
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
module SymbolicIndexingInterface

using DocStringExtensions
export ScalarSymbolic, ArraySymbolic, NotSymbolic, symbolic_type, hasname, getname
include("trait.jl")

export is_variable, variable_index, variable_symbols, is_parameter, parameter_index,
parameter_symbols, is_independent_variable, independent_variable_symbols, is_observed,
observed, is_time_dependent, constant_structure, symbolic_container
include("interface.jl")
include("symbolcache.jl")

export independent_variables, is_indep_sym, states, state_sym_to_index, is_state_sym,
parameters, param_sym_to_index, is_param_sym, observed, observed_sym_to_index,
is_observed_sym, get_state_dependencies, get_observed_dependencies,
get_deps_of_observed, SymbolCache, unknown_states
export SymbolCache
include("symbol_cache.jl")

export parameter_values, getp, setp
include("parameter_indexing.jl")

end
168 changes: 59 additions & 109 deletions src/interface.jl
Original file line number Diff line number Diff line change
@@ -1,162 +1,112 @@
"""
$(TYPEDSIGNATURES)
symbolic_container(p)
Get an iterable over the independent variables for the given system. Default to an empty
vector.
"""
function independent_variables end
independent_variables(::Any) = []
Using `p`, return an object that implements the symbolic indexing interface. In case `p`
itself implements the interface, `p` can be returned as-is. All symbolic indexing interface
methods fall back to calling the same method on `symbolic_container(p)`, so this may be
used for trivial implementations of the interface that forward all calls to another object.
This is also used by [`ParameterIndexingProxy`](@ref)
"""
$(TYPEDSIGNATURES)
function symbolic_container end

Check if the given sym is an independent variable in the given system. Default to checking
if the given `sym` exists in the iterable returned by `independent_variables`.
"""
function is_indep_sym end

function is_indep_sym(store, sym)
any(isequal(Symbol(sym)), Symbol.(independent_variables(store)))
end
is_variable(sys, sym)
Check whether the given `sym` is a variable in `sys`.
"""
$(TYPEDSIGNATURES)
is_variable(sys, sym) = is_variable(symbolic_container(sys), sym)

Get an iterable over the states for the given system. Default to an empty vector.
"""
function states end

states(::Any) = []
variable_index(sys, sym, [i])
Return the index of the given variable `sym` in `sys`, or `nothing` otherwise. If
[`constant_structure`](@ref) is `false`, this accepts the current time index as an
additional parameter `i`.
"""
$(TYPEDSIGNATURES)
variable_index(sys, sym) = variable_index(symbolic_container(sys), sym)
variable_index(sys, sym, i) = variable_index(symbolic_container(sys), sym, i)

Get an iterable over the unknown states for the given system. Default to an empty vector.
"""
function unknown_states end

unknown_states(::Any) = []
variable_symbols(sys, [i])
Return a vector of the symbolic variables being solved for in the system `sys`. If
`constant_structure(sys) == false` this accepts an additional parameter indicating
the current time index. The returned vector should not be mutated.
"""
$(TYPEDSIGNATURES)
variable_symbols(sys) = variable_symbols(symbolic_container(sys))
variable_symbols(sys, i) = variable_symbols(symbolic_container(sys), i)

Find the index of the given sym in the given system. Default to the index of the first
symbol in the iterable returned by `states` which matches the given `sym`. Return
`nothing` if the given `sym` does not match.
"""
function state_sym_to_index end

function state_sym_to_index(store, sym)
findfirst(isequal(Symbol(sym)), Symbol.(states(store)))
end
is_parameter(sys, sym)
Check whether the given `sym` is a parameter in `sys`.
"""
$(TYPEDSIGNATURES)
is_parameter(sys, sym) = is_parameter(symbolic_container(sys), sym)

Check if the given sym is a state variable in the given system. Default to checking if
the value returned by `state_sym_to_index` is not `nothing`.
"""
function is_state_sym end

is_state_sym(store, sym) = !isnothing(state_sym_to_index(store, sym))
parameter_index(sys, sym)
Return the index of the given parameter `sym` in `sys`, or `nothing` otherwise.
"""
$(TYPEDSIGNATURES)
parameter_index(sys, sym) = parameter_index(symbolic_container(sys), sym)

Get an iterable over the parameters variables for the given system. Default to an empty
vector.
"""
function parameters end

parameters(::Any) = []
parameter_symbols(sys)
Return a vector of the symbolic parameters of the given system `sys`. The returned
vector should not be mutated.
"""
$(TYPEDSIGNATURES)
parameter_symbols(sys) = parameter_symbols(symbolic_container(sys))

Find the index of the given sym in the given system. Default to the index of the first
symbol in the iterable retruned by `parameters` which matches the given `sym`. Return
`nothing` if the given `sym` does not match.
"""
function param_sym_to_index end

param_sym_to_index(store, sym) = findfirst(isequal(Symbol(sym)), Symbol.(parameters(store)))
is_independent_variable(sys, sym)
Check whether the given `sym` is an independent variable in `sys`. The returned vector
should not be mutated.
"""
$(TYPEDSIGNATURES)
is_independent_variable(sys, sym) = is_independent_variable(symbolic_container(sys), sym)

Check if the given sym is a parameter variable in the given system. Default
to checking if the value returned by `param_sym_to_index` is not `nothing`.
"""
function is_param_sym end

is_param_sym(store, sym) = !isnothing(param_sym_to_index(store, sym))
independent_variable_symbols(sys)
Return a vector of the symbolic independent variables of the given system `sys`.
"""
$(TYPEDSIGNATURES)
independent_variable_symbols(sys) = independent_variable_symbols(symbolic_container(sys))

Get an iterable over the observed variable expressions for the given system.
Default to an empty vector.
"""
function observed end

observed(::Any) = []
is_observed(sys, sym)
Check whether the given `sym` is an observed value in `sys`.
"""
$(TYPEDSIGNATURES)
is_observed(sys, sym) = is_observed(symbolic_container(sys), sym)

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

Find the index of the given sym in the given system. Default to the index of the first
symbol in the iterable returned by `states` which matches the given `sym`. Return
`nothing` if the given `sym` does not match.
"""
function observed_sym_to_index end

function observed_sym_to_index(store, sym)
findfirst(o -> isequal(sym, o.lhs), observed(store))
end
is_time_dependent(sys)
Check if `sys` has time as (one of) its independent variables.
"""
$(TYPEDSIGNATURES)
is_time_dependent(sys) = is_time_dependent(symbolic_container(sys))

Return a list of the dependent state variables of an observed variable. Default to returning
an empty list.
"""
function get_state_dependencies end
constant_structure(sys)
get_state_dependencies(store, sym) = []

"""
$(TYPEDSIGNATURES)
Return a list of the dependent observed variables of an observed variable. Default to returning
an empty list.
"""
function get_observed_dependencies end

get_observed_dependencies(store, sym) = []

"""
$(TYPEDSIGNATURES)
Return a list of the dependent state variables of all observed equations of the system.
Default to returning an empty list.
Check if `sys` has a constant structure. Constant structure systems do not change the
number of variables or parameters over time.
"""
function get_deps_of_observed end

function get_deps_of_observed(store)
obs = observed(store)
deps = mapreduce(vcat, obs, init = []) do eq
get_state_dependencies(store, eq.lhs)
end |> unique

return deps
end
constant_structure(sys) = constant_structure(symbolic_container(sys))
Loading

0 comments on commit af679a3

Please sign in to comment.