Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: indexing rework #12

Merged
merged 35 commits into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
0e6e9e7
feat!: rework interface
AayushSabharwal Oct 20, 2023
cf92a76
test: add tests
AayushSabharwal Oct 20, 2023
ced1e65
refactor: formatting
AayushSabharwal Oct 20, 2023
b7f47d2
feat: bump major version
AayushSabharwal Oct 20, 2023
08d8dbb
docs: update docs compat and docstrings
AayushSabharwal Oct 20, 2023
5a96b7a
feat: add `IsSymbolic` trait
AayushSabharwal Oct 20, 2023
37eda77
feat: add extensions for Symbolics and SymbolicUtils
AayushSabharwal Oct 20, 2023
423e611
refactor: split into multiple files
AayushSabharwal Oct 20, 2023
1fe9d57
feat: add pre-1.9 compat using Requires
AayushSabharwal Oct 20, 2023
95e6c1b
fix: conditional import in extensions
AayushSabharwal Oct 20, 2023
9bea164
feat: support nonstatic states, normalize function names
AayushSabharwal Oct 23, 2023
859e130
test: add trait tests
AayushSabharwal Oct 23, 2023
51ad41f
fixup! test: add trait tests
AayushSabharwal Oct 23, 2023
66e59f2
fix: move Requires.jl import
AayushSabharwal Oct 23, 2023
52fc726
feat: rework trait
AayushSabharwal Oct 27, 2023
9885731
feat: add current_state, refactor observed, update tests
AayushSabharwal Oct 27, 2023
15a987b
feat: update interface, tests
AayushSabharwal Oct 31, 2023
c1821c9
feat: add SymbolCache
AayushSabharwal Nov 3, 2023
c6a1036
refactor: remove has_static_variable
AayushSabharwal Nov 3, 2023
916c7f1
docs: update api.md
AayushSabharwal Nov 3, 2023
9204fc5
feat: add Base.copy method for SymbolCache
AayushSabharwal Nov 6, 2023
8f786f3
feat: add functions to get vector of symbols from system
AayushSabharwal Nov 7, 2023
5fb4928
feat: add getname to API
AayushSabharwal Nov 14, 2023
064d9f0
refactor: remove SymbolicsExt
AayushSabharwal Nov 20, 2023
5b6e191
feat: add `hasname` function
AayushSabharwal Nov 21, 2023
7237205
refactor: fix SymbolCache SII methods
AayushSabharwal Nov 24, 2023
6a823db
docs: improve ArraySymbolic docstring
AayushSabharwal Nov 24, 2023
b8ff5ba
feat: add symbolic_container, ParameterIndexingProxy, parameter_value…
AayushSabharwal Nov 24, 2023
4e75bff
refactor: add PARAMETER_INDEXING_PROXY_PROPERTY_NAME
AayushSabharwal Nov 24, 2023
a110ee4
refactor: remove ParameterIndexingProxy, add get_p and set_p functions
AayushSabharwal Nov 28, 2023
b4e781c
refactor: rework SymbolCache
AayushSabharwal Nov 29, 2023
2f13f30
docs: add a couple functions to api.md
AayushSabharwal Dec 11, 2023
1e5450b
test: move Symbolics tests to Symbolics downstream
AayushSabharwal Dec 11, 2023
b243589
refactor: format
AayushSabharwal Dec 11, 2023
7a5c62f
refactor: remove SymbolicUtils extension
AayushSabharwal Dec 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
name = "SymbolicIndexingInterface"
uuid = "2efcf032-c050-4f8e-a9bb-153293bab1f5"
authors = ["Aayush Sabharwal <[email protected]> and contributors"]
version = "0.2.2"
version = "0.3.0"

[deps]
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
Requires = "ae029012-a4dd-5104-9daa-d747884805df"

[weakdeps]
SymbolicUtils = "d1185830-fcd6-423d-90d6-eec64667417b"
Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7"

[extensions]
SymbolicIndexingInterfaceSymbolicUtilsExt = "SymbolicUtils"
SymbolicIndexingInterfaceSymbolicsExt = "Symbolics"

[compat]
DocStringExtensions = "0.9"
Requires = "1.0"
SymbolicUtils = "1.4"
Symbolics = "5.10"
julia = "1"

[extras]
SymbolicUtils = "d1185830-fcd6-423d-90d6-eec64667417b"
Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test"]
test = ["SymbolicUtils", "Symbolics","Test"]
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)
33 changes: 22 additions & 11 deletions docs/src/api.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
# Interface Functions

Default methods cast all symbols to `Symbol` before comparing.
```@docs
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
```

