具有多个根的编程语言

时间:2015-12-16 21:39:30

标签: python programming-languages octave julia complex-numbers

2 ^( - 1/3)的答案是三个根:

0.79370,-0.39685-0.68736i和0.39685 + 0.68736i(约)

Wolfram Alpha上查看正确答案。

我知道有几种支持复数的语言,但它们只返回三个结果中的第一个:

的Python:

>>> complex(2,0)**(-1/3)
(0.7937005259840998-0j)

八度:

>> (2+0i)^(-1/3)
ans = 0.79370

朱莉娅:

julia> complex(2,0)^(-1/3)
0.7937005259840998 + 0.0im

我正在寻找的是:

>> 2^(-1/3)
[0.79370+0i, -0.39685-0.68736i, 0.39685+0.68736i]

是否有一种编程语言(带有REPL)可以正确返回所有三个根,而不必求助于任何特殊的模块或库,它们也有可用的开源实现?

2 个答案:

答案 0 :(得分:7)

正如许多评论所解释的那样,想要一个通用语言默认情况下,复杂根函数的每个分支的结果可能是一个很高的顺序。但是 Julia 允许非常自然地专门化/重载运算符(因为即使是开箱即用的实现也经常用Julia编写)。具体做法是:

using Roots,Polynomials  # Might need to Pkg.add("Roots") first
import Base: ^

^{T<:AbstractFloat}(b::T, r::Rational{Int64}) =
    roots(poly([0])^r.den - b^abs(r.num)).^sign(r.num)

现在,当试图将浮动提升到合理的力量时:

julia> 2.0^(-1//3)
3-element Array{Complex{Float64},1}:
 -0.39685-0.687365im
 -0.39685+0.687365im
 0.793701-0.0im     

请注意,将^的定义专门化为理性指数可以解决评论中提到的舍入问题。

答案 1 :(得分:2)

以下是如何通过根多项式 x b 1 / n 的所有根em> n - b 使用Matlab的roots或Octave&#39; roots:< / p>

b = 2;
n = -3; % for b^(1/n)
c = [1 zeros(1,abs(n)-1) -b];
r = roots(c).^sign(n);

返回

r =

 -0.396850262992050 - 0.687364818499301i
 -0.396850262992050 + 0.687364818499301i
  0.793700525984100 + 0.000000000000000i

或者,使用roots of unity(不确定这是多么健壮):

b = 2;
n = -3;
n0 = abs(n);
r0 = b^(1/n0);
w = exp(2*pi*1i/n0);
r = (r0*w.^(0:n0-1).').^sign(n)

或使用Matlab的符号数学工具箱:

b = 2;
n = -3;
c = [1 zeros(1,abs(n)-1) -b];
r = solve(poly2sym(c)).^sign(n)

返回:

r =

                           2^(2/3)/2
  2^(2/3)/(2*((3^(1/2)*1i)/2 - 1/2))
 -2^(2/3)/(2*((3^(1/2)*1i)/2 + 1/2))

在某些情况下,您可能还会发现nthroot有用(Octave documentation)。