# paulfioravanti's solution

## to Complex Numbers in the Ruby Track

Published at May 12 2019 · 0 comments
Instructions
Test suite
Solution

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.

For installation and learning resources, refer to the Ruby resources page.

For running the tests provided, you will need the Minitest gem. Open a terminal window and run the following command to install minitest:

``````gem install minitest
``````

If you would like color output, you can `require 'minitest/pride'` in the test file, or note the alternative instruction, below, for running the test file.

Run the tests from the exercise directory using the following command:

``````ruby complex_numbers_test.rb
``````

To include color from the command line:

``````ruby -r minitest/pride complex_numbers_test.rb
``````

## Submitting Incomplete Solutions

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

### complex_numbers_test.rb

``````require 'minitest/autorun'
require_relative 'complex_numbers'

# Common test data version: 1.3.0 1e1c9ca
class ComplexNumbersTest < Minitest::Test
def test_real_part_of_a_purely_real_number
# skip
expected = 1
assert_equal expected, ComplexNumber.new(1, 0).real
end

def test_real_part_of_a_purely_imaginary_number
skip
expected = 0
assert_equal expected, ComplexNumber.new(0, 1).real
end

def test_real_part_of_a_number_with_real_and_imaginary_part
skip
expected = 1
assert_equal expected, ComplexNumber.new(1, 2).real
end

def test_imaginary_part_of_a_purely_real_number
skip
expected = 0
assert_equal expected, ComplexNumber.new(1, 0).imaginary
end

def test_imaginary_part_of_a_purely_imaginary_number
skip
expected = 1
assert_equal expected, ComplexNumber.new(0, 1).imaginary
end

def test_imaginary_part_of_a_number_with_real_and_imaginary_part
skip
expected = 2
assert_equal expected, ComplexNumber.new(1, 2).imaginary
end

def test_imaginary_unit
skip
expected = ComplexNumber.new(-1, 0)
assert_equal expected, ComplexNumber.new(0, 1) * ComplexNumber.new(0, 1)
end

skip
expected = ComplexNumber.new(3, 0)
assert_equal expected, ComplexNumber.new(1, 0) + ComplexNumber.new(2, 0)
end

skip
expected = ComplexNumber.new(0, 3)
assert_equal expected, ComplexNumber.new(0, 1) + ComplexNumber.new(0, 2)
end

skip
expected = ComplexNumber.new(4, 6)
assert_equal expected, ComplexNumber.new(1, 2) + ComplexNumber.new(3, 4)
end

def test_subtract_purely_real_numbers
skip
expected = ComplexNumber.new(-1, 0)
assert_equal expected, ComplexNumber.new(1, 0) - ComplexNumber.new(2, 0)
end

def test_subtract_purely_imaginary_numbers
skip
expected = ComplexNumber.new(0, -1)
assert_equal expected, ComplexNumber.new(0, 1) - ComplexNumber.new(0, 2)
end

def test_subtract_numbers_with_real_and_imaginary_part
skip
expected = ComplexNumber.new(-2, -2)
assert_equal expected, ComplexNumber.new(1, 2) - ComplexNumber.new(3, 4)
end

def test_multiply_purely_real_numbers
skip
expected = ComplexNumber.new(2, 0)
assert_equal expected, ComplexNumber.new(1, 0) * ComplexNumber.new(2, 0)
end

def test_multiply_purely_imaginary_numbers
skip
expected = ComplexNumber.new(-2, 0)
assert_equal expected, ComplexNumber.new(0, 1) * ComplexNumber.new(0, 2)
end

def test_multiply_numbers_with_real_and_imaginary_part
skip
expected = ComplexNumber.new(-5, 10)
assert_equal expected, ComplexNumber.new(1, 2) * ComplexNumber.new(3, 4)
end

def test_divide_purely_real_numbers
skip
expected = ComplexNumber.new(0.5, 0)
assert_equal expected, ComplexNumber.new(1, 0) / ComplexNumber.new(2, 0)
end

def test_divide_purely_imaginary_numbers
skip
expected = ComplexNumber.new(0.5, 0)
assert_equal expected, ComplexNumber.new(0, 1) / ComplexNumber.new(0, 2)
end

def test_divide_numbers_with_real_and_imaginary_part
skip
expected = ComplexNumber.new(0.44, 0.08)
assert_equal expected, ComplexNumber.new(1, 2) / ComplexNumber.new(3, 4)
end

def test_absolute_value_of_a_positive_purely_real_number
skip
expected = 5
assert_equal expected, ComplexNumber.new(5, 0).abs
end

def test_absolute_value_of_a_negative_purely_real_number
skip
expected = 5
assert_equal expected, ComplexNumber.new(-5, 0).abs
end

def test_absolute_value_of_a_purely_imaginary_number_with_positive_imaginary_part
skip
expected = 5
assert_equal expected, ComplexNumber.new(0, 5).abs
end

def test_absolute_value_of_a_purely_imaginary_number_with_negative_imaginary_part
skip
expected = 5
assert_equal expected, ComplexNumber.new(0, -5).abs
end

def test_absolute_value_of_a_number_with_real_and_imaginary_part
skip
expected = 5
assert_equal expected, ComplexNumber.new(3, 4).abs
end

def test_conjugate_a_purely_real_number
skip
expected = ComplexNumber.new(5, 0)
assert_equal expected, ComplexNumber.new(5, 0).conjugate
end

def test_conjugate_a_purely_imaginary_number
skip
expected = ComplexNumber.new(0, -5)
assert_equal expected, ComplexNumber.new(0, 5).conjugate
end

def test_conjugate_a_number_with_real_and_imaginary_part
skip
expected = ComplexNumber.new(1, -1)
assert_equal expected, ComplexNumber.new(1, 1).conjugate
end

def test_eulers_identity_formula
skip
expected = ComplexNumber.new(-1, 0)
assert_equal expected, ComplexNumber.new(0, Math::PI).exp
end

def test_exponential_of_0
skip
expected = ComplexNumber.new(1, 0)
assert_equal expected, ComplexNumber.new(0, 0).exp
end

def test_exponential_of_a_purely_real_number
skip
expected = ComplexNumber.new(Math::E, 0)
assert_equal expected, ComplexNumber.new(1, 0).exp
end

def test_exponential_of_a_number_with_real_and_imaginary_part
skip
expected = ComplexNumber.new(-2, 0)
assert_equal expected, ComplexNumber.new(Math.log(2), Math::PI).exp
end
end``````
``````class ComplexNumber
complex_number.real**2 + complex_number.imaginary**2
end

def initialize(real, imaginary)
@real = real
@imaginary = imaginary
end

def ==(other)
real == other.real && imaginary == other.imaginary
end

# (a + i * b) + (c + i * d) = (a + c) + (b + d) * i
def +(other)
self.class.new(
)
end

# (a + i * b) - (c + i * d) = (a - c) + (b - d) * i
def -(other)
self.class.new(
subtract_real(other),
subtract_imaginary(other)
)
end

# (a + i * b) * (c + i * d) = (a * c - b * d) + (b * c + a * d) * i
def *(other)
self.class.new(
multiplication_real(other),
multiplication_imaginary(other)
)
end

# (a + i * b) / (c + i * d) =
#   (a * c + b * d) / (c^2 + d^2) + (b * c - a * d) / (c^2 + d^2) * i
def /(other)
self.class.new(
divide_real(other),
divide_imaginary(other)
)
end

# |z| = sqrt(a^2 + b^2)
def abs
self
.then(&Math.method(:sqrt))
end

# a - b * i
def conjugate
self.class.new(real, -imaginary)
end

# e^(a + i * b) = e^a * e^(i * b)
# => e^(i * b) = cos(b) + i * sin(b)
def exp
self.class.new(
Math.exp(real) * eulers_formula,
0
)
end

private

# (a + c)
real + other.real
end

# (b + d)
imaginary + other.imaginary
end

# (a - c)
def subtract_real(other)
real - other.real
end

# (b - d)
def subtract_imaginary(other)
imaginary - other.imaginary
end

# (a * c - b * d)
def multiplication_real(other)
multiply_real(other) - multiply_imaginary(other)
end

# (b * c + a * d)
def multiplication_imaginary(other)
multiply_imaginary_to_real(other) + multiply_real_to_imaginary(other)
end

# (a * c)
def multiply_real(other)
real * other.real
end

# (a * d)
def multiply_real_to_imaginary(other)
real * other.imaginary
end

# (b * d)
def multiply_imaginary(other)
imaginary * other.imaginary
end

# (b * c)
def multiply_imaginary_to_real(other)
imaginary * other.real
end

# (a * c + b * d) / (c^2 + d^2)
def divide_real(other)
(multiply_real(other) + multiply_imaginary(other)) /
division_denominator(other)
end

# (b * c - a * d) / (c^2 + d^2)
def divide_imaginary(other)
(multiply_imaginary_to_real(other) - multiply_real_to_imaginary(other)) /
division_denominator(other)
end

# (c^2 + d^2)
def division_denominator(other)
other
.to_f
end

# e^(i * b) = cos(b) + i * sin(b)
def eulers_formula
(Math.cos(imaginary) + Math.sin(imaginary)).round
end
end``````