# Complex Number Calculator

Page 1 of 1

## 0 Replies - 2196 Views - Last Post: 26 March 2014 - 06:19 AM

### #1 Dormilich

• 痛覚残留

Reputation: 4138
• Posts: 13,074
• Joined: 08-June 10

# Complex Number Calculator

Posted 26 March 2014 - 06:19 AM

```/**
* An object representing a complex number supporting the base
* calculations (+, –, *, /) and the computation of conjugate
* complex numbers.
* The script makes use of ECMAScript 5’s property descriptors
* and thus may only run in appropriate, supporting browsers. The
* implementation forces a complete lock-down of the constructor
* object and the instance properties "re" and "im" are defined
* through accessors. There should be no issue from deleted or
* changed properties now.
*
* @author Bertold von Dormilich <Dormilich at netscape dot net>
* @created October 13, 2011
*/
/**
* Short API
*   METHOD       OPERATION
* subtract()       a - b
* subtractFrom()   b - a
* multiply()       a · b
* divideBy()       a ÷ b
* divisionOf()     b ÷ a
* conjugate()      a* / x - y·i
* absolute()       a · a* / x² + y²
* toString()       "x + y·i"
* valueOf()        length / sqrt(a·a*) / sqrt(x² + y²)
*
* the static methods are intended for internal use only.
*/

/**
* constructor for complex number object. both input parameters
* must evaluate as a number. If a value is assigned to either
* "re" or "im", this value is checked for validaty as well.
*
* @param (mixed) r     real part of the complex number
* @param (mixed) i     imaginary part of the complex number
* @throws (Error)      number conversion failed
*/
function Complex(r, i)
{
// convert input to number
function valueToNumber(x)
{
x = parseFloat(x);
if (isNaN(x)) {
throw new Error("Parameter does not qualify for a complex number.");
}
return x;
}
// where the values are saved
r = valueToNumber(r);
i = valueToNumber(i);
// definition of the "virtual" properties "re"/"im"
// this.re
Object.defineProperty(this, "re", {
get : function () { return r; },
set : function (real) { r = valueToNumber(real); }
});
// this.im
Object.defineProperty(this, "im", {
get : function () { return i; },
set : function (imaginary) { i = valueToNumber(imaginary); }
});
}
/**
* create a new complex number based on the addition of the
* real/imaginary parameters of two complex numbers.
*
* @param (number) r1       real part of the 1st summand
* @param (number) i1       imaginary part of the 1st summand
* @param (number) r2       real part of the 2nd summand
* @param (number) i2       imaginary part of the 2n summand
* @return (Complex)        complex number of the sum
*/
Complex.addParameters = function (r1, i1, r2, i2)
{
return new Complex(r1 + r2, i1 + i2);
};
/**
* add two complex numbers. the 2nd summand may be given as object
* or via its real/imaginary parameters.
*
* @param (mixed) num       either an instance of Complex or a set
*                          of exactly two numbers representing the
*                          real and imaginary part
* @return (Complex)        complex number of the sum (this + num)
* @throws (Error)          parameters don’t match
*/
{
if (2 === arguments.length) {
num = new Complex(arguments[0], arguments[1]);
}
if (num instanceof Complex) {
}
throw new Error("Invalid complex number given.");
};
/**
* create a new complex number based on the subtraction of the
* real/imaginary parameters of two complex numbers.
*
* @param (number) r1       real part of the minuend
* @param (number) i1       imaginary part of the minuend
* @param (number) r2       real part of the subtrahend
* @param (number) i2       imaginary part of the subtrahend
* @return (Complex)        complex number of the difference
*/
Complex.subParameters = function (r1, i1, r2, i2)
{
return new Complex(r1 - r2, i1 - i2);
};
/**
* subtract two complex numbers. the current instance is the minuend
* (first term in the difference equation) the given parameter is the
* subtrahend (second term in the difference equation).
*
* @param (mixed) num       either an instance of Complex or a set
*                          of exactly two numbers representing the
*                          real and imaginary part
* @return (Complex)        complex number of the difference (this - num)
* @throws (Error)          parameters don’t match
*/
Complex.prototype.subtract = function (num)
{
if (2 === arguments.length) {
num = new Complex(arguments[0], arguments[1]);
}
if (num instanceof Complex) {
return Complex.subParameters(this.re, this.im, num.re, num.im);
}
throw new Error("Invalid complex number given.");
};
/**
* subtract two complex numbers. the current instance is the subtrahend
* (second term in the difference equation) the given parameter is the
* minuend (second term in the difference equation). only useful if the
* minuend is not given as object, otherwise you should use the subtract()
* method of the minuend or it used in chaining.
*
* @param (mixed) num       either an instance of Complex or a set
*                          of exactly two numbers representing the
*                          real and imaginary part
* @return (Complex)        complex number of the difference (num - this)
* @throws (Error)          parameters don’t match
*/
Complex.prototype.subtractFrom = function (num)
{
if (2 === arguments.length) {
num = new Complex(arguments[0], arguments[1]);
}
if (num instanceof Complex) {
return num.subtract(this);
}
throw new Error("Invalid complex number given.");
};
/**
* create a new complex number based on the multiplication of the
* real/imaginary parameters of two complex numbers, based on the
* binomial theorem.
*
* @param (number) r1       real part of the 1st factor
* @param (number) i1       imaginary part of 1st factor
* @param (number) r2       real part of the 2nd factor
* @param (number) i2       imaginary part of the 2nd factor
* @return (Complex)        complex number of the product
*/
Complex.multParameters = function (r1, i1, r2, i2)
{
return new Complex(r1 * r2 - i1 * i2, r1 * i2 + r2 * i1);
};
/**
* multiply two complex numbers. the 2nd factor may be given as object
* or via its real/imaginary parameters.
*
* @param (mixed) num       either an instance of Complex or a set
*                          of exactly two numbers representing the
*                          real and imaginary part
* @return (Complex)        complex number of the product (this * num)
* @throws (Error)          parameters don’t match
*/
Complex.prototype.multiply = function (num)
{
if (2 === arguments.length) {
num = new Complex(arguments[0], arguments[1]);
}
if (num instanceof Complex) {
return Complex.multParameters(this.re, this.im, num.re, num.im);
}
throw new Error("Invalid complex number given.");
};
/**
* divide two complex numbers. the divisor may be given as object
* or via its real/imaginary parameters. complex division is done
* according to the binomial theorem: a ÷ b = (a · b*) ÷ (b · b*)
* [b* - complex conjugate of b; b·b* is always a real number]
*
* @param (mixed) num       divisor, either an instance of Complex or
*                          a set of exactly two numbers representing
*                          the real and imaginary part
* @return (Complex)        complex number of the quotient (this ÷ num)
* @throws (Error)          parameters don’t match
*/
Complex.prototype.divideBy = function (num)
{
if (2 === arguments.length) {
num = new Complex(arguments[0], arguments[1]);
}
if (num instanceof Complex) {
var abs  = num.absolute(),                      // b·b*
prod = num.conjugate().multiply(this);      // a·b*
prod.re /= abs;
prod.im /= abs;
return prod;
}
throw new Error("Invalid complex number given.");
};
/**
* same as divideBy() only with divisor and dividend exchanged.
* allows to divide the current instance from a number given as
* parameters or for chaining.
*
* @param (mixed) num       dividend, either an instance of Complex or
*                          a set of exactly two numbers representing
*                          the real and imaginary part
* @return (Complex)        complex number of the quotient (num ÷ this)
* @throws (Error)          parameters don’t match
*/
Complex.prototype.divisionOf = function (num)
{
if (2 === arguments.length) {
num = new Complex(arguments[0], arguments[1]);
}
if (num instanceof Complex) {
return num.divideBy(this);
}
throw new Error("Invalid complex number given.");
};
/**
* create the conjugate complex number. if n = a + b·i, the conjugate
* complex is n* = a - b·i. useful in many mathematical operations
* (related to Matrix algebra).
*
* @return (Complex)        conjugate complex number
*/
Complex.prototype.conjugate = function ()
{
return new Complex(this.re, -1 * this.im);
};
/**
* result of the operation n·n*. equivalent to the square of the
* vectorial length of the complex number in the complex plane.
*
* @return (number)         conjugate complex number
*/
Complex.prototype.absolute = function ()
{
return this.conjugate().multiply(this).re;
};
/**
* string representation as: a + b·i. used in Javascript when a string
* representation is required, e.g. for printing values to the document.
*
* @param (number) acc      number of post decimal positions
* @return (string)         rectangular expression of the complex number
*/
Complex.prototype.toString = function (acc)
{
var re = this.re,
im = Math.abs(this.im);

if ((typeof acc == "number") && (acc >= 0)) {
re = re.toFixed(acc);
im = im.toFixed(acc);
}
if (0 === this.im) {
return re;
}
return re + (this.im < 0 ? " – " : " + ") + (1 == im ? "i" : im + "·i");
};
/**
* length of the vector in rectangular expression of the complex number.
* used in Javascript operations that require a number, e.g. 2 * c.
*
* @return (number)         length value of the complex number
*/
Complex.prototype.valueOf = function ()
{
return Math.sqrt(this.absolute());
};

// prevent further modifications of the Complex object
Object.freeze(Complex);

```

Usage:
```//create complex numbers:
var c1 = new Complex(1, 2); // 1 + 2i
var c2 = new Complex(1, -1); // 1 - i