我使用SymPy包(https://github.com/jverzani/SymPy.jl)创建了一个符号表达式。我想现在使用Roots包(https://github.com/JuliaLang/Roots.jl)找到该表达式的根。但是,我无法弄清楚如何使用fzeros
方法来查找根,因为这只能应用于类型为Function
而不是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
类型的表达式转换为Function
类型,以便找到根?
答案 0 :(得分:4)
[更新:以下讨论在很多情况下已被最近推出的lambdify
功能取代。调用lambdify(expr)
创建了一个julia函数,该函数不会回调到SymPy进行评估,因此应该更快。它应该适用于大多数,但肯定不是所有的表达方式。]
这是一个两步过程:
convert(Function, expr)
在您的情况下,将返回自由变量x
的函数。但是,函数值仍然是符号的,不能与fzeros
一起使用。可以猜测输入,但返回值的类型是另一个故事。但是,在这种情况下,强制浮动将起作用:
fzeros(x -> float(convert(Function, expr)), -10, 10)
(您也可以使用a -> float(replace(expr, x, a))
执行此操作。)
对于这个简单示例,solve(expr)
也可以使用,但一般情况下,findroot
中的SymPy
函数未公开,因此通过SymPy
进行数字根求解不是&#39 ;没有最终用户的努力就可以解决问题。
答案 1 :(得分:0)
使用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):
fzeros(expr, -10, 10)
Pure Julia(1.5ms):
fzeros(x-> sin(x), -10, 10)
半天真(7.6ms):
fzeros(Function(expr), -10, 10)
显式转换(3.8ms):
expr2 = Function(expr)
fzeros(expr2, -10, 10)