Complex Numbers

A complex number is a number in the form a + b * i where a and b are real and i satisfies i^2 = -1.

a is called the real part and b is called the imaginary part of z. The conjugate of the number a + b * i is the number a - b * i. The absolute value of a complex number z = a + b * i is a real number |z| = sqrt(a^2 + b^2). The square of the absolute value |z|^2 is the result of multiplication of z by its complex conjugate.

The sum/difference of two complex numbers involves adding/subtracting their real and imaginary parts separately: (a + i * b) + (c + i * d) = (a + c) + (b + d) * i, (a + i * b) - (c + i * d) = (a - c) + (b - d) * i.

Multiplication result is by definition (a + i * b) * (c + i * d) = (a * c - b * d) + (b * c + a * d) * i.

The reciprocal of a non-zero complex number is 1 / (a + i * b) = a/(a^2 + b^2) - b/(a^2 + b^2) * i.

Dividing a complex number a + i * b by another c + i * d gives: (a + i * b) / (c + i * d) = (a * c + b * d)/(c^2 + d^2) + (b * c - a * d)/(c^2 + d^2) * i.

Raising e to a complex exponent can be expressed as e^(a + i * b) = e^a * e^(i * b), the last term of which is given by Euler's formula e^(i * b) = cos(b) + i * sin(b).

Implement the following operations:

  • addition, subtraction, multiplication and division of two complex numbers,
  • conjugate, absolute value, exponent of a given complex number.

Assume the programming language you are using does not have an implementation of complex numbers.

The Julia Base implementation of complex numbers can be found here: https://github.com/JuliaLang/julia/blob/master/base/complex.jl.


You can work on the bonus exercises by changing @test_skip to @test.

Bonus A

Implement the exponential function on complex numbers exp(::ComplexNumber).

Bonus B

Implement jm analogous to im so that 1 + 1jm == ComplexNumber(1, 1).

Source

Wikipedia https://en.wikipedia.org/wiki/Complex_number

Version compatibility

This exercise has been tested on Julia versions >=1.0.

Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

Your solution


In [ ]:
# submit

Test suite


In [ ]:
# canonical data version: 1.3.0

using Test

# include("complex-numbers.jl")

@test ComplexNumber <: Number

@test ComplexNumber(0, 1)^2 == ComplexNumber(-1, 0)

@testset "Arithmetic" begin
    @testset "Addition" begin
        @test ComplexNumber(1, 0) + ComplexNumber(2, 0) == ComplexNumber(3, 0)
        @test ComplexNumber(0, 1) + ComplexNumber(0, 2) == ComplexNumber(0, 3)
        @test ComplexNumber(1, 2) + ComplexNumber(3, 4) == ComplexNumber(4, 6)
    end

    @testset "Subtraction" begin
        @test ComplexNumber(1, 0) - ComplexNumber(2, 0) == ComplexNumber(-1, 0)
        @test ComplexNumber(0, 1) - ComplexNumber(0, 2) == ComplexNumber(0, -1)
        @test ComplexNumber(1, 2) - ComplexNumber(3, 4) == ComplexNumber(-2, -2)
    end

    @testset "Multiplication" begin
        @test ComplexNumber(1, 0) * ComplexNumber(2, 0) == ComplexNumber(2, 0)
        @test ComplexNumber(0, 1) * ComplexNumber(0, 2) == ComplexNumber(-2, 0)
        @test ComplexNumber(1, 2) * ComplexNumber(3, 4) == ComplexNumber(-5, 10)
    end

    @testset "Division" begin
        @test ComplexNumber(1, 0) / ComplexNumber(2, 0) == ComplexNumber(0.5, 0)
        @test ComplexNumber(0, 1) / ComplexNumber(0, 2) == ComplexNumber(0.5, 0)
        @test ComplexNumber(1, 2) / ComplexNumber(3, 4) == ComplexNumber(0.44, 0.08)
    end
end

@testset "Absolute value" begin
    @test abs(ComplexNumber(5, 0))  == 5
    @test abs(ComplexNumber(-5, 0)) == 5
    @test abs(ComplexNumber(0, 5))  == 5
    @test abs(ComplexNumber(0, -5)) == 5
    @test abs(ComplexNumber(3, 4))  == 5
end

@testset "Complex conjugate" begin
    @test conj(ComplexNumber(5, 0))  == ComplexNumber(5, 0)
    @test conj(ComplexNumber(0, 5))  == ComplexNumber(0, -5)
    @test conj(ComplexNumber(1, 1))  == ComplexNumber(1, -1)
end

@testset "Real part" begin
    @test real(ComplexNumber(1, 0)) == 1
    @test real(ComplexNumber(0, 1)) == 0
    @test real(ComplexNumber(1, 2)) == 1
end

@testset "Imaginary part" begin
    @test imag(ComplexNumber(1, 0)) == 0
    @test imag(ComplexNumber(0, 1)) == 1
    @test imag(ComplexNumber(1, 2)) == 2
end

# Bonus A
@testset "Complex exponential" begin
    @test_skip exp(ComplexNumber(0, π))  ComplexNumber(-1, 0)
    @test_skip exp(ComplexNumber(0, 0)) == ComplexNumber(1, 0)
    @test_skip exp(ComplexNumber(1, 0))  ComplexNumber(, 0)
    @test_skip exp(ComplexNumber(log(2), π))  ComplexNumber(-2, 0)
end

# Bonus B
@testset "Syntax sugar jm" begin
    @test_skip ComplexNumber(0, 1)  == jm
    @test_skip ComplexNumber(1, 0)  == 1 + 0jm
    @test_skip ComplexNumber(1, 1)  == 1 + 1jm
    @test_skip ComplexNumber(-1, 0) == jm^2
end

Prepare submission

To submit your exercise, you need to save your solution in a file called complex-numbers.jl before using the CLI. You can either create it manually or use the following functions, which will automatically write every notebook cell that starts with # submit to the file complex-numbers.jl.


In [ ]:
# using Pkg; Pkg.add("Exercism")
# using Exercism
# Exercism.create_submission("complex-numbers")