src/elements/Complex.js
function Complex(real, imaginary, parameters) {
    abstractions.Element.call(this, utilities.types.NUMBER, parameters);

    // normalize the values
    if (real === undefined || real === null || real === -0) {
        real = 0;
    }
    real = utilities.precision.lockOnExtreme(real);
    if (imaginary === undefined || imaginary === null || imaginary === -0) {
        imaginary = 0;
    }
    if (imaginary.getTypeId && imaginary.getTypeId() === utilities.types.ANGLE) {
        // convert polar to rectangular
        var magnitude = real;
        var phase = imaginary;
        if (magnitude < 0) {
            // normalize the magnitude
            magnitude = -magnitude;
            phase = Angle.inverse(phase);
        }
        real = magnitude * Angle.cosine(phase);
        imaginary = magnitude * Angle.sine(phase);
    }
    imaginary = utilities.precision.lockOnExtreme(imaginary);
    if (real.toString() === 'NaN' || imaginary.toString() === 'NaN') {
        real = NaN;
        imaginary = NaN;
    } else if (real === Infinity || real === -Infinity || imaginary === Infinity || imaginary === -Infinity) {
        real = Infinity;
        imaginary = Infinity;
    }
    this.getReal = function() { return real; };
    this.getImaginary = function() { return imaginary; };
    this.getMagnitude = function() {
        // need to preserve full precision on this except for the sum part
        var magnitude = Math.sqrt(utilities.precision.sum(Math.pow(real, 2), Math.pow(imaginary, 2)));
        magnitude = utilities.precision.lockOnExtreme(magnitude);
        return magnitude;
    };

    this.getPhase = function() {
        if (this.isInfinite()) return new Angle(0);
        if (this.isUndefined()) return undefined;
        const phase = Angle.arctangent(imaginary, real);
        return phase;
    };


    return this;
}
function Complex(real, imaginary, parameters) {
    abstractions.Element.call(this, utilities.types.NUMBER, parameters);

    // normalize the values
    if (real === undefined || real === null || real === -0) {
        real = 0;
    }
    real = utilities.precision.lockOnExtreme(real);
    if (imaginary === undefined || imaginary === null || imaginary === -0) {
        imaginary = 0;
    }
    if (imaginary.getTypeId && imaginary.getTypeId() === utilities.types.ANGLE) {
        // convert polar to rectangular
        var magnitude = real;
        var phase = imaginary;
        if (magnitude < 0) {
            // normalize the magnitude
            magnitude = -magnitude;
            phase = Angle.inverse(phase);
        }
        real = magnitude * Angle.cosine(phase);
        imaginary = magnitude * Angle.sine(phase);
    }
    imaginary = utilities.precision.lockOnExtreme(imaginary);
    if (real.toString() === 'NaN' || imaginary.toString() === 'NaN') {
        real = NaN;
        imaginary = NaN;
    } else if (real === Infinity || real === -Infinity || imaginary === Infinity || imaginary === -Infinity) {
        real = Infinity;
        imaginary = Infinity;
    }
    this.getReal = function() { return real; };
    this.getImaginary = function() { return imaginary; };
    this.getMagnitude = function() {
        // need to preserve full precision on this except for the sum part
        var magnitude = Math.sqrt(utilities.precision.sum(Math.pow(real, 2), Math.pow(imaginary, 2)));
        magnitude = utilities.precision.lockOnExtreme(magnitude);
        return magnitude;
    };

    this.getPhase = function() {
        if (this.isInfinite()) return new Angle(0);
        if (this.isUndefined()) return undefined;
        const phase = Angle.arctangent(imaginary, real);
        return phase;
    };


    return this;
}
function Complex ( real , imaginary , parameters ) { abstractions . Element . call ( this , utilities . types . NUMBER , parameters ) ; // normalize the values if ( real === undefined || real === null || real === - 0 ) { real = 0 ; } real = utilities . precision . lockOnExtreme ( real ) ; if ( imaginary === undefined || imaginary === null || imaginary === - 0 ) { imaginary = 0 ; } if ( imaginary . getTypeId && imaginary . getTypeId ( ) === utilities . types . ANGLE ) { // convert polar to rectangular var magnitude = real ; var phase = imaginary ; if ( magnitude < 0 ) { // normalize the magnitude magnitude = - magnitude ; phase = Angle . inverse ( phase ) ; } real = magnitude * Angle . cosine ( phase ) ; imaginary = magnitude * Angle . sine ( phase ) ; } imaginary = utilities . precision . lockOnExtreme ( imaginary ) ; if ( real . toString ( ) === 'NaN' || imaginary . toString ( ) === 'NaN' ) { real = NaN ; imaginary = NaN ; } else if ( real === Infinity || real === - Infinity || imaginary === Infinity || imaginary === - Infinity ) { real = Infinity ; imaginary = Infinity ; } this . getReal = function ( ) { return real ; } ; this . getImaginary = function ( ) { return imaginary ; } ; this . getMagnitude = function ( ) { // need to preserve full precision on this except for the sum part var magnitude = Math . sqrt ( utilities . precision . sum ( Math . pow ( real , 2 ) , Math . pow ( imaginary , 2 ) ) ) ; magnitude = utilities . precision . lockOnExtreme ( magnitude ) ; return magnitude ; } ; this . getPhase = function ( ) { if ( this . isInfinite ( ) ) return new Angle ( 0 ) ; if ( this . isUndefined ( ) ) return undefined ; const phase = Angle . arctangent ( imaginary , real ) ; return phase ; } ; return this ; }
PUBLIC CONSTRUCTORS 
This constructor creates an immutable instance of a complex number using the specified
real and imaginary values.  If the imaginary value is an angle then the complex number
is in polar form, otherwise it is in rectangular form.

@constructor
@param {Number} real The real value of the complex number.
@param {Number|Angle} imaginary The imaginary value of the complex number.
@param {Parameters} parameters Optional parameters used to parameterize this element.
@returns {Complex} The new complex number.
PUBLIC CONSTRUCTORS This constructor creates an immutable instance of a complex number using the specified real and imaginary values . If the imaginary value is an angle then the complex number is in polar form otherwise it is in rectangular form .