Open jverzani opened 3 years ago
Nice! But this seems more apt as a blog post or an appendix than something this package would need to support. It would be good to use any CAS, not just SymPy.
No, I think it would be good to have this code somewhere in JuliaSymbolics. I think it would be good to keep it off of Symbolics.jl because Python dependencies always cause issues (like always, they are the bane of my existence). But I think it would be really good to capture this code in an @requires
. This would do two things:
So there's a lot of value there. So please go ahead and let's get this code and document it, and if it becomes too big we can move it to SymPySymbolics.jl but for now it should be a quick @requires
block with one documentation page showing the link.
I think @shashi is right here. Doing this reasonably well requires more work than this simple proof of concept. Including this would bring on more ownership issues than what it is worth. The return trip needs doing as well. I believe the approach taken by Symata, which works at the AST level, might be worth pursuing (https://github.com/jlapeyre/Symata.jl/blob/master/src/sympy.jl) were there any spare time by any one working on Symbolics.
I think contributing a proof of concept is fine though. Giving a little bit and nurturing the code's evolution is what needs to happen, not necessarily someone doing 100% of it in a single code drop.
Here is a hacky solution that gets simple things done, but not nuanced ones, when called at the command line:
using Symbolics
import PyCall
const sympy = PyCall.pyimport_conda("sympy", "sympy")
function PyCall.PyObject(ex::Num)
sympy.sympify(string(ex)) # lose type detail of variables
end;
Symbolics.Num(o::PyCall.PyObject) = eval(Meta.parse(sympy.julia_code(o)))
Which gives, for example:
julia> @variables a b x
(a, b, x)
julia> o = sympy.limit(sin(a*x)/sin(b*x), x, 0)
PyObject a/b
julia> Num(o)
a*(b^-1)
But it seems far too brittle to put into a package, though I should post somewhere as an example. Here it falls apart due to a Piecewise condition (Ne
)
julia> o = sympy.integrate(1/x^n, x)
PyObject Piecewise((x**(1 - n)/(1 - n), Ne(n, 1)), (log(x), True))
julia> Num(o)
ERROR: MethodError: no method matching !(::Num)
Building a CAS is time consuming process, but wouldn't it be nice to be able to leverage some
SymPy
operations while this happens? It might not be impossible, this toy model shows one way to go half way there, though at a loss of type information:The PyObject method is the big conversion from Symbolics to the python SymPy using SymPy.jl. The use of
build_function
is a hacky way to get that done. The round trip needs more thought. The best way would be to integrate in PyCall'spytype_mapping
for behind the scenes conversion, but a quick an easy means might be achievable by turning the sympy value into an expression and incorporating that back into Symbolics.My question, is there any appetite in pursing this?
┆Issue is synchronized with this Trello card by Unito