# Complex

[JS](../../..) ⟩ [value](../..) ⟩ [object](../../obj) ⟩ [class](..) ⟩ [example]() ⟩ Complex&#x20;

{% hint style="success" %}
a class to represent <mark style="color:yellow;">**complex numbers**</mark>.
{% endhint %}

{% tabs %}
{% tab title="💾 程式" %}
* replit ⟩ [Complex](https://replit.com/@pegasusroe/Complex#Complex.js)

```javascript
class Complex {

    // ⭐️ static constant
    static get zero() { return new Complex(0) }  // 0
    static get one() { return new Complex(1) }   // 1
    static get i() { return new Complex(0, 1) }  // i

    // constructor
    constructor(a = 0, b = 0) {
        this.x = a;
        this.y = b;
    }

    // -z
    negate() {
        return new Complex(-this.x, -this.y);
    }

    // conjugate (x - yi)
    conjugate() {
        return new Complex(this.x, -this.y);
    }

    // z1 + z2
    plus({ x, y }) {
        return new Complex(x + this.x, y + this.y);
    }

    // z1 - z2
    minus({ x, y }) {
        return new Complex(this.x - x, this.y - y);
    }

    // z1 * z2
    times({ x: c, y: d }) {
        const { x: a, y: b } = this;
        return new Complex(a * c - b * d, a * d + b * c);
    }

    // |z|^2
    get magnitudeSquare() {
        return this.times(this.conjugate()).x;    // real number
    }

    // 1/z
    inverse() {
        // 1/z = z' / |z|^2 (where z' is conjugate of z)
        return this.conjugate().times(new Complex(1/this.magnitudeSquare));
    }

    // z1 / z2
    dividedBy(z2) {
        return this.times(z2.inverse());
    }

    // z^n (where n is an integer)
    toPower(n) {

        let result = Complex.one;
        if (n === 0) return result;

        if (n > 0) {
            while (n > 0) {
                result = result.times(this);
                n -= 1;
            }
            return result;
        }

        if (n < 0) {
            while (n < 0) {
                result = result.dividedBy(this);
                n += 1;
            }
            return result;
        }

    }

    // complex -> string
    toString() {

        const { x, y } = this;

        return (
            y === 0 ? `${x}`           :        // x
            x === 0 ? `${hideOne(y)}i` :        // yi
            `${x} ${y < 0 ? '-' : '+'} ${hideOne(Math.abs(y))}i`  // x + yi
        );

        function hideOne(y) {
            return (
                y ===  1 ? ``  :
                y === -1 ? `-` : `${y}`
            )
        }
    }
}

module.exports = Complex;
```
{% endtab %}

{% tab title="💈範例" %}
```javascript
const Complex = require('./Complex.js');

let z1 = new Complex(1, 1);    // 1 + i
let z2 = new Complex(3, -4);   // 3 - 4i
const i = Complex.i;           // i
const one = Complex.one;       // 1

z1.plus(z2),            // 4 - 3i
z1.minus(z2),           // -2 + 5i
z1.times(z2),           // 7 - i
z1.dividedBy(z2),       // -0.04 + 0.28i

i.toPower(4),           // 1
z1.toPower(3),          // -2 + 2i
i.inverse(),            // -i
i.negate(),             // -i
z1.inverse(),           // 0.5 - 0.5i
z1.magnitudeSquare,     // 2

[-2, -1, 0, 1, 2].map(x => z1.toPower(x).toString()),
// -0.5i, 0.5 - 0.5i, 1, 1 + i, 2i
```
{% endtab %}

{% tab title="📗 參考" %}
* [ ] [javascript-the-definitive-guide](../../../../master/ref/javascript-the-definitive-guide "mention") ⟩ 9.3.4 Example: A Complex Number Class&#x20;
{% endtab %}
{% endtabs %}
