Skip to content

Commit

Permalink
generalize symbolics (#18)
Browse files Browse the repository at this point in the history
* generalize symbolic derivative frameworks

* test SymEngine.jl, SymPy.jl, and Symbolics.jl

* use conda for CI

* make default compute_derivative empty
  • Loading branch information
ranocha authored Sep 28, 2021
1 parent 39aad49 commit 6d604b5
Show file tree
Hide file tree
Showing 4 changed files with 310 additions and 90 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ jobs:
${{ runner.os }}-test-
${{ runner.os }}-
- uses: julia-actions/julia-buildpkg@v1
env:
PYTHON: ""
- uses: julia-actions/julia-runtest@v1
env:
PYTHON: ""
- uses: julia-actions/julia-processcoverage@v1
- uses: codecov/codecov-action@v1
with:
Expand Down
8 changes: 5 additions & 3 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,22 @@ version = "0.1.5-pre"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
RootedTrees = "47965b36-3f3e-11e9-0dcf-4570dfd42a8c"
Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7"

[compat]
OrderedCollections = "1"
Reexport = "1"
Requires = "1"
RootedTrees = "2.1"
Symbolics = "3"
julia = "1"

[extras]
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
SymEngine = "123dc426-2d89-5057-bbad-38513e3affd8"
SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6"
Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["StaticArrays", "Symbolics", "Test"]
test = ["StaticArrays", "SymEngine", "SymPy", "Symbolics", "Test"]
74 changes: 64 additions & 10 deletions src/BSeries.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ using RootedTrees: RootedTree

@reexport using OrderedCollections: OrderedDict

@reexport using Symbolics: Symbolics, Num
using Symbolics: Differential, expand_derivatives
using Requires: @require


export bseries, substitute, compose
Expand All @@ -26,6 +25,47 @@ export elementary_differentials
end


"""
compute_derivative(expression, variable)
Internal function specialized on symbolic variables and expressions from
- [SymEngine.jl](https://github.com/symengine/SymEngine.jl),
- [SymPy.jl](https://github.com/JuliaPy/SymPy.jl), and
- [Symbolics.jl](https://github.com/JuliaSymbolics/Symbolics.jl)
if these packages are loaded (via Requires.jl).
"""
function compute_derivative end

function __init__()
@require SymEngine="123dc426-2d89-5057-bbad-38513e3affd8" begin
using .SymEngine: SymEngine

function compute_derivative(expression::SymEngine.Basic, variable::SymEngine.Basic)
SymEngine.diff(expression, variable)
end
end

@require SymPy="24249f21-da20-56a4-8eb1-6a02cf4ae2e6" begin
using .SymPy: SymPy

function compute_derivative(expression::SymPy.Sym, variable::SymPy.Sym)
SymPy.diff(expression, variable)
end
end

@require Symbolics="0c5d862f-8b57-4792-8d23-62f2024744c7" begin
using .Symbolics: Symbolics

function compute_derivative(expression::Symbolics.Num, variable::Symbolics.Num)
Symbolics.expand_derivatives(Symbolics.Differential(variable)(expression))
end
end
end



"""
substitute(b, a, t::RootedTree)
Expand Down Expand Up @@ -103,7 +143,7 @@ end


"""
ExactSolution{T}
ExactSolution{T}()
Lazy representation of the B-series of the exact solution of an ordinary
differential equation using coefficients of type at least as representative as
Expand Down Expand Up @@ -200,8 +240,15 @@ Butcher coefficients `A, b, c` up to the prescribed `order` with respect to
the ordinary differential equation ``u'(t) = f(u(t))`` with vector field `f`
and dependent variables `u` for a time step size `dt`.
Here, `u` is assumed to be a vector of variables from Symbolics.jl (`Symbolics.Num`)
and `f` is assumed to be a vector of expressions in these variables.
Here, `u` is assumed to be a vector of symbolic variables and `f` is assumed
to be a vector of expressions in these variables. Currently, symbolic variables
from
- [SymEngine.jl](https://github.com/symengine/SymEngine.jl),
- [SymPy.jl](https://github.com/JuliaPy/SymPy.jl), and
- [Symbolics.jl](https://github.com/JuliaSymbolics/Symbolics.jl)
are supported.
# References
Expand Down Expand Up @@ -290,8 +337,15 @@ method with Butcher coefficients `A, b, c` up to the prescribed `order` with
respect to the ordinary differential equation ``u'(t) = f(u(t))`` with vector
field `f` and dependent variables `u` for a time step size `dt`.
Here, `u` is assumed to be a vector of variables from Symbolics.jl (`Symbolics.Num`)
and `f` is assumed to be a vector of expressions in these variables.
Here, `u` is assumed to be a vector of symbolic variables and `f` is assumed
to be a vector of expressions in these variables. Currently, symbolic variables
from
- [SymEngine.jl](https://github.com/symengine/SymEngine.jl),
- [SymPy.jl](https://github.com/JuliaPy/SymPy.jl), and
- [Symbolics.jl](https://github.com/JuliaSymbolics/Symbolics.jl)
are supported.
# References
Expand Down Expand Up @@ -364,14 +418,14 @@ function _compute_partial_derivatives!(d, f, u, lower_derivatives)
# f_idx = first(idx_tuple)
# partial_derivative = f[f_idx]
# for i in u_idx
# partial_derivative = Differential(u[i])(partial_derivative)
# partial_derivative = compute_derivative(partial_derivative, u[i])
# end
# but we re-use the already computed `lower_derivatives`.
idx_known = Base.front(idx_tuple)
idx_new = last(idx_tuple)
partial_derivative = Differential(u[idx_new])(lower_derivatives[idx_known...])
partial_derivative = compute_derivative(lower_derivatives[idx_known...], u[idx_new])

d[idx] = expand_derivatives(partial_derivative)
d[idx] = partial_derivative
end
end

Expand Down
Loading

0 comments on commit 6d604b5

Please sign in to comment.