Complex exponentiation: 1^x ≈ 2

I have a mind worm, and I’m trying to figure out how we might express this in Julia.

Examine the following REPL log including complex exponentiation.

julia> x = -1im * log(2)/(2π)
 0.0 - 0.1103178000763258im
 
julia> 1^x
 1.0 - 0.0im
 
julia> 2^(1/x)
 1.0 - 1.133107779529596e-15im

julia> 1 ≈ 2^(1/x)
 true
 
julia> 1^x ≈ 2
 false

julia> 1 ≈ exp(1im*2π)
true

julia> exp(1im*2π*x)
2.0 + 0.0im

julia> 1^x ≈ exp(1im*2π*x)
false

julia> 2 ≈ exp(1im*2π*x)
true

The problem is that we only are reporting the principal value. For example for sqrt(4) we only report 2 and not -2.

I was hoping that a package such as ComplexValues.jl by @tobydriscoll might help express this better, but I’m not sure how to do so yet.

What I want is some kind of complex polar repesentation that has a notion of equivalence classes. Does this have to be symbolic?

3 Likes

if you want to find all the different values, you could do something like

(^̃)(a, b) = let (;num, den) = rationalize(b)
    [exp((num * log(a) + 2*im*n*π)/den) for n ∈ 0:den-1]
end

and then we have

julia> 1 ^̃ (1/2)
2-element Vector{ComplexF64}:
  1.0 + 0.0im
 -1.0 + 1.2246467991473532e-16im

julia> 1 ^̃ (1/10)
10-element Vector{ComplexF64}:
                  1.0 + 0.0im
   0.8090169943749475 + 0.5877852522924731im
  0.30901699437494745 + 0.9510565162951535im
 -0.30901699437494734 + 0.9510565162951536im
  -0.8090169943749473 + 0.5877852522924732im
                 -1.0 + 1.2246467991473532e-16im
  -0.8090169943749475 - 0.587785252292473im
 -0.30901699437494756 - 0.9510565162951535im
  0.30901699437494723 - 0.9510565162951536im
   0.8090169943749473 - 0.5877852522924734im

Extending this to complex exponents is left as an exercise to the reader.

3 Likes

The function, z^{m/n}, is a power function. +1 for its definition. But as I understood, the OP is interested in the exponential function, f(z)=a^z, a\in\mathbb{C}\setminus\{0\}, which is defined by f(z)=exp(z*log(a)).
While z^{m/n} is multivaluated, the exponential function, f(z)=a^z, is a univaluated function, because in its definition one takes a fixed branch of logarithm.

I think that’s kind of Mason’s point?

I wanted to point out that in complex function theory, the exponential function f(z)=a^z is univaluated, defined by a fixed value of log(a).

I’m guessing mkitti is imagining lazier types to represent an output of multivalued functions, so they can compose with existing functions. Just like how we need to do sqrt(Complex(-4)) to avoid a type-stability-preserving DomainError, we probably need convert inputs before passing into functions. Not sure if one Multivalues type can do it for outputs of all multivalued functions, my naive thought is that ±2 would look very different from an infinite set of complex numbers.

The equivalence class is represented by a polynomial (equation), whose roots are the elements of the equivalence class. You could use PolynomialRoots.jl (warning, it’s buggy) or AMRVW.jl to find the roots of the polynomial.

For example, given multivalued x = {a^{\frac{m}{n}}}, you want the roots of {x^n} - {a^m}. If the polynomial is just {x^e} - c, you can use Mason’s method for calculating all the roots, instead of reaching out for one of the above packages.