# 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
```

## 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
14 changes: 14 additions & 0 deletions ext/SymbolicIndexingInterfaceSymbolicUtilsExt.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module SymbolicIndexingInterfaceSymbolicUtilsExt

using SymbolicIndexingInterface
@static if isdefined(Base, :get_extension)
using SymbolicUtils
else
using ..SymbolicUtils
end

function SymbolicIndexingInterface.symbolic_type(::Type{<:SymbolicUtils.BasicSymbolic})
ScalarSymbolic()

Check warning on line 11 in ext/SymbolicIndexingInterfaceSymbolicUtilsExt.jl

View check run for this annotation

Codecov / codecov/patch

ext/SymbolicIndexingInterfaceSymbolicUtilsExt.jl#L10-L11

Added lines #L10 - L11 were not covered by tests
end

end
14 changes: 14 additions & 0 deletions ext/SymbolicIndexingInterfaceSymbolicsExt.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module SymbolicIndexingInterfaceSymbolicsExt

using SymbolicIndexingInterface

@static if isdefined(Base, :get_extension)
using Symbolics
else
using ..Symbolics
end

SymbolicIndexingInterface.symbolic_type(::Type{<:Symbolics.Num}) = ScalarSymbolic()
SymbolicIndexingInterface.symbolic_type(::Type{<:Symbolics.Arr}) = ArraySymbolic()

Check warning on line 12 in ext/SymbolicIndexingInterfaceSymbolicsExt.jl

View check run for this annotation

Codecov / codecov/patch

ext/SymbolicIndexingInterfaceSymbolicsExt.jl#L11-L12

Added lines #L11 - L12 were not covered by tests

end
22 changes: 16 additions & 6 deletions src/SymbolicIndexingInterface.jl
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
module SymbolicIndexingInterface

using DocStringExtensions
using Requires

export ScalarSymbolic, ArraySymbolic, NotSymbolic, symbolic_type
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
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")

@static if !isdefined(Base, :get_extension)
function __init__()
@require Symbolics="0c5d862f-8b57-4792-8d23-62f2024744c7" include("../ext/SymbolicIndexingInterfaceSymbolicsExt.jl")
@require SymbolicUtils="d1185830-fcd6-423d-90d6-eec64667417b" include("../ext/SymbolicIndexingInterfaceSymbolicUtilsExt.jl")

Check warning on line 19 in src/SymbolicIndexingInterface.jl

View check run for this annotation

Codecov / codecov/patch

src/SymbolicIndexingInterface.jl#L17-L19

Added lines #L17 - L19 were not covered by tests
end
end

end
163 changes: 49 additions & 114 deletions src/interface.jl
Original file line number Diff line number Diff line change
@@ -1,162 +1,97 @@
"""
$(TYPEDSIGNATURES)
is_variable(sys, sym)

Get an iterable over the independent variables for the given system. Default to an empty
vector.
Check whether the given `sym` is a variable in `sys`.
"""
function independent_variables end
independent_variables(::Any) = []
function is_variable end

"""
$(TYPEDSIGNATURES)
variable_index(sys, sym, [i])

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`.
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`.
"""
function is_indep_sym end

function is_indep_sym(store, sym)
any(isequal(Symbol(sym)), Symbol.(independent_variables(store)))
end

"""
$(TYPEDSIGNATURES)

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

states(::Any) = []

"""
$(TYPEDSIGNATURES)

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

unknown_states(::Any) = []
function variable_index end

"""
$(TYPEDSIGNATURES)

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
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)
function variable_symbols end

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))
is_parameter(sys, sym)

Check whether the given `sym` is a parameter in `sys`.
"""
$(TYPEDSIGNATURES)
function is_parameter end

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

parameters(::Any) = []
parameter_index(sys, sym)

Return the index of the given parameter `sym` in `sys`, or `nothing` otherwise.
"""
$(TYPEDSIGNATURES)
function parameter_index end

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)))
parameter_symbols(sys)

Return a vector of the symbolic parameters of the given system `sys`. The returned
vector should not be mutated.
"""
$(TYPEDSIGNATURES)
function parameter_symbols end

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))
is_independent_variable(sys, sym)

Check whether the given `sym` is an independent variable in `sys`. The returned vector
should not be mutated.
"""
$(TYPEDSIGNATURES)
function is_independent_variable end

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

observed(::Any) = []
independent_variable_symbols(sys)

Return a vector of the symbolic independent variables of the given system `sys`.
"""
$(TYPEDSIGNATURES)
function independent_variable_symbols end

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

is_observed_sym(store, sym) = !isnothing(observed_sym_to_index(store, sym))
is_observed(sys, sym)

Check whether the given `sym` is an observed value in `sys`.
"""
$(TYPEDSIGNATURES)
function is_observed end

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
observed(sys, sym, [states])

function observed_sym_to_index(store, sym)
findfirst(o -> isequal(sym, o.lhs), observed(store))
end
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)
function observed end

Return a list of the dependent state variables of an observed variable. Default to returning
an empty list.
"""
function get_state_dependencies end

get_state_dependencies(store, sym) = []
is_time_dependent(sys)

Check if `sys` has time as (one of) its independent variables.
"""
$(TYPEDSIGNATURES)
function is_time_dependent end

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) = []
constant_structure(sys)

Check if `sys` has a constant structure. Constant structure systems do not change the
number of variables or parameters over time.
"""
$(TYPEDSIGNATURES)

Return a list of the dependent state variables of all observed equations of the system.
Default to returning an empty list.
"""
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
function constant_structure end
Loading
Loading