Skip to content

Commit 70ec623

Browse files
committedAug 11, 2018
Add ComplexNumber.
1 parent 46b13f0 commit 70ec623

File tree

4 files changed

+380
-0
lines changed

4 files changed

+380
-0
lines changed
 

‎README.md

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ a set of rules that precisely define a sequence of operations.
6868
* `B` [Sieve of Eratosthenes](src/algorithms/math/sieve-of-eratosthenes) - finding all prime numbers up to any given limit
6969
* `B` [Is Power of Two](src/algorithms/math/is-power-of-two) - check if the number is power of two (naive and bitwise algorithms)
7070
* `B` [Pascal's Triangle](src/algorithms/math/pascal-triangle)
71+
* `B` [Complex Number](src/algorithms/math/complex-number) - complex numbers and basic operations with them
7172
* `A` [Integer Partition](src/algorithms/math/integer-partition)
7273
* `A` [Liu Hui π Algorithm](src/algorithms/math/liu-hui) - approximate π calculations based on N-gons
7374
* **Sets**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
export default class ComplexNumber {
2+
/**
3+
* @param {number} [real]
4+
* @param {number} [imaginary]
5+
*/
6+
constructor({ real = 0, imaginary = 0 } = {}) {
7+
this.real = real;
8+
this.imaginary = imaginary;
9+
}
10+
11+
/**
12+
* @param {ComplexNumber} addend
13+
* @return {ComplexNumber}
14+
*/
15+
add(addend) {
16+
return new ComplexNumber({
17+
real: this.real + addend.real,
18+
imaginary: this.imaginary + addend.imaginary,
19+
});
20+
}
21+
22+
/**
23+
* @param {ComplexNumber} subtrahend
24+
* @return {ComplexNumber}
25+
*/
26+
subtract(subtrahend) {
27+
return new ComplexNumber({
28+
real: this.real - subtrahend.real,
29+
imaginary: this.imaginary - subtrahend.imaginary,
30+
});
31+
}
32+
33+
/**
34+
* @param {ComplexNumber} multiplicand
35+
* @return {ComplexNumber}
36+
*/
37+
multiply(multiplicand) {
38+
return new ComplexNumber({
39+
real: this.real * multiplicand.real - this.imaginary * multiplicand.imaginary,
40+
imaginary: this.real * multiplicand.imaginary + this.imaginary * multiplicand.real,
41+
});
42+
}
43+
44+
/**
45+
* @param {ComplexNumber} divider
46+
* @return {ComplexNumber}
47+
*/
48+
divide(divider) {
49+
// Get divider conjugate.
50+
const dividerConjugate = this.conjugate(divider);
51+
52+
// Multiply dividend by divider's conjugate.
53+
const finalDivident = this.multiply(dividerConjugate);
54+
55+
// Calculating final divider using formula (a + bi)(a − bi) = a^2 + b^2
56+
const finalDivider = (divider.real ** 2) + (divider.imaginary ** 2);
57+
58+
return new ComplexNumber({
59+
real: finalDivident.real / finalDivider,
60+
imaginary: finalDivident.imaginary / finalDivider,
61+
});
62+
}
63+
64+
/**
65+
* @param {ComplexNumber} complexNumber
66+
*/
67+
conjugate(complexNumber) {
68+
return new ComplexNumber({
69+
real: complexNumber.real,
70+
imaginary: -1 * complexNumber.imaginary,
71+
});
72+
}
73+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
# Complex Number
2+
3+
A **complex number** is a number that can be expressed in the
4+
form `a + b * i`, where `a` and `b` are real numbers, and `i` is a solution of
5+
the equation `x^2 = −1`. Because no *real number* satisfies this
6+
equation, `i` is called an *imaginary number*. For the complex
7+
number `a + b * i`, `a` is called the *real part*, and `b` is called
8+
the *imaginary part*.
9+
10+
![Complex Number](https://www.mathsisfun.com/numbers/images/complex-example.svg)
11+
12+
A Complex Number is a combination of a Real Number and an Imaginary Number:
13+
14+
![Complex Number](https://www.mathsisfun.com/numbers/images/complex-number.svg)
15+
16+
Geometrically, complex numbers extend the concept of the one-dimensional number
17+
line to the *two-dimensional complex plane* by using the horizontal axis for the
18+
real part and the vertical axis for the imaginary part. The complex
19+
number `a + b * i` can be identified with the point `(a, b)` in the complex plane.
20+
21+
A complex number whose real part is zero is said to be *purely imaginary*; the
22+
points for these numbers lie on the vertical axis of the complex plane. A complex
23+
number whose imaginary part is zero can be viewed as a *real number*; its point
24+
lies on the horizontal axis of the complex plane.
25+
26+
| Complex Number | Real Part | Imaginary Part | |
27+
| :------------- | :-------: | :------------: | --- |
28+
| 3 + 2i | 3 | 2 | |
29+
| 5 | 5 | **0** | Purely Real |
30+
| −6i | **0** | -6 | Purely Imaginary |
31+
32+
A complex number can be visually represented as a pair of numbers `(a, b)` forming
33+
a vector on a diagram called an *Argand diagram*, representing the *complex plane*.
34+
`Re` is the real axis, `Im` is the imaginary axis, and `i` satisfies `i^2 = −1`.
35+
36+
![Complex Number](https://upload.wikimedia.org/wikipedia/commons/a/af/Complex_number_illustration.svg)
37+
38+
> Complex does not mean complicated. It means the two types of numbers, real and
39+
imaginary, together form a complex, just like a building complex (buildings
40+
joined together).
41+
42+
## Basic Operations
43+
44+
### Adding
45+
46+
To add two complex numbers we add each part separately:
47+
48+
```text
49+
(a + b * i) + (c + d * i) = (a + c) + (b + d) * i
50+
```
51+
52+
**Example**
53+
54+
```text
55+
(3 + 5i) + (4 − 3i) = (3 + 4) + (5 − 3)i = 7 + 2i
56+
```
57+
58+
On complex plane the adding operation will look like the following:
59+
60+
![Complex Addition](https://www.mathsisfun.com/algebra/images/complex-plane-vector-add.svg)
61+
62+
### Subtracting
63+
64+
To subtract two complex numbers we subtract each part separately:
65+
66+
```text
67+
(a + b * i) - (c + d * i) = (a - c) + (b - d) * i
68+
```
69+
70+
**Example**
71+
72+
```text
73+
(3 + 5i) - (4 − 3i) = (3 - 4) + (5 + 3)i = -1 + 8i
74+
```
75+
76+
### Multiplying
77+
78+
To multiply complex numbers each part of the first complex number gets multiplied
79+
by each part of the second complex number:
80+
81+
Just use "FOIL", which stands for "**F**irsts, **O**uters, **I**nners, **L**asts" (
82+
see [Binomial Multiplication](ttps://www.mathsisfun.com/algebra/polynomials-multiplying.html) for
83+
more details):
84+
85+
![Complex Multiplication](https://www.mathsisfun.com/algebra/images/foil-complex.svg)
86+
87+
- Firsts: `a × c`
88+
- Outers: `a × di`
89+
- Inners: `bi × c`
90+
- Lasts: `bi × di`
91+
92+
In general it looks like this:
93+
94+
```text
95+
(a + bi)(c + di) = ac + adi + bci + bdi^2
96+
```
97+
98+
But there is also a quicker way!
99+
100+
Use this rule:
101+
102+
```text
103+
(a + bi)(c + di) = (ac − bd) + (ad + bc)i
104+
```
105+
106+
**Example**
107+
108+
```text
109+
(3 + 2i)(1 + 7i)
110+
= 3×1 + 3×7i + 2i×1+ 2i×7i
111+
= 3 + 21i + 2i + 14i^2
112+
= 3 + 21i + 2i − 14 (because i^2 = −1)
113+
= −11 + 23i
114+
```
115+
116+
```text
117+
(3 + 2i)(1 + 7i) = (3×1 − 2×7) + (3×7 + 2×1)i = −11 + 23i
118+
```
119+
120+
### Conjugates
121+
122+
We will need to know about conjugates in a minute!
123+
124+
A conjugate is where we change the sign in the middle like this:
125+
126+
![Complex Conjugate](https://www.mathsisfun.com/numbers/images/complex-conjugate.svg)
127+
128+
A conjugate is often written with a bar over it:
129+
130+
```text
131+
______
132+
5 − 3i = 5 + 3i
133+
```
134+
135+
On the complex plane the conjugate number will be mirrored against real axes.
136+
137+
![Complex Conjugate](https://upload.wikimedia.org/wikipedia/commons/6/69/Complex_conjugate_picture.svg)
138+
139+
### Dividing
140+
141+
The conjugate is used to help complex division.
142+
143+
The trick is to *multiply both top and bottom by the conjugate of the bottom*.
144+
145+
**Example**
146+
147+
```text
148+
2 + 3i
149+
------
150+
4 − 5i
151+
```
152+
153+
Multiply top and bottom by the conjugate of `4 − 5i`:
154+
155+
```text
156+
(2 + 3i) * (4 + 5i) 8 + 10i + 12i + 15i^2
157+
= ------------------- = ----------------------
158+
(4 − 5i) * (4 + 5i) 16 + 20i − 20i − 25i^2
159+
```
160+
161+
Now remember that `i^2 = −1`, so:
162+
163+
```text
164+
8 + 10i + 12i − 15 −7 + 22i −7 22
165+
= ------------------- = -------- = -- + -- * i
166+
16 + 20i − 20i + 25 41 41 41
167+
168+
```
169+
170+
There is a faster way though.
171+
172+
In the previous example, what happened on the bottom was interesting:
173+
174+
```text
175+
(4 − 5i)(4 + 5i) = 16 + 20i − 20i − 25i
176+
```
177+
178+
The middle terms `(20i − 20i)` cancel out! Also `i^2 = −1` so we end up with this:
179+
180+
```text
181+
(4 − 5i)(4 + 5i) = 4^2 + 5^2
182+
```
183+
184+
Which is really quite a simple result. The general rule is:
185+
186+
```text
187+
(a + bi)(a − bi) = a^2 + b^2
188+
```
189+
190+
## References
191+
192+
- [Wikipedia](https://en.wikipedia.org/wiki/Complex_number)
193+
- [Math is Fun](https://www.mathsisfun.com/numbers/complex-numbers.html)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import ComplexNumber from '../ComplexNumber';
2+
3+
describe('ComplexNumber', () => {
4+
it('should create complex numbers', () => {
5+
const complexNumber = new ComplexNumber({ real: 1, imaginary: 2 });
6+
7+
expect(complexNumber).toBeDefined();
8+
expect(complexNumber.real).toBe(1);
9+
expect(complexNumber.imaginary).toBe(2);
10+
11+
const defaultComplexNumber = new ComplexNumber();
12+
expect(defaultComplexNumber.real).toBe(0);
13+
expect(defaultComplexNumber.imaginary).toBe(0);
14+
});
15+
16+
it('should add complex numbers', () => {
17+
const complexNumber1 = new ComplexNumber({ real: 1, imaginary: 2 });
18+
const complexNumber2 = new ComplexNumber({ real: 3, imaginary: 8 });
19+
20+
const complexNumber3 = complexNumber1.add(complexNumber2);
21+
const complexNumber4 = complexNumber2.add(complexNumber1);
22+
23+
expect(complexNumber3.real).toBe(1 + 3);
24+
expect(complexNumber3.imaginary).toBe(2 + 8);
25+
26+
expect(complexNumber4.real).toBe(1 + 3);
27+
expect(complexNumber4.imaginary).toBe(2 + 8);
28+
});
29+
30+
it('should add complex and natural numbers', () => {
31+
const complexNumber = new ComplexNumber({ real: 1, imaginary: 2 });
32+
const realNumber = new ComplexNumber({ real: 3 });
33+
34+
const complexNumber3 = complexNumber.add(realNumber);
35+
const complexNumber4 = realNumber.add(complexNumber);
36+
37+
expect(complexNumber3.real).toBe(1 + 3);
38+
expect(complexNumber3.imaginary).toBe(2);
39+
40+
expect(complexNumber4.real).toBe(1 + 3);
41+
expect(complexNumber4.imaginary).toBe(2);
42+
});
43+
44+
it('should subtract complex numbers', () => {
45+
const complexNumber1 = new ComplexNumber({ real: 1, imaginary: 2 });
46+
const complexNumber2 = new ComplexNumber({ real: 3, imaginary: 8 });
47+
48+
const complexNumber3 = complexNumber1.subtract(complexNumber2);
49+
const complexNumber4 = complexNumber2.subtract(complexNumber1);
50+
51+
expect(complexNumber3.real).toBe(1 - 3);
52+
expect(complexNumber3.imaginary).toBe(2 - 8);
53+
54+
expect(complexNumber4.real).toBe(3 - 1);
55+
expect(complexNumber4.imaginary).toBe(8 - 2);
56+
});
57+
58+
it('should subtract complex and natural numbers', () => {
59+
const complexNumber = new ComplexNumber({ real: 1, imaginary: 2 });
60+
const realNumber = new ComplexNumber({ real: 3 });
61+
62+
const complexNumber3 = complexNumber.subtract(realNumber);
63+
const complexNumber4 = realNumber.subtract(complexNumber);
64+
65+
expect(complexNumber3.real).toBe(1 - 3);
66+
expect(complexNumber3.imaginary).toBe(2);
67+
68+
expect(complexNumber4.real).toBe(3 - 1);
69+
expect(complexNumber4.imaginary).toBe(-2);
70+
});
71+
72+
it('should multiply complex numbers', () => {
73+
const complexNumber1 = new ComplexNumber({ real: 3, imaginary: 2 });
74+
const complexNumber2 = new ComplexNumber({ real: 1, imaginary: 7 });
75+
76+
const complexNumber3 = complexNumber1.multiply(complexNumber2);
77+
const complexNumber4 = complexNumber2.multiply(complexNumber1);
78+
79+
expect(complexNumber3.real).toBe(-11);
80+
expect(complexNumber3.imaginary).toBe(23);
81+
82+
expect(complexNumber4.real).toBe(-11);
83+
expect(complexNumber4.imaginary).toBe(23);
84+
});
85+
86+
it('should multiply complex numbers by themselves', () => {
87+
const complexNumber = new ComplexNumber({ real: 1, imaginary: 1 });
88+
89+
const result = complexNumber.multiply(complexNumber);
90+
91+
expect(result.real).toBe(0);
92+
expect(result.imaginary).toBe(2);
93+
});
94+
95+
it('should calculate i in power of two', () => {
96+
const complexNumber = new ComplexNumber({ real: 0, imaginary: 1 });
97+
98+
const result = complexNumber.multiply(complexNumber);
99+
100+
expect(result.real).toBe(-1);
101+
expect(result.imaginary).toBe(0);
102+
});
103+
104+
it('should divide complex numbers', () => {
105+
const complexNumber1 = new ComplexNumber({ real: 2, imaginary: 3 });
106+
const complexNumber2 = new ComplexNumber({ real: 4, imaginary: -5 });
107+
108+
const complexNumber3 = complexNumber1.divide(complexNumber2);
109+
110+
expect(complexNumber3.real).toBe(-7 / 41);
111+
expect(complexNumber3.imaginary).toBe(22 / 41);
112+
});
113+
});

0 commit comments

Comments
 (0)
Please sign in to comment.