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
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
/docs/const
/docs/import
.CondaPkg/*
default.profraw
/test/default.profraw
/default.profraw
/test/default.profraw
/docs/default.profraw
17 changes: 13 additions & 4 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,27 @@ PythonCall = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d"
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
SymPyCore = "458b697b-88f0-4a86-b56b-78b75cfb3531"

[weakdeps]
Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7"

[extensions]
SymPyPythonCallSymbolicsExt = "Symbolics"

[compat]
julia = "1.6.1"
LinearAlgebra = "1"
SymPyCore = "0.1"
CommonEq = "0.2"
CommonSolve = "0.2"
CondaPkg = "0.2"
LinearAlgebra = "1"
PythonCall = "0.9"
SpecialFunctions = "0.8, 0.9, 0.10, 1.0, 2"
Symbolics = "5"
SymPyCore = "0.1"
julia = "1.6.1"


[extras]
Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test"]
test = ["Symbolics", "Test"]
120 changes: 120 additions & 0 deletions ext/SymPyPythonCallSymbolicsExt.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
module SymPyPythonCallSymbolicsExt

# from https://github.com/JuliaSymbolics/Symbolics.jl/pull/957/
# by @jClugstor
import SymPyPythonCall
sp = SymPyPythonCall._sympy_
const PythonCall = SymPyPythonCall.PythonCall
import PythonCall: pyconvert, pyimport, pyisinstance

import Symbolics
import Symbolics: @variables

PythonCall.pyconvert(::Type{T}, x::SymPyPythonCall.Sym) where {T} = pyconvert(T, x.o)

# rule functions
function pyconvert_rule_sympy_symbol(::Type{Symbolics.Num}, x)
if !pyisinstance(x,sp.Symbol)
return PythonCall.pyconvert_unconverted()
end
name = PythonCall.pyconvert(Symbol,x.name)
return PythonCall.pyconvert_return(Symbolics.variable(name))
end

function pyconvert_rule_sympy_pow(::Type{Symbolics.Num}, x)
if !pyisinstance(x,sp.Pow)
return PythonCall.pyconvert_unconverted()
end
expbase = pyconvert(Symbolics.Num,x.base)
exp = pyconvert(Symbolics.Num,x.exp)
return PythonCall.pyconvert_return(expbase^exp)
end

function pyconvert_rule_sympy_mul(::Type{Symbolics.Num}, x)
if !pyisinstance(x,sp.Mul)
return PythonCall.pyconvert_unconverted()
end
mult = reduce(*,PythonCall.pyconvert.(Symbolics.Num,x.args))
return PythonCall.pyconvert_return(mult)
end

function pyconvert_rule_sympy_add(::Type{Symbolics.Num}, x)
if !pyisinstance(x,sp.Add)
return PythonCall.pyconvert_unconverted()
end
sum = reduce(+, PythonCall.pyconvert.(Symbolics.Num,x.args))
return PythonCall.pyconvert_return(sum)
end

function pyconvert_rule_sympy_derivative(::Type{Symbolics.Num}, x)
if !pyisinstance(x,sp.Derivative)
return PythonCall.pyconvert_unconverted()
end
variables = pyconvert.(Symbolics.Num,x.variables)
derivatives = prod(var -> Differential(var), variables)
expr = pyconvert(Symbolics.Num, x.expr)
return PythonCall.pyconvert_return(derivatives(expr))
end

function pyconvert_rule_sympy_function(::Type{Symbolics.Num}, x)
if !pyisinstance(x,sp.Function)
return PythonCall.pyconvert_unconverted()
end
nm = PythonCall.pygetattr(x, "func", nothing)
isnothing(nm) && return PythonCall.pyconvert_unconverted() # XXX
name = pyconvert(Symbol, nm)
args = pyconvert.(Symbolics.Num, x.args)
func = @variables $name(..)
return PythonCall.pyconvert_return(first(func)(args...))
end

function pyconvert_rule_sympy_equality(::Type{Symbolics.Equation}, x)
if !pyisinstance(x,sp.Equality)
return PythonCall.pyconvert_unconverted()
end
rhs = pyconvert(Symbolics.Num,x.rhs)
lhs = pyconvert(Symbolics.Num,x.lhs)
return PythonCall.pyconvert_return(rhs ~ lhs)
end


function __init__()
# added rules
# T = Symbolics.Num
PythonCall.pyconvert_add_rule("sympy.core.symbol:Symbol", Symbolics.Num, pyconvert_rule_sympy_symbol)

PythonCall.pyconvert_add_rule("sympy.core.power:Pow", Symbolics.Num, pyconvert_rule_sympy_pow)

PythonCall.pyconvert_add_rule("sympy.core.mul:Mul", Symbolics.Num, pyconvert_rule_sympy_mul)

PythonCall.pyconvert_add_rule("sympy.core.add:Add", Symbolics.Num, pyconvert_rule_sympy_add)

PythonCall.pyconvert_add_rule("sympy.core.function:Derivative", Symbolics.Num, pyconvert_rule_sympy_derivative)

PythonCall.pyconvert_add_rule("sympy.core.function:Function", Symbolics.Num, pyconvert_rule_sympy_function)

# T = Symbolics.Equation
PythonCall.pyconvert_add_rule("sympy.core.relational:Equality", Symbolics.Equation, pyconvert_rule_sympy_equality)

# core numbers
add_pyconvert_rule(f, cls, T=Symbolics.Num) = PythonCall.pyconvert_add_rule(cls, T, f)

add_pyconvert_rule("sympy.core.numbers:Pi") do T::Type{Symbolics.Num}, x
PythonCall.pyconvert_return(Symbolics.Num(pi))
end
add_pyconvert_rule("sympy.core.numbers:Exp1") do T::Type{Symbolics.Num}, x
PythonCall.pyconvert_return(Symbolics.Num(ℯ))
end
add_pyconvert_rule("sympy.core.numbers:Infinity") do T::Type{Symbolics.Num}, x
PythonCall.pyconvert_return(Symbolics.Num(Inf))
end
# Complex{Num}
add_pyconvert_rule("sympy.core.numbers:ImaginaryUnit", Complex{Symbolics.Num}) do T::Type{Complex{Symbolics.Num}}, x
PythonCall.pyconvert_return(Complex(Symbolics.Num(0), Symbolics.Num{1}))
end
add_pyconvert_rule("sympy.core.numbers:ComplexInfinity", Complex{Symbolics.Num}) do T::Type{Complex{Symbolics.Num}}, x
PythonCall.pyconvert_return(Complex(Symbolics.Num(0), Symbolics.Num(Inf)) )
end
end

end
5 changes: 5 additions & 0 deletions test/extension-symbolics.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using SymPyPythonCall
import Symbolics
using Test

@test isa(SymPyPythonCall.PythonCall.pyconvert(Symbolics.Num, sympy.sympify("x")), Symbolics.Num)
2 changes: 2 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ using SymPyPythonCall

path = joinpath(pathof(SymPyPythonCall.SymPyCore), "../../test")
include(joinpath(path, "runtests-sympycore.jl"))

VERSION >= v"1.9.0" && include("extension-symbolics.jl")