I can find square root of complex numbers but not cube root
julia> sqrt(1 + 2im)
1.272019649514069 + 0.7861513777574233im
julia> cbrt(1 + 2im)
ERROR: MethodError: no method matching cbrt(::Complex{Int64})
Closest candidates are:
cbrt(::BigFloat) at mpfr.jl:619
cbrt(::Float16) at math.jl:1125
cbrt(::Union{Float32, Float64}) at special/cbrt.jl:144
...
Stacktrace:
[1] top-level scope at REPL[2]:1
So this is my attempt to extend cube root of complex numbers. Am I doing this right?
julia> import Base: cbrt
julia> cbrt(x::Complex{T}) where T = x^(one(T)/(one(T)+one(T)+one(T)))
cbrt (generic function with 6 methods)
julia> cbrt(1 + 2im)
1.2196165079717578 + 0.47171126778938893im
1 Like
What about the two other complex roots?
1 Like
I guess cbrt
could be extended to complex numbers. Maybe open an issue? In the meantime,
julia> (1+2im)^(1/3)
1.2196165079717578 + 0.47171126778938893im
Like sqrt
, it would have to pick one. AFAIK it is commonly called the principal root.
1 Like
Things can get weird here. If you use the principal root, then it is not always true that
(ab)^(1/3) = a^(1/3) b^(1/3)
It’s exactly the same situation as with sqrt
:
a = complex(-1)
sqrt(a*a) == 1
sqrt(a)*sqrt(a) == -1
2 Likes
I opened an issue: https://github.com/JuliaLang/julia/issues/36534
However, the choice of branch cut isn’t immediately clear to me, since the obvious choice is inconsistent with how cbrt
is defined for real values:
# naive definition:
julia> Base.cbrt(z::Complex) = cbrt(abs(z)) * cis(angle(z)/3)
julia> cbrt(-3)
-1.4422495703074083
julia> cbrt(-3+0im)
0.7211247851537043 + 1.2490247664834064im
julia> (-3+0im)^(1//3)
0.7211247851537042 + 1.2490247664834064im
2 Likes
I don’t think there is an obvious choice. If you want a positive real root for a positive real input, you are still in a hole. If you integrate around a contour about the origin, you’ll cross a branch cut and get different values as the argument increases. So if z=r exp(im*theta) and cbrt(z) = r exp(im *theta/3), one pass around the contour does not take you back to where you started. All you can do is keep the books correctly as you traverse a contour.
Same story z^(1/n) for n =2, 3, …
2 Likes
In Mathematica, cbrt is only defined to return the real value of cuberoot.
I don’t think it is a good idea to define cbrt for complex value because it would cause discontinuity (depending on whether the arguement is Real or Complex). But certainly the documentation for crbt should be updated to mention that
cbrt(-27) == -3 while (-27+0im)^(1/3) == 1.5 + 2.598076211353316im
so cbrt will only return a real result (and never a complex result)
1 Like