Skip to content
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
4 changes: 1 addition & 3 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ version = "4.3.6"
[deps]
Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
ArrayInterface = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9"
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
Expand Down Expand Up @@ -53,7 +52,6 @@ RecursiveArrayToolsZygoteExt = "Zygote"
Adapt = "4"
ArrayInterface = "7.17.0"
CUDA = "5, 6.0"
DocStringExtensions = "0.9.3"
FastBroadcast = "1.3"
ForwardDiff = "0.10.38, 1"
GPUArraysCore = "0.2"
Expand All @@ -71,7 +69,7 @@ RecursiveArrayToolsShorthandConstructors = "1"
ReverseDiff = "1.15"
SafeTestsets = "0.1"
SciMLPublic = "1"
SciMLTesting = "2.1"
SciMLTesting = "2.4"
SparseArrays = "1.10"
StaticArrays = "1.6"
StaticArraysCore = "1.4.2"
Expand Down
4 changes: 2 additions & 2 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ makedocs(
sitename = "RecursiveArrayTools.jl",
authors = "Chris Rackauckas",
modules = [RecursiveArrayTools, RecursiveArrayToolsRaggedArrays],
clean = true, doctest = false, linkcheck = true,
warnonly = [:missing_docs],
clean = true, doctest = true, linkcheck = true,
checkdocs = :exports,
format = Documenter.HTML(
assets = ["assets/favicon.ico"],
canonical = "https://docs.sciml.ai/RecursiveArrayTools/stable/"
Expand Down
8 changes: 8 additions & 0 deletions docs/src/array_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,13 @@ NamedArrayPartition
```@docs
VA
AP
```

## Developer Interfaces

`AllObserved` is intended for packages extending symbolic indexing of differential-equation
arrays. Application code should use the ordinary symbolic indexing interface.

```@docs
AllObserved
```
4 changes: 4 additions & 0 deletions docs/src/index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# RecursiveArrayTools.jl: Arrays of Arrays and Even Deeper

```@docs
RecursiveArrayTools
```

RecursiveArrayTools.jl is a set of tools for dealing with recursive arrays, like
arrays of arrays. It contains type wrappers for making recursive arrays act more
like normal arrays (for example, automating the recursion of broadcast, maps,
Expand Down
4 changes: 4 additions & 0 deletions docs/src/plotting.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ when plotting solution objects.

## Plot Helper API

!!! warning "Developer API"
These helpers support plot recipe implementations in packages such as SciMLBase. Application
code should use the plotting interfaces described above instead of depending on these helpers.

```@docs
DEFAULT_PLOT_FUNC
plottable_indices
Expand Down
3 changes: 3 additions & 0 deletions docs/src/ragged_arrays.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,9 @@ structure and access elements without implicit zeros.

## API Reference

The abstract types below are developer interfaces for packages implementing ragged containers.
Application code should construct `RaggedVectorOfArray` or `RaggedDiffEqArray`.

```@docs
RecursiveArrayTools.AbstractRaggedVectorOfArray
RecursiveArrayTools.AbstractRaggedDiffEqArray
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
[deps]
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b"
RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd"
RecursiveArrayToolsArrayPartitionAnyAll = "172d604e-c495-4f00-97bf-d70957099afa"
SciMLTesting = "09d9d899-5365-40a9-917a-5f67fddea283"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[sources]
RecursiveArrayToolsArrayPartitionAnyAll = {path = "../.."}

[compat]
Aqua = "0.8"
JET = "0.9, 0.10, 0.11"
RecursiveArrayTools = "4"
RecursiveArrayToolsArrayPartitionAnyAll = "1"
SciMLTesting = "1.6, 2.1"
SciMLTesting = "2.4"
Test = "1"
julia = "1.10"
3 changes: 1 addition & 2 deletions lib/RecursiveArrayToolsArrayPartitionAnyAll/test/qa/qa.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ const RATAPAA = RecursiveArrayToolsArrayPartitionAnyAll

run_qa(
RATAPAA;
explicit_imports = true,
# `any`/`all` are extended on the RecursiveArrayTools-owned `ArrayPartition`
# type, so they are intentional (owned) methods, not piracy.
aqua_kwargs = (; piracies = (; treat_as_own = [RATAPAA.ArrayPartition])),
jet_kwargs = (; target_defined_modules = true),
jet_kwargs = (; target_modules = (RATAPAA,)),
)
16 changes: 6 additions & 10 deletions lib/RecursiveArrayToolsArrayPartitionAnyAll/test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,12 @@ const TEST_GROUP = get(ENV, "RECURSIVEARRAYTOOLS_TEST_GROUP", "Core")

function activate_qa_env()
Pkg.activate(joinpath(@__DIR__, "qa"))
# On Julia < 1.11, the [sources] section in the qa Project.toml is not
# honored, so Pkg.develop the local paths explicitly.
if VERSION < v"1.11.0-DEV.0"
Pkg.develop(
[
PackageSpec(path = dirname(@__DIR__)),
PackageSpec(path = normpath(joinpath(dirname(@__DIR__), "..", ".."))),
]
)
end
Pkg.develop(
[
PackageSpec(path = dirname(@__DIR__)),
PackageSpec(path = normpath(joinpath(dirname(@__DIR__), "..", ".."))),
]
)
return Pkg.instantiate()
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,76 +4,66 @@ import RecursiveArrayTools: RecursiveArrayTools, AbstractRaggedVectorOfArray,
AbstractRaggedDiffEqArray, VectorOfArray, DiffEqArray,
AbstractVectorOfArray, AbstractDiffEqArray,
recursivefill!, recursivecopy!
using SymbolicIndexingInterface
import Adapt
import ArrayInterface
import StaticArraysCore
import SymbolicIndexingInterface
using SymbolicIndexingInterface: ParameterTimeseriesCollection, ParameterIndexingProxy,
ScalarSymbolic, ArraySymbolic, NotSymbolic, Timeseries, SymbolCache
using Adapt
using ArrayInterface
using StaticArraysCore
ScalarSymbolic, ArraySymbolic, NotSymbolic, Timeseries, SymbolCache,
all_variable_symbols, getu, is_parameter, is_timeseries_parameter, observed,
parameter_values, symbolic_container, symbolic_type, variable_symbols
using LinearAlgebra: Adjoint

export RaggedVectorOfArray, RaggedDiffEqArray

# Based on code from M. Bauman Stackexchange answer + Gitter discussion

"""
```julia
RaggedVectorOfArray(u::AbstractVector)
```

A `RaggedVectorOfArray` is an array which has the underlying data structure `Vector{AbstractArray{T}}`
(but, hopefully, concretely typed!). This wrapper over such data structures allows one to lazily
act like it's a higher-dimensional vector, and easily convert it to different forms. The indexing
structure is:

```julia
A.u[i] # Returns the ith array in the vector of arrays
A[j, i] # Returns the jth component in the ith array
A[j1, ..., jN, i] # Returns the (j1,...,jN) component of the ith array
```
RaggedVectorOfArray(u::AbstractVector)

which presents itself as a column-major matrix with the columns being the arrays from the vector.
The `AbstractArray` interface is implemented, giving access to `copy`, `push`, `append!`, etc. functions,
which act appropriately. Points to note are:
Wrap a collection of arrays while preserving each array's shape. Unlike `VectorOfArray`,
this type does not present zero-padded ragged data as a rectangular `AbstractArray`.

- The length is the number of vectors, or `length(A.u)` where `u` is the vector of arrays.
- Iteration follows the linear index and goes over the vectors
# Fields

Additionally, the `convert(Array,VA::AbstractRaggedVectorOfArray)` function is provided, which transforms
the `RaggedVectorOfArray` into a matrix/tensor. Also, `vecarr_to_vectors(VA::AbstractRaggedVectorOfArray)`
returns a vector of the series for each component, that is, `A[i,:]` for each `i`.
- `u`: the collection of stored arrays.

There is also support for `RaggedVectorOfArray` constructed from multi-dimensional arrays
# Examples

```julia
RaggedVectorOfArray(u::AbstractArray{AT}) where {T, N, AT <: AbstractArray{T, N}}
A = RaggedVectorOfArray([[1, 2], [3, 4, 5]])
A[:, 1] == [1, 2]
A[end, 2] == 5
```

where `IndexStyle(typeof(u)) isa IndexLinear`.
"""
mutable struct RaggedVectorOfArray{T, N, A} <: AbstractRaggedVectorOfArray{T, N, A}
u::A # A <: AbstractArray{<: AbstractArray{T, N - 1}}
end
# RaggedVectorOfArray with an added series for time

"""
```julia
RaggedDiffEqArray(u::AbstractVector, t::AbstractVector)
```
RaggedDiffEqArray(u::AbstractVector, t::AbstractVector; kwargs...)

Wrap ragged saved states `u` and matching time points `t` with differential-equation and
symbolic-indexing metadata.

# Fields

This is a `RaggedVectorOfArray`, which stores `A.t` that matches `A.u`. This will plot
`(A.t[i],A[i,:])`. The function `tuples(diffeq_arr)` returns tuples of `(t,u)`.
- `u`: the saved ragged state arrays.
- `t`: the time corresponding to each entry of `u`.
- `p`: parameter values associated with the solution.
- `sys`: symbolic indexing metadata.
- `discretes`: discrete parameter timeseries, or `nothing`.
- `interp`: interpolation object for dense output, or `nothing`.
- `dense`: whether dense interpolation is available.

To construct a RaggedDiffEqArray
# Examples

```julia
t = 0.0:0.1:10.0
f(t) = t - 1
f2(t) = t^2
vals = [[f(tval) f2(tval)] for tval in t]
A = RaggedDiffEqArray(vals, t)
A[1, :] # all time periods for f(t)
A.t
t = [0.0, 1.0]
u = [[1.0, 2.0], [3.0, 4.0, 5.0]]
A = RaggedDiffEqArray(u, t)
A[:, 2] == [3.0, 4.0, 5.0]
```
"""
mutable struct RaggedDiffEqArray{
Expand Down
7 changes: 3 additions & 4 deletions lib/RecursiveArrayToolsRaggedArrays/test/qa/Project.toml
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
[deps]
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b"
RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd"
RecursiveArrayToolsRaggedArrays = "c384ba91-639a-44ca-823a-e1d3691ab84a"
SciMLTesting = "09d9d899-5365-40a9-917a-5f67fddea283"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[sources]
RecursiveArrayToolsRaggedArrays = {path = "../.."}

[compat]
Aqua = "0.8"
JET = "0.9, 0.10, 0.11"
RecursiveArrayTools = "4"
RecursiveArrayToolsRaggedArrays = "1"
SciMLTesting = "1.6, 2.1"
SciMLTesting = "2.4"
Test = "1"
julia = "1.10"
18 changes: 4 additions & 14 deletions lib/RecursiveArrayToolsRaggedArrays/test/qa/qa.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ using SciMLTesting, RecursiveArrayToolsRaggedArrays, JET, Test

run_qa(
RecursiveArrayToolsRaggedArrays;
explicit_imports = true,
# The arithmetic/array methods (`*`, `+`, `Array`, `copyto!`, ...) are defined on
# the RecursiveArrayTools-owned `AbstractRaggedVectorOfArray` /
# `AbstractRaggedDiffEqArray` abstract types, so they are intentional (owned)
Expand All @@ -15,23 +14,17 @@ run_qa(
],
),
),
jet_kwargs = (; target_defined_modules = true),
jet_kwargs = (; target_modules = (RecursiveArrayToolsRaggedArrays,)),
# Pre-existing JET typo-mode finding (reproduces byte-identically on master):
# the `copyto!`/`fill!`/broadcast immutable-element branches call
# `StaticArraysCore.similar_type(dest.u[i])`, but `dest.u[i]` infers as `::Any`
# because the abstract `AbstractRaggedVectorOfArray` `.u` field is untyped, so
# `similar_type(::Any)` has no matching method. Tracked (with the real fix —
# tightening the `.u` type / guarding the immutable branch) in
# https://github.com/SciML/RecursiveArrayTools.jl/issues/620. `jet_broken`
# auto-flags an Unexpected Pass once that fix lands, prompting removal.
jet_broken = true,
# https://github.com/SciML/RecursiveArrayTools.jl/issues/620. JET 0.9 on Julia
# 1.10 does not report this finding, so keep that stricter lane unbroken.
jet_broken = VERSION >= v"1.11",
ei_kwargs = (;
# `AbstractRaggedVectorOfArray`/`AbstractRaggedDiffEqArray` are
# RecursiveArrayTools-owned abstract types this subpackage subtypes; they are
# not (yet) declared public in RecursiveArrayTools.
all_explicit_imports_are_public = (;
ignore = (:AbstractRaggedVectorOfArray, :AbstractRaggedDiffEqArray),
),
# Non-public names legitimately qualified/imported from upstream packages
# (Base, Base.Broadcast, StaticArraysCore, ArrayInterface, Adapt,
# SymbolicIndexingInterface). Not this subpackage's to make public.
Expand All @@ -47,7 +40,4 @@ run_qa(
),
),
),
# Whole-module `using` exposes many names implicitly; explicit-import refactor
# tracked in https://github.com/SciML/RecursiveArrayTools.jl/issues/619
ei_broken = (:no_implicit_imports,),
)
16 changes: 6 additions & 10 deletions lib/RecursiveArrayToolsRaggedArrays/test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,12 @@ const TEST_GROUP = get(ENV, "RECURSIVEARRAYTOOLS_TEST_GROUP", "Core")

function activate_qa_env()
Pkg.activate(joinpath(@__DIR__, "qa"))
# On Julia < 1.11, the [sources] section in the qa Project.toml is not
# honored, so Pkg.develop the local paths explicitly.
if VERSION < v"1.11.0-DEV.0"
Pkg.develop(
[
PackageSpec(path = dirname(@__DIR__)),
PackageSpec(path = normpath(joinpath(dirname(@__DIR__), "..", ".."))),
]
)
end
Pkg.develop(
[
PackageSpec(path = dirname(@__DIR__)),
PackageSpec(path = normpath(joinpath(dirname(@__DIR__), "..", ".."))),
]
)
return Pkg.instantiate()
end

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
[deps]
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b"
RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd"
RecursiveArrayToolsShorthandConstructors = "39fb7555-b4ad-4efd-8abe-30331df017d3"
SciMLTesting = "09d9d899-5365-40a9-917a-5f67fddea283"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[sources]
RecursiveArrayToolsShorthandConstructors = {path = "../.."}

[compat]
Aqua = "0.8"
JET = "0.9, 0.10, 0.11"
RecursiveArrayTools = "4"
RecursiveArrayToolsShorthandConstructors = "1"
SciMLTesting = "1.6, 2.1"
SciMLTesting = "2.4"
Test = "1"
julia = "1.10"
3 changes: 1 addition & 2 deletions lib/RecursiveArrayToolsShorthandConstructors/test/qa/qa.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ const RATSC = RecursiveArrayToolsShorthandConstructors

run_qa(
RATSC;
explicit_imports = true,
# `getindex(::Type{VA}, ...)` / `getindex(::Type{AP}, ...)` extend Base on
# RecursiveArrayTools-owned types, so they are intentional (owned) methods,
# not piracy.
aqua_kwargs = (; piracies = (; treat_as_own = [RATSC.VA, RATSC.AP])),
jet_kwargs = (; target_defined_modules = true),
jet_kwargs = (; target_modules = (RATSC,)),
)
16 changes: 6 additions & 10 deletions lib/RecursiveArrayToolsShorthandConstructors/test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,12 @@ const TEST_GROUP = get(ENV, "RECURSIVEARRAYTOOLS_TEST_GROUP", "Core")

function activate_qa_env()
Pkg.activate(joinpath(@__DIR__, "qa"))
# On Julia < 1.11, the [sources] section in the qa Project.toml is not
# honored, so Pkg.develop the local paths explicitly.
if VERSION < v"1.11.0-DEV.0"
Pkg.develop(
[
PackageSpec(path = dirname(@__DIR__)),
PackageSpec(path = normpath(joinpath(dirname(@__DIR__), "..", ".."))),
]
)
end
Pkg.develop(
[
PackageSpec(path = dirname(@__DIR__)),
PackageSpec(path = normpath(joinpath(dirname(@__DIR__), "..", ".."))),
]
)
return Pkg.instantiate()
end

Expand Down
Loading
Loading