Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Julia: how do I convert a symbolic expression to a function?

Tags:

julia

sympy

I have created a symbolic expression using the SymPy package (https://github.com/jverzani/SymPy.jl). I want to now find the roots of that expression using the Roots package (https://github.com/JuliaLang/Roots.jl). However, I cannot figure out how to use the fzeros method for finding the roots, since this can only be applied on an object with the type Function rather than Sym, which is the type of my expression.

Here's an example of what I'm trying to do. I create a symbolic "x" and a symbolic expression sin(x). Now lets try to find the zeros of sin(x) between the values -10 and 10:

using SymPy
x = sym"x"
expr = sin(x)
using Roots
fzeros(expr,-10,10)

Here's the error:

ERROR: `fzeros` has no method matching fzeros(::Sym, ::Int64, ::Int64)

How do I convert an expression with Sym type to Function type, so I can find the roots?

like image 251
Eddy Avatar asked Dec 08 '14 12:12

Eddy


1 Answers

[UPDATE: The discussion below has been superseded in many cases by the recently introduced lambdify function. The call lambdify(expr) creates a julia function that does not call back into SymPy to evaluate, so should be much faster. It should work for most, but certainly not all, expressions.]

It is a two step process:

convert(Function, expr)

will return a function of the free variables, x, in your case. However, the function values are still symbolic and can't be used with fzeros. The inputs can be guessed, but the type of the return value is another story. However, coercing to float will work in this case:

fzeros(x -> float(convert(Function, expr)), -10, 10)

(You could also do this with a -> float(replace(expr, x, a)).)

For this simple example solve(expr) will also work, but in general, the findroot function in SymPy is not exposed, so numeric root solving via SymPy isn't a workaround without some effort by the end-users.

like image 90
jverzani Avatar answered Oct 14 '22 22:10

jverzani