# 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:
 throw_complex_domainerror(f::Symbol, x::Float64)
@ Base.Math ./math.jl:33
 sqrt(x::Float64)
@ Base.Math ./math.jl:582
 top-level scope
@ In:1
 eval
@ ./boot.jl:360 [inlined]
 include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)


## 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.