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

fix: observed getu generation, tuple wrapper #72

Merged
merged 4 commits into from
May 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "SymbolicIndexingInterface"
uuid = "2efcf032-c050-4f8e-a9bb-153293bab1f5"
authors = ["Aayush Sabharwal <[email protected]> and contributors"]
version = "0.3.19"
version = "0.3.20"

[deps]
Accessors = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697"
Expand Down
1 change: 1 addition & 0 deletions docs/pages.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

pages = [
"Home" => "index.md",
"Terminology" => "terminology.md",
"Tutorials" => [
"Using the SciML Symbolic Indexing Interface" => "usage.md",
"Simple Demonstration of a Symbolic System Structure" => "simple_sii_sys.md",
Expand Down
45 changes: 25 additions & 20 deletions docs/src/api.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Interface Functions

## Mandatory methods
## Index provider interface

### Mandatory methods

```@docs
symbolic_container
Expand All @@ -22,14 +24,16 @@ solvedvariables
allvariables
```

## Optional Methods
### Optional Methods

### Observed equation handling
#### Observed equation handling

```@docs
observed
```

## Value provider interface

### Parameter indexing

```@docs
Expand All @@ -41,6 +45,19 @@ setp
ParameterIndexingProxy
```

#### Parameter timeseries

If a solution object saves a timeseries of parameter values that are updated during the
simulation (such as by callbacks), it must implement the following methods to ensure
correct functioning of [`getu`](@ref) and [`getp`](@ref).

```@docs
parameter_timeseries
parameter_values_at_time
parameter_values_at_state_time
```


### State indexing

```@docs
Expand All @@ -54,22 +71,17 @@ getu
setu
```

## Container objects
### Batched Queries and Updates

```@docs
remake_buffer
BatchedInterface
associated_systems
```

### Parameter timeseries

If a solution object saves a timeseries of parameter values that are updated during the
simulation (such as by callbacks), it must implement the following methods to ensure
correct functioning of [`getu`](@ref) and [`getp`](@ref).
## Container objects

```@docs
parameter_timeseries
parameter_values_at_time
parameter_values_at_state_time
remake_buffer
```

# Symbolic Trait
Expand All @@ -90,10 +102,3 @@ symbolic_evaluate
SymbolCache
ProblemState
```

### Batched Queries and Updates

```@docs
BatchedInterface
associated_systems
```
61 changes: 61 additions & 0 deletions docs/src/terminology.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Terminology

SymbolicIndexingInterface.jl uses various library-specific terminology throughout its
documentation. This page attempts to provide comprehensive explanations of the terms
used.

## Indexes

An index is an object that defines how to extract specific data from a data structure.
Indexes may be anything from integer indexes into arrays, to custom types that contain
information specific to a particular data structure.

In code samples, an index is typically denoted with the name `idx` or `i`.

## Symbolic variables

Symbolic variables are objects that represent quantities (states, parameters, time, etc.)
or collections of quantities used in a numerical simulation in a more human-accessible
manner. Typically the values of these quantities are stored in custom data structures
and referred to using indexes that do not convey any semantic meaning to users. Symbolic
variables cannot directly be used to access values from these data structures and need
to be translated into indexes.

In code samples, a symbolic variable is typically denoted with the name `sym`.

Symbolic variables are also sometimes referred to as "symbolic indices".

## Index providers

Index providers translate symbolic variables into indexes. In general, an "index" can
be anything from integer indexes into an array, or custom types that define how to
index into complicated data structures. `nothing` is reserved to denote the absence of
an index, in cases where the index provider is unaware of a particular symbolic variable.
It cannot be used as an index. ModelingToolkit.jl systems are examples of index providers.

In code samples, an index provider is typically denoted with the name `indp`.

## Value providers

Value providers store values of symbolic variables. Given an appropriate index from an
index provider, value providers return the value (or values) stored at that index. The
problem, integrator and solution types in SciML are all examples of value providers.
Each value provider is (directly or indirectly) associated with an index provider that
defines the set of valid symbolic variables for that value provider, and the corresponding
indexes.

A value provider may not store values for all symbolic variables in the corresponding index
provider. For example, a parameter object (even a plain `Array` storing parameter values)
is a value provider specifically for the symbolic variables referring to parameters.

In code samples, a value provider is typically denoted with the name `valp`.

!!! note
It is important to note that an object may be both a value- and index- provider. For
example, SciML's problem, integrator and solution types are both value- and index-
providers. This allows for several syntactic improvements. The [`symbolic_container`](@ref)
function is useful in defining such objects.

!!! note "Timeseries objects"
The documentation uses "Timeseries objects" to refer to value providers which implement
the [`Timeseries`](@ref) variant of the [`is_timeseries`](@ref) trait.
2 changes: 1 addition & 1 deletion src/SymbolicIndexingInterface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export is_variable, variable_index, variable_symbols, is_parameter, parameter_in
observed, is_time_dependent, constant_structure, symbolic_container,
all_variable_symbols,
all_symbols, solvedvariables, allvariables, default_values, symbolic_evaluate
include("interface.jl")
include("index_provider_interface.jl")

export SymbolCache
include("symbol_cache.jl")
Expand Down
57 changes: 29 additions & 28 deletions src/batched_interface.jl
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
"""
struct BatchedInterface{S <: AbstractVector, I}
function BatchedInterface(syssyms::Tuple...)
function BatchedInterface(indp_syms::Tuple...)

A struct which stores information for batched calls to [`getu`](@ref) or [`setu`](@ref).
Given `Tuple`s, where the first element of each tuple is a system and the second an
array of symbols (either variables or parameters) in the system, `BatchedInterface` will
compute the union of all symbols and associate each symbol with the first system with
which it occurs.
Given `Tuple`s, where the first element of each tuple is an index provider and the second
an array of symbolic variables (either states or parameters) in the index provider,
`BatchedInterface` will compute the union of all symbols and associate each symbol with
the first index provider with which it occurs.

For example, given two systems `s1 = SymbolCache([:x, :y, :z])` and
For example, given two index providers `s1 = SymbolCache([:x, :y, :z])` and
`s2 = SymbolCache([:y, :z, :w])`, `BatchedInterface((s1, [:x, :y]), (s2, [:y, :z]))` will
associate `:x` and `:y` with `s1` and `:z` with `s2`. The information that `s1` had
associated symbols `:x` and `:y` and `s2` had associated symbols `:y` and `:z` will also
Expand All @@ -24,17 +24,17 @@ See also: [`associated_systems`](@ref).
struct BatchedInterface{S <: AbstractVector, I, T}
"Order of symbols in the union."
symbol_order::S
"Index of the system each symbol in the union is associated with."
"Index of the index provider each symbol in the union is associated with."
associated_systems::Vector{Int}
"Index of symbol in the system it is associated with."
"Index of symbol in the index provider it is associated with."
associated_indexes::I
"Whether the symbol is a state in the system it is associated with."
"Whether the symbol is a state in the index provider it is associated with."
isstate::BitVector
"Map from system to indexes of its symbols in the union."
"Map from index provider to indexes of its symbols in the union."
system_to_symbol_subset::Vector{Vector{Int}}
"Map from system to indexes of its symbols in the system."
"Map from index provider to indexes of its symbols in the index provider."
system_to_symbol_indexes::Vector{Vector{T}}
"Map from system to whether each of its symbols is a state in the system."
"Map from index provider to whether each of its symbols is a state in the index provider."
system_to_isstate::Vector{BitVector}
end

Expand Down Expand Up @@ -102,26 +102,27 @@ is_variable(bi::BatchedInterface, sym) = variable_index(bi, sym) !== nothing
associated_systems(bi::BatchedInterface)

Return an array of integers of the same length as `variable_symbols(bi)` where each value
is the index of the system associated with the corresponding symbol in
is the index of the index provider associated with the corresponding symbol in
`variable_symbols(bi)`.
"""
associated_systems(bi::BatchedInterface) = bi.associated_systems

"""
getu(bi::BatchedInterface)

Given a [`BatchedInterface`](@ref) composed from `n` systems (and corresponding symbols),
return a function which takes `n` corresponding problems and returns an array of the values
of the symbols in the union. The returned function can also be passed an `AbstractArray` of
the appropriate `eltype` and size as its first argument, in which case the operation will
populate the array in-place with the values of the symbols in the union.
Given a [`BatchedInterface`](@ref) composed from `n` index providers (and corresponding
symbols), return a function which takes `n` corresponding value providers and returns an
array of the values of the symbols in the union. The returned function can also be passed
an `AbstractArray` of the appropriate `eltype` and size as its first argument, in which
case the operation will populate the array in-place with the values of the symbols in the
union.

Note that all of the problems passed to the function returned by `getu` must satisfy
Note that all of the value providers passed to the function returned by `getu` must satisfy
`is_timeseries(prob) === NotTimeseries()`.

The value of the `i`th symbol in the union (obtained through `variable_symbols(bi)[i]`) is
obtained from the problem corresponding to the associated system (i.e. the problem at
index `associated_systems(bi)[i]`).
obtained from the problem corresponding to the associated index provider (i.e. the value
provider at index `associated_systems(bi)[i]`).

See also: [`variable_symbols`](@ref), [`associated_systems`](@ref), [`is_timeseries`](@ref),
[`NotTimeseries`](@ref).
Expand Down Expand Up @@ -180,16 +181,16 @@ end
"""
setu(bi::BatchedInterface)

Given a [`BatchedInterface`](@ref) composed from `n` systems (and corresponding symbols),
return a function which takes `n` corresponding problems and an array of the values, and
updates each of the problems with the values of the corresponding symbols.
Given a [`BatchedInterface`](@ref) composed from `n` index providers (and corresponding
symbols), return a function which takes `n` corresponding problems and an array of the
values, and updates each of the problems with the values of the corresponding symbols.

Note that all of the problems passed to the function returned by `setu` must satisfy
Note that all of the value providers passed to the function returned by `setu` must satisfy
`is_timeseries(prob) === NotTimeseries()`.

Note that if any subset of the `n` systems share common symbols (among those passed to
`BatchedInterface`) then all of the corresponding problems in the subset will be updated
with the values of the common symbols.
Note that if any subset of the `n` index providers share common symbols (among those passed
to `BatchedInterface`) then all of the corresponding value providers in the subset will be
updated with the values of the common symbols.

See also: [`is_timeseries`](@ref), [`NotTimeseries`](@ref).
"""
Expand Down
Loading
Loading