Skip to content

Commit 45e5b14

Browse files
docs: add more docstrings, fix broken links
1 parent 03072e4 commit 45e5b14

File tree

4 files changed

+107
-29
lines changed

4 files changed

+107
-29
lines changed

docs/src/manual/variants.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ as `BasicSymbolic`. A `BasicSymbolic` is considered immutable. Mutating its fiel
99
behavior.
1010

1111
In SymbolicUtils v3, the type `T` in `BasicSymbolic{T}` was the type represented by the symbolic
12-
variable. In other words, `T` was the [`symtype`](@ref) of the variable.
12+
variable. In other words, `T` was the [`SymbolicUtils.symtype`](@ref) of the variable.
1313

1414
In SymbolicUtils v4, the `symtype` is not stored in the type, and is instead a field of the
1515
struct. This allows for greatly increased type-stability. The type `T` in `BasicSymbolic{T}`
@@ -26,6 +26,7 @@ A given expression must be pure in its `vartype`. In other words, no operation s
2626
of different `vartype`s.
2727

2828
!!! warning "A short note on (im-)mutability"
29+
2930
While `ismutabletype(BasicSymbolic)` returns `true`, symbolic types are IMMUTABLE.
3031
Any mutation is undefined behavior and can lead to very confusing and hard-to-debug issues.
3132
This includes internal mutation, such as mutating `AddMul.dict`. The arrays returned from
@@ -294,6 +295,7 @@ range of indices over which they should iterate, in case such a range is explici
294295
provided.
295296

296297
!!! note
298+
297299
The common global index variable is printed as `_1`, `_2`, ... in arrayops. It is not
298300
a valid symbolic variable outside of an `ArrayOp`'s `expr`.
299301

@@ -336,8 +338,8 @@ to Base-like behavior:
336338
doing so requires the function(s) passed to `map` and `mapreduce` instead of their types
337339
or shapes.
338340
- Since `ndims` information is not present in the type, `eachindex`, `iterate`, `size`,
339-
`axes`, `ndims`, `collect` are type-unstable. [`stable_eachindex`](@ref) is useful as
340-
a type-stable iteration alternative.
341+
`axes`, `ndims`, `collect` are type-unstable. [`SymbolicUtils.stable_eachindex`](@ref) is
342+
useful as a type-stable iteration alternative.
341343
- `ifelse` requires that both the true and false cases have identical shape.
342344
- Symbolic arrays _only_ support cartesian indexing. For example, given `@syms x[1:3, 1:3]`
343345
accessing `x[4]` is invalid and `x[1, 2]` should be used. Valid indices are
@@ -385,7 +387,7 @@ words,
385387
Here, `f1(x)` is considered a symbolic function `f1` called with the argument `x` and
386388
`f2(x)` is considered a dependent variable that depends on `x`. The utilities
387389
[`SymbolicUtils.is_function_symbolic`](@ref), [`SymbolicUtils.is_function_symtype`](@ref),
388-
[`symbolicUtils.is_called_function_symbolic`](@ref) can be used to differentiate between
390+
[`SymbolicUtils.is_called_function_symbolic`](@ref) can be used to differentiate between
389391
these cases.
390392

391393
## API

src/SymbolicUtils.jl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ using SymbolicIndexingInterface
1818
import Base: +, -, *, /, //, \, ^, ImmutableDict
1919
using ConstructionBase
2020
using TermInterface
21-
import TermInterface: iscall, isexpr, children,
22-
operation, arguments, metadata, maketerm, sorted_arguments
21+
import TermInterface: iscall, operation, arguments, metadata, maketerm, sorted_arguments
2322
# For ReverseDiffExt
2423
import ArrayInterface
2524
import ExproniconLite as EL

src/inspect.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ the expression.
3333
This function is used internally for printing via AbstractTrees.
3434
"""
3535
function AbstractTrees.children(x::BasicSymbolic)
36-
iscall(x) ? sorted_arguments(x) : isexpr(x) ? sorted_children(x) : ()
36+
iscall(x) ? sorted_arguments(x) : ()
3737
end
3838

3939
"""

src/types.jl

Lines changed: 99 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,27 @@
11
export SymReal, SafeReal, TreeReal, vartype
22

33
abstract type SymVariant end
4+
"""
5+
$TYPEDEF
6+
7+
One of three possible values of the [`vartype`](@ref). This variant is the default and
8+
behaves as a typical ideal scalar algebra would be expected to.
9+
"""
410
abstract type SymReal <: SymVariant end
11+
"""
12+
$TYPEDEF
13+
14+
One of three possible values of the [`vartype`](@ref). This variant is identical to
15+
[`SymReal`](@ref) except common terms in the numerator and denominator of a division are
16+
not cancelled out.
17+
"""
518
abstract type SafeReal <: SymVariant end
19+
"""
20+
$TYPEDEF
21+
22+
One of three possible values of the [`vartype`](@ref). This variant does not assume anything
23+
about the algebra and always uses the default tree form for expressions.
24+
"""
625
abstract type TreeReal <: SymVariant end
726

827
###
@@ -35,10 +54,25 @@ end
3554

3655
const SCALARS = [Bool, Int, Int32, BigInt, Float64, Float32, BigFloat, Rational{Int}, Rational{Int32}, Rational{BigInt}, ComplexF32, ComplexF64, Complex{BigFloat}]
3756

57+
"""
58+
$TYPEDEF
3859
60+
Type of metadata field for symbolics.
61+
"""
3962
const MetadataT = Union{Base.ImmutableDict{DataType, Any}, Nothing}
63+
"""
64+
$TYPEDEF
65+
66+
A custom vector type which does not allocate for small numbers of elements. If the number of elements is
67+
known at compile time, it should be passed as a `Tuple` to the constructor.
68+
"""
4069
const SmallV{T} = SmallVec{T, Vector{T}}
4170
const ShapeVecT = SmallV{UnitRange{Int}}
71+
"""
72+
$TYPEDEF
73+
74+
Type that represents the [`SymbolicUtils.shape`](@ref) of symbolics.
75+
"""
4276
const ShapeT = Union{Unknown, ShapeVecT}
4377
const IdentT = Union{IDType, Nothing}
4478
const MonomialOrder = MP.Graded{MP.Reverse{MP.InverseLexOrder}}
@@ -50,6 +84,11 @@ const _PolynomialT{T} = DP.Polynomial{PolyVarOrder, MonomialOrder, T}
5084
# we can't actually print a zero polynomial of this type, since it attempts to call
5185
# `zero(Any)` but that doesn't matter because we shouldn't ever store a zero polynomial
5286
const PolynomialT = _PolynomialT{PolyCoeffT}
87+
"""
88+
$TYPEDEF
89+
90+
Allowed types for the [`SymbolicUtils.symtype`](@ref) of symbolics.
91+
"""
5392
const TypeT = DataType
5493
const MonomialT = DP.Monomial{PolyVarOrder, MonomialOrder}
5594
const MonomialVecT = DP.MonomialVector{PolyVarOrder, MonomialOrder}
@@ -81,6 +120,12 @@ function onepoly()
81120
PolynomialT(PolyCoeffT[1], mv)
82121
end
83122

123+
"""
124+
$(TYPEDEF)
125+
126+
An EnumX.jl enum used to distinguish between addition and multiplication in
127+
[`SymbolicUtils.BSImpl.AddMul`](@ref).
128+
"""
84129
@enumx AddMulVariant::Bool begin
85130
ADD
86131
MUL
@@ -89,7 +134,7 @@ end
89134
"""
90135
$(TYPEDEF)
91136
92-
Core ADT for `BasicSymbolic`
137+
Core ADT for symbolic expressions.
93138
"""
94139
@data mutable BasicSymbolicImpl{T <: SymVariant} begin
95140
struct Const
@@ -171,12 +216,38 @@ Core ADT for `BasicSymbolic`
171216
end
172217
end
173218

219+
"""
220+
Alias for `SymbolicUtils.BasicSymbolicImpl`.
221+
"""
174222
const BSImpl = BasicSymbolicImpl
223+
"""
224+
Alias for `SymbolicUtils.BasicSymbolicImpl.Type`.
225+
"""
175226
const BasicSymbolic = BSImpl.Type
227+
"""
228+
The type of a mutable buffer containing symbolic arguments. Passing this to the
229+
[`SymbolicUtils.Term`](@ref) constructor will avoid allocating a new array.
230+
"""
176231
const ArgsT{T} = SmallV{BasicSymbolic{T}}
232+
"""
233+
The type of a read-only buffer containing symbolic arguments. Passing this to the
234+
[`SymbolicUtils.Term`](@ref) constructor will avoid allocating a new array. This is
235+
the type returned from [`TermInterface.arguments`](@ref).
236+
"""
177237
const ROArgsT{T} = ReadOnlyVector{BasicSymbolic{T}, ArgsT{T}}
238+
"""
239+
The type of the dictionary stored in [`BSImpl.AddMul`](@ref). Passing this to the
240+
[`SymbolicUtils.Add`](@ref) or [`SymbolicUtils.Mul`](@ref) constructors will avoid
241+
allocating a new dictionary.
242+
"""
178243
const ACDict{T} = Dict{BasicSymbolic{T}, Number}
244+
"""
245+
The type of the `output_idxs` field in [`BSImpl.ArrayOp`](@ref).
246+
"""
179247
const OutIdxT{T} = SmallV{Union{Int, BasicSymbolic{T}}}
248+
"""
249+
The type of the `ranges` field in [`BSImpl.ArrayOp`](@ref).
250+
"""
180251
const RangesT{T} = Dict{BasicSymbolic{T}, StepRange{Int, Int}}
181252

182253
"""
@@ -423,7 +494,7 @@ end
423494
###
424495

425496
"""
426-
operation(expr)
497+
$TYPEDSIGNATURES
427498
428499
Extract the operation (function) from a symbolic function call expression.
429500
Only valid for expressions where `iscall(expr)` returns `true`.
@@ -454,7 +525,7 @@ operation(expr4) # returns sin
454525
operation(arguments(expr4)[1]) # returns +
455526
```
456527
457-
See also: [`iscall`](@ref), [`arguments`](@ref)
528+
See also: [`TermInterface.iscall`](@ref), [`arguments`](@ref)
458529
"""
459530
@inline function TermInterface.operation(x::BSImpl.Type{T}) where {T}
460531
@nospecialize x
@@ -612,21 +683,6 @@ end
612683
"""
613684
$TYPEDSIGNATURES
614685
615-
Check if a `BasicSymbolic` is an expression (not a `Sym` or `Const`).
616-
617-
# Arguments
618-
- `s`: A `BasicSymbolic` value to check.
619-
620-
# Returns
621-
`true` if `s` is a compound expression.
622-
"""
623-
function isexpr(s::BSImpl.Type)
624-
!MData.isa_variant(s, BSImpl.Sym) && !MData.isa_variant(s, BSImpl.Const)
625-
end
626-
627-
"""
628-
iscall(expr)
629-
630686
Check if a symbolic expression `expr` represents a function call. Returns `true` if the
631687
expression is a composite expression with an operation and arguments, `false` otherwise.
632688
@@ -653,7 +709,9 @@ iscall(x * y) # true
653709
654710
See also: [`operation`](@ref), [`arguments`](@ref)
655711
"""
656-
iscall(s::BSImpl.Type) = isexpr(s)
712+
function TermInterface.iscall(s::BSImpl.Type)
713+
!MData.isa_variant(s, BSImpl.Sym) && !MData.isa_variant(s, BSImpl.Const)
714+
end
657715

658716
"""
659717
$TYPEDSIGNATURES
@@ -2690,9 +2748,9 @@ end
26902748
###
26912749

26922750
"""
2693-
promote_symtype(f, Ts...)
2751+
$TYPEDSIGNATURES
26942752
2695-
The result of applying `f` to arguments of [`symtype`](#symtype) `Ts...`
2753+
The result of applying `f` to arguments of [`SymbolicUtils.symtype`](@ref) `Ts...`
26962754
26972755
```julia
26982756
julia> promote_symtype(+, Real, Real)
@@ -2708,15 +2766,22 @@ julia> promote_symtype(f, Number)
27082766
Complex
27092767
```
27102768
2711-
When constructing [`Term`](#Term)s without an explicit symtype,
2769+
When constructing expressions without an explicit symtype,
27122770
`promote_symtype` is used to figure out the symtype of the Term.
2771+
2772+
It is recommended that all type arguments be annotated with [`SymbolicUtils.TypeT`](@ref)
2773+
and one method be implemented for any combination of `f` and the number of arguments. For
2774+
example, one method is implemented for unary `-` and one method for binary `-`. Each method
2775+
has an `if..elseif` chain to handle possible types. Any call to `promote_type` should be
2776+
typeasserted with `::TypeT`.
27132777
"""
27142778
promote_symtype(f, Ts...) = Any
27152779

27162780
"""
27172781
promote_shape(f, shs::ShapeT...)
27182782
27192783
The shape of the result of applying `f` to arguments of [`shape`](@ref) `shs...`.
2784+
It is recommended that implemented methods `@nospecialize` all the shape arguments.
27202785
"""
27212786
promote_shape(f, szs::ShapeT...) = Unknown(-1)
27222787

@@ -2956,6 +3021,12 @@ Base.empty!(awb::AddWorkerBuffer) = empty!(awb.dict)
29563021
const SYMREAL_ADDBUFFER = TaskLocalValue{AddWorkerBuffer{SymReal}}(AddWorkerBuffer{SymReal})
29573022
const SAFEREAL_ADDBUFFER = TaskLocalValue{AddWorkerBuffer{SafeReal}}(AddWorkerBuffer{SafeReal})
29583023

3024+
"""
3025+
$METHODLIST
3026+
3027+
Add an indexable list or tuple of terms `terms` with the given vartype. Applicable only for
3028+
symbolic expressions with numeric or array of numeric symtype.
3029+
"""
29593030
add_worker(::Type{SymReal}, terms) = SYMREAL_ADDBUFFER[](terms)
29603031
add_worker(::Type{SafeReal}, terms) = SAFEREAL_ADDBUFFER[](terms)
29613032

@@ -3428,6 +3499,12 @@ function (mwb::MulWorkerBuffer{T})(terms) where {T}
34283499
return Term{T}(*, new_arrterms; type, shape = newshape)
34293500
end
34303501

3502+
"""
3503+
$METHODLIST
3504+
3505+
Multiply an indexable list or tuple of terms `terms` with the given vartype. Applicable
3506+
only for symbolic expressions with numeric or array of numeric symtype.
3507+
"""
34313508
mul_worker(::Type{SymReal}, terms) = SYMREAL_MULBUFFER[](terms)
34323509
mul_worker(::Type{SafeReal}, terms) = SAFEREAL_MULBUFFER[](terms)
34333510

0 commit comments

Comments
 (0)