7.3. Complex numbers#

Complex numbers can be created using the global constant im for the imaginary unit \(\sqrt{-1}\):

a = 5 - 3im
5 - 3im

or alternatively using the syntax complex(real,imag):

b = complex(5,3)
5 + 3im
c = 5 + (3/4)im      # Parentheses needed since 3/4im == 3/(4im) 
5.0 + 0.75im

The standard operations work as expected for complex arguments:

a * b
34 + 0im
a / b
0.4705882352941177 - 0.8823529411764706im
(1 + im)^2
0 + 2im

Several functions are provided for manipulation of complex numbers (from the Julia documentation):

julia> z = 1 + 2im
1 + 2im

julia> real(1 + 2im) # real part of z
1

julia> imag(1 + 2im) # imaginary part of z
2

julia> conj(1 + 2im) # complex conjugate of z
1 - 2im

julia> abs(1 + 2im) # absolute value of z
2.23606797749979

julia> abs2(1 + 2im) # squared absolute value
5

julia> angle(1 + 2im) # phase angle in radians
1.1071487177940904

Also most elementary functions are defined for complex arguments (from the Julia documentation):

julia> sqrt(1im)
0.7071067811865476 + 0.7071067811865475im

julia> sqrt(1 + 2im)
1.272019649514069 + 0.7861513777574233im

julia> cos(1 + 2im)
2.0327230070196656 - 3.0518977991518im

julia> exp(1 + 2im)
-1.1312043837568135 + 2.4717266720048188im

julia> sinh(1 + 2im)
-0.4890562590412937 + 1.4031192506220405im

Note that these functions typically return real values when applied to real numbers and complex values when applied to complex numbers:

sqrt(-1.0 + 0im)  # OK, complex input gives complex output
0.0 + 1.0im
sqrt(-1.0)        # Error - real input but needs complex output
DomainError with -1.0:
sqrt will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).

Stacktrace:
 [1] throw_complex_domainerror(f::Symbol, x::Float64)
   @ Base.Math ./math.jl:33
 [2] sqrt(x::Float64)
   @ Base.Math ./math.jl:677
 [3] top-level scope
   @ In[8]:1

7.3.1. Example: Roots of quadratic function#

We can now update our previous example of the quadratic formula to handle all cases, including complex roots. We make sure that the argument to the sqrt function is complex:

function roots_of_quadratic(a,b,c)
    # Compute the roots of the quadratic ax^2 + bx + c = 0
    d = sqrt(complex(b^2 - 4*a*c))
    r1 = (-b - d) / 2a
    r2 = (-b + d) / 2a
    r1, r2
end
roots_of_quadratic (generic function with 1 method)
roots_of_quadratic(1,0,1)
(0.0 - 1.0im, 0.0 + 1.0im)
roots_of_quadratic(1,4,13)
(-2.0 - 3.0im, -2.0 + 3.0im)

Note that this implementation will return complex numbers even if the roots are real:

roots_of_quadratic(-1,5,6)
(6.0 + 0.0im, -1.0 - 0.0im)

If desired, one could easily write the function such that it returns real numbers for these cases.