Julia 朱莉娅:如何将符号表达式转换为函数?

Julia 朱莉娅:如何将符号表达式转换为函数?,julia,sympy,Julia,Sympy,我使用Symphy包()创建了一个符号表达式。现在我想使用roots包()查找该表达式的根。但是,我不知道如何使用fzeros方法查找根,因为这只能应用于类型为函数的对象,而不是我表达式的类型为Sym 这是一个我正在尝试做的例子。我创建了一个符号“x”和一个符号表达式sin(x)。现在,让我们尝试在值-10和10之间找到sin(x)的零: using SymPy x = sym"x" expr = sin(x) using Roots fzeros(expr,-10,10) 以下是错误: ER

我使用Symphy包()创建了一个符号表达式。现在我想使用roots包()查找该表达式的根。但是,我不知道如何使用
fzeros
方法查找根,因为这只能应用于类型为
函数的对象,而不是我表达式的类型为
Sym

这是一个我正在尝试做的例子。我创建了一个符号
“x”
和一个符号表达式
sin(x)
。现在,让我们尝试在值-10和10之间找到
sin(x)
的零:

using SymPy
x = sym"x"
expr = sin(x)
using Roots
fzeros(expr,-10,10)
以下是错误:

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

如何将带有
Sym
类型的表达式转换为
函数
类型,以便找到根?

[更新:以下讨论在许多情况下已被最近引入的
lambdify
函数所取代。调用
lambdify(expr)
创建一个julia函数,该函数不会回调到Symphy进行求值,因此应该更快。它应该适用于大多数(但肯定不是所有)表达式。]

这是一个分为两步的过程:

convert(Function, expr)
在您的情况下,将返回一个自由变量函数,
x
。但是,函数值仍然是符号,不能与
fzeros
一起使用。可以猜测输入,但返回值的类型是另一回事。但是,强制浮动在这种情况下有效:

fzeros(x -> float(convert(Function, expr)), -10, 10)
(您也可以使用
a->float(replace(expr,x,a))
执行此操作)


对于这个简单的示例,
solve(expr)
也可以工作,但一般来说,
symphy
中的
findroot
函数没有公开,因此通过
symphy
进行数值根解算并不是一个解决办法,最终用户不必付出一定的努力。

对于Julia 0.6,这是一种开箱即用的方法:

julia> using SymPy, Roots

julia> x = Sym("x")
x

julia> expr = sin(x)
sin(x)

julia> fzeros(expr, -10, 10)
7-element Array{Float64,1}:
 -9.42478
 -6.28319
 -3.14159
  0.0
  3.14159
  6.28319
  9.42478
但它比纯Julia解慢得多。 以下是我使用
BenchmarkTools
运行的一些基准测试:

原始解决方案(6.8s):

纯朱莉娅(1.5ms):

半幼稚(7.6ms):

显式转换(3.8ms):


谢谢是的,忘了这一点,
nsolve(expr,x0)
将用于查找单个零。原始问题中的
fzeros
函数有点老套,它试图在指定的时间间隔内找到所有简单的零。这更接近于
solve
fzeros(expr, -10, 10)
fzeros(x-> sin(x), -10, 10)
fzeros(Function(expr), -10, 10)
expr2 = Function(expr)
fzeros(expr2, -10, 10)