Skip to content

Commit

Permalink
add package extension for SymPyPythonCall.jl (#212)
Browse files Browse the repository at this point in the history
* add package extension for SymPyPythonCall.jl

* fix for Julia v1.6

* format

* use SymPyPythonCall in docs instead of SymPy

* try to fix CI issue caused by loadong PyCall and PythonCall

* trying to fix CI

* bump compat for SymPy to v2

* fix docs

* format

* fix tests

* fix

* fix SymPy

* skip tests
  • Loading branch information
ranocha authored Jun 11, 2024
1 parent b02080d commit 7195ea3
Show file tree
Hide file tree
Showing 14 changed files with 295 additions and 62 deletions.
14 changes: 9 additions & 5 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "BSeries"
uuid = "ebb8d67c-85b4-416c-b05f-5f409e808f32"
authors = ["Hendrik Ranocha <[email protected]> and contributors"]
version = "0.1.59"
version = "0.1.60"

[deps]
Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa"
Expand All @@ -17,12 +17,14 @@ SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
[weakdeps]
SymEngine = "123dc426-2d89-5057-bbad-38513e3affd8"
SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6"
SymPyPythonCall = "bc8888f7-b21e-4b7c-a06a-5d9c9496438c"
Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7"

[extensions]
SymEngineExt = "SymEngine"
SymPyExt = "SymPy"
SymbolicsExt = "Symbolics"
BSeriesSymEngineExt = "SymEngine"
BSeriesSymPyExt = "SymPy"
BSeriesSymPyPythonCallExt = "SymPyPythonCall"
BSeriesSymbolicsExt = "Symbolics"

[compat]
Combinatorics = "1"
Expand All @@ -35,11 +37,13 @@ Requires = "1"
RootedTrees = "2.16"
SparseArrays = "1"
SymEngine = "0.8, 0.9.1, 0.10, 0.11"
SymPy = "1"
SymPy = "2"
SymPyPythonCall = "0.3"
Symbolics = "4, 5"
julia = "1.6"

[extras]
SymEngine = "123dc426-2d89-5057-bbad-38513e3affd8"
SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6"
SymPyPythonCall = "bc8888f7-b21e-4b7c-a06a-5d9c9496438c"
Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7"
4 changes: 2 additions & 2 deletions docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
SymEngine = "123dc426-2d89-5057-bbad-38513e3affd8"
SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6"
SymPyPythonCall = "bc8888f7-b21e-4b7c-a06a-5d9c9496438c"
Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7"

[compat]
Expand All @@ -19,7 +19,7 @@ Plots = "1"
PyCall = "1"
StaticArrays = "1"
SymEngine = "0.8, 0.9.1, 0.10, 0.11"
SymPy = "1.0.53"
SymPyPythonCall = "0.3"
Symbolics = "3, 4, 5"

[preferences.OrdinaryDiffEq]
Expand Down
15 changes: 8 additions & 7 deletions docs/src/benchmarks.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ Symbolic computations of [`modified_equation`](@ref)s and
support

- [SymEngine.jl](https://github.com/symengine/SymEngine.jl),
- [SymPy.jl](https://github.com/JuliaPy/SymPy.jl), and
- [SymPy.jl](https://github.com/JuliaPy/SymPy.jl),
- [SymPyPythonCall.jl](https://github.com/jverzani/SymPyPythonCall.jl), and
- [Symbolics.jl](https://github.com/JuliaSymbolics/Symbolics.jl)

as symbolic backends. Here, we compare them in the context of the explicit
Expand Down Expand Up @@ -70,12 +71,12 @@ end
Next, we load the symbolic packages and run the benchmarks.

```@setup benchmark-nonlinear-oscillator
using SymPy # generates annoying output online when conda installs sympy
using SymPyPythonCall # generates annoying output online when conda installs sympy
```

```@example benchmark-nonlinear-oscillator
using SymEngine: SymEngine
using SymPy: SymPy
using SymPyPythonCall: SymPyPythonCall
using Symbolics: Symbolics
println("SymEngine")
Expand All @@ -85,9 +86,9 @@ subs = SymEngine.subs
benchmark(u, dt, subs, 8)
println("SymPy")
dt = SymPy.symbols("dt")
u = SymPy.symbols("u1, u2")
subs = SymPy.subs
dt = SymPyPythonCall.symbols("dt")
u = SymPyPythonCall.symbols("u1, u2")
subs = SymPyPythonCall.subs
benchmark(u, dt, subs, 8)
println("Symbolics")
Expand All @@ -104,7 +105,7 @@ using InteractiveUtils
versioninfo()
using Pkg
Pkg.status(["BSeries", "RootedTrees", "SymEngine", "SymPy", "Symbolics"],
Pkg.status(["BSeries", "RootedTrees", "SymEngine", "SymPyPythonCall", "Symbolics"],
mode=PKGMODE_MANIFEST)
nothing # hide
```
Expand Down
10 changes: 5 additions & 5 deletions docs/src/tutorials/bseries_basics.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ methods, generically or when applied to a specific ordinary differential equatio
# These must first be installed using: import Pkg; Pkg.add("package_name")
using BSeries
using Latexify # Only needed for some pretty-printing cells below using `latexify`
import SymPy; sp=SymPy;
import SymPyPythonCall; sp = SymPyPythonCall;
```

## B-series for a generic ODE
Expand All @@ -20,7 +20,7 @@ Here is a generic 2-stage, 2nd-order method:


```@example bseries-basics
α = sp.symbols("α", real=true)
α = sp.symbols("α", real = true)
A = [0 0; 1/(2*α) 0]; b = [1-α, α]; c = [0, 1/(2*α)]
coeffs2 = bseries(A, b, c, 3)
latexify(coeffs2, cdot=false)
Expand Down Expand Up @@ -155,9 +155,9 @@ u_2'(t) & = t.


```@example bseries-basics
λ = sp.symbols("λ", real=true)
y, t = sp.symbols("y t", real=true)
h = sp.symbols("h", real=true)
λ = sp.symbols("λ", real = true)
y, t = sp.symbols("y t", real = true)
h = sp.symbols("h", real = true)
u = [y, t]
ff = [λ*(u[1]-sin(t))+cos(t), 1]
Expand Down
4 changes: 2 additions & 2 deletions docs/src/tutorials/rk_order_conditions.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
In this tutorial, we generate order conditions for a generic explicit Runge-Kutta method.

First, we create symbolic coefficient arrays with the appropriate structure.
There are several symbolic packages you can use. Here, we will use SymPy.jl.
There are several symbolic packages you can use. Here, we will use SymPyPythonCall.jl.


```@example bseries-RK-order-conditions
using BSeries, SymPy, Latexify
using BSeries, SymPyPythonCall, Latexify
s = 4 # Stages
p = 4 # Desired order of accuracy
Expand Down
26 changes: 14 additions & 12 deletions docs/src/tutorials/symbolic_computations.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ computations in [BSeries.jl](https://github.com/ranocha/BSeries.jl) support
at least

- [SymEngine.jl](https://github.com/symengine/SymEngine.jl),
- [SymPy.jl](https://github.com/JuliaPy/SymPy.jl), and
- [SymPy.jl](https://github.com/JuliaPy/SymPy.jl),
- [SymPyPythonCall.jl](https://github.com/jverzani/SymPyPythonCall.jl), and
- [Symbolics.jl](https://github.com/JuliaSymbolics/Symbolics.jl)

as symbolic backends. You can find some performance comparisons of them in the
Expand Down Expand Up @@ -87,12 +88,12 @@ latexify(series / h, cdot=false) |> println
```

We can also use other packages for the symbolic computations, of course.
SymPy.jl often provides very clean expressions.
SymPyPythonCall.jl often provides very clean expressions.

```@example modified-equation-sympy
using BSeries, SymPy
using BSeries, SymPyPythonCall
α = SymPy.symbols("α", real=true)
α = SymPyPythonCall.symbols("α", real = true)
A = [0 0; 1/(2α) 0]
b = [1-α, α]
c = [0, 1/(2α)]
Expand All @@ -105,20 +106,21 @@ SymEngine.jl.

```@example modified-equation-sympy
using Latexify
latexify(series, reduce_order_by=1, dt=SymPy.symbols("h"), cdot=false) |> println
latexify(series, reduce_order_by = 1, dt = SymPyPythonCall.symbols("h"),
cdot = false) |> println
```

We can also use the simplified versions.

```@example modified-equation-sympy
using Latexify
latexify(series, reduce_order_by=1, cdot=false) |> println
latexify(series, reduce_order_by = 1, cdot = false) |> println
```

```@example modified-equation-sympy
using Latexify
h = SymPy.symbols("h", real=true)
latexify(series / h, cdot=false) |> println
h = SymPyPythonCall.symbols("h", real = true)
latexify(series / h, cdot = false) |> println
```

Alternatively, we can also use Symbolics.jl.
Expand All @@ -137,7 +139,7 @@ series = modified_equation(A, b, c, 3)
```@example modified-equation-symbolics
using Latexify
Symbolics.@variables h
latexify(series / h, cdot=false) |> println
latexify(series / h, cdot = false) |> println
```


Expand All @@ -163,14 +165,14 @@ If even `Int128` is not enough, one can specify the type `BigInt`, which has adj
You can also create purely symbolic B-series as starting point of exploratory research, e.g.,

```@example ex:symbolic-series
using BSeries, SymPy
using BSeries, SymPyPythonCall
series = bseries(5) do t, series
return symbols("a_$(butcher_representation(t))", real=true)
return symbols("a_$(butcher_representation(t))", real = true)
end
```

This B-series can be used as any other B-series, e.g., to compute a
This B-series can be used as any other B-series, e.g., to compute a
modified equation:

```@example ex:symbolic-series
Expand Down
2 changes: 1 addition & 1 deletion ext/SymEngineExt.jl → ext/BSeriesSymEngineExt.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module SymEngineExt
module BSeriesSymEngineExt

if isdefined(Base, :get_extension)
using SymEngine: SymEngine
Expand Down
20 changes: 20 additions & 0 deletions ext/BSeriesSymPyExt.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module BSeriesSymPyExt

if isdefined(Base, :get_extension)
using SymPy: SymPy
else
using ..SymPy: SymPy
end

using BSeries: BSeries

function BSeries.compute_derivative(expression::SymPy.Sym{SymPy.PyCall.PyObject},
variable::SymPy.Sym{SymPy.PyCall.PyObject})
SymPy.diff(expression, variable)
end

function BSeries.latexify_default_dt(::Type{SymPy.Sym{SymPy.PyCall.PyObject}})
SymPy.symbols("h", real = true)
end

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

if isdefined(Base, :get_extension)
using SymPyPythonCall: SymPyPythonCall
else
using ..SymPyPythonCall: SymPyPythonCall
end

using BSeries: BSeries

function BSeries.compute_derivative(expression::SymPyPythonCall.Sym{SymPyPythonCall.PythonCall.Core.Py},
variable::SymPyPythonCall.Sym{SymPyPythonCall.PythonCall.Core.Py})
SymPyPythonCall.diff(expression, variable)
end

function BSeries.latexify_default_dt(::Type{SymPyPythonCall.Sym{SymPyPythonCall.PythonCall.Core.Py}})
SymPyPythonCall.symbols("h", real = true)
end

end # module
2 changes: 1 addition & 1 deletion ext/SymbolicsExt.jl → ext/BSeriesSymbolicsExt.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module SymbolicsExt
module BSeriesSymbolicsExt

if isdefined(Base, :get_extension)
using Symbolics: Symbolics
Expand Down
17 changes: 0 additions & 17 deletions ext/SymPyExt.jl

This file was deleted.

10 changes: 7 additions & 3 deletions src/BSeries.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1605,15 +1605,19 @@ function compute_derivative end
@static if !isdefined(Base, :get_extension)
function __init__()
@require Symbolics="0c5d862f-8b57-4792-8d23-62f2024744c7" begin
include("../ext/SymbolicsExt.jl")
include("../ext/BSeriesSymbolicsExt.jl")
end

@require SymEngine="123dc426-2d89-5057-bbad-38513e3affd8" begin
include("../ext/SymEngineExt.jl")
include("../ext/BSeriesSymEngineExt.jl")
end

@require SymPy="24249f21-da20-56a4-8eb1-6a02cf4ae2e6" begin
include("../ext/SymPyExt.jl")
include("../ext/BSeriesSymPyExt.jl")
end

@require SymPyPythonCall="bc8888f7-b21e-4b7c-a06a-5d9c9496438c" begin
include("../ext/BSeriesSymPyPythonCallExt.jl")
end
end
end
Expand Down
5 changes: 4 additions & 1 deletion test/Project.toml
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
[deps]
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
SymEngine = "123dc426-2d89-5057-bbad-38513e3affd8"
SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6"
SymPyPythonCall = "bc8888f7-b21e-4b7c-a06a-5d9c9496438c"
Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[compat]
Aqua = "0.8"
StaticArrays = "1"
SymEngine = "0.8, 0.9.1, 0.10, 0.11"
SymPy = "1"
SymPy = "2"
SymPyPythonCall = "0.3"
Symbolics = "4, 5"
Loading

2 comments on commit 7195ea3

@ranocha
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/108706

Tip: Release Notes

Did you know you can add release notes too? Just add markdown formatted text underneath the comment after the text
"Release notes:" and it will be added to the registry PR, and if TagBot is installed it will also be added to the
release that TagBot creates. i.e.

@JuliaRegistrator register

Release notes:

## Breaking changes

- blah

To add them here just re-invoke and the PR will be updated.

Tagging

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.1.60 -m "<description of version>" 7195ea3f713da94e0a8f8fcde34b6a64278541ea
git push origin v0.1.60

Please sign in to comment.