complex.js | |
---|---|
This module defines a constructor for complex number objects. It is by no means a complete class, as it lacks many operations you would expect to be able to perform with complex numbers. It simply covers the needs of this particular application. Binary operations (e.g. addition, multiplication, etc) are added directly to the | |
define(
['underscore'],
function(_) {
| |
Constructor. |
function Complex(real, imaginary) {
if (imaginary === undefined) imaginary = 0.0;
if (!_.isNumber(real) || !_.isNumber(imaginary)) throw new TypeError();
this.real = real;
this.imaginary = imaginary;
}
|
This method returns |
Complex.prototype.isReal = function() {
return Math.abs(this.imaginary) < Complex.EPSILON;
};
|
Returns the modulus, or absolute value, which for a complex number $z = a + bi$ is defined as $$|z| = \sqrt{a^2 + b^2}$$ |
Complex.prototype.modulus = function() {
return Math.sqrt(this.modulusSquared());
};
|
Returns the modulus squared, which for a complex number $z = a + bi$ is equal to $$|z|^2 = a^2 + b^2$$ |
Complex.prototype.modulusSquared = function() {
return this.real * this.real + this.imaginary * this.imaginary;
};
|
Returns the argument or phase, which for a complex number $z = a + bi$ is defined as $$\angle z = \operatorname{atan2}(b, a)$$ |
Complex.prototype.argument = function() {
return Math.atan2(this.imaginary, this.real);
};
|
Returns the complex conjugate, which for a complex number $z = a + bi$ is defined as $$\bar{z} = a - bi$$ |
Complex.prototype.conjugate = function() {
return new Complex(this.real, -this.imaginary);
};
|
Returns the multiplicative inverse, which for a complex number $z = a + bi$ is equal to $$\frac{1}{z} = \frac{\bar{z}}{z\bar{z}} = \frac{a - bi}{a^2 + b^2}$$ |
Complex.prototype.reciprocal = function() {
var modulusSquared = this.real * this.real + this.imaginary * this.imaginary;
return new Complex(this.real / modulusSquared, -this.imaginary / modulusSquared);
};
|
Returns the additive inverse, which for a complex number $z = a + bi$ is equal to $$-z = -a -bi$$ |
Complex.prototype.negation = function() {
return new Complex(-this.real, -this.imaginary);
};
|
Scales the complex number by a real factor such that its modulus equals |
Complex.prototype.scaleModulusTo = function(x) {
var scaleFactor = x / this.modulus();
this.real *= scaleFactor;
this.imaginary *= scaleFactor;
};
|
Takes the |
Complex.prototype.root = function(n) {
var r = Math.pow(this.modulus(), 1/n);
var phi = this.argument() / n;
return Complex.fromPolar(r, phi);
};
|
Returns a string describing the complex number in $a + bi$ form. |
Complex.prototype.toString = function() {
if (this.isReal()) return this.real;
return this.real + " + " + this.imaginary + "i";
};
|
Returns a new complex number from a combination of modulus |
Complex.fromPolar = function(r, phi) {
return new Complex(r * Math.cos(phi), r * Math.sin(phi));
};
|
Adds two complex numbers |
Complex.add = function(lhs, rhs) {
return new Complex(lhs.real + rhs.real, lhs.imaginary + rhs.imaginary);
};
|
Subtracts the complex numbers |
Complex.subtract = function(lhs, rhs) {
return new Complex(lhs.real - rhs.real, lhs.imaginary - rhs.imaginary);
};
|
Multiplies two complex numbers |
Complex.multiply = function(lhs, rhs) {
var real = lhs.real * rhs.real - lhs.imaginary * rhs.imaginary;
var imaginary = lhs.real * rhs.imaginary + lhs.imaginary * rhs.real;
return new Complex(real, imaginary);
};
|
Divides two complex number |
Complex.divide = function (lhs, rhs) {
var modulusSquared = rhs.real * rhs.real + rhs.imaginary * rhs.imaginary;
var real = lhs.real * rhs.real + lhs.imaginary * rhs.imaginary;
var imaginary = lhs.imaginary * rhs.real - lhs.real * rhs.imaginary;
return new Complex(real / modulusSquared, imaginary / modulusSquared);
};
|
Returns the complex exponential $exp($ |
Complex.exp = function(z) {
var realPart = new Complex(Math.exp(z.real));
var imaginaryPart = new Complex(Math.cos(z.imaginary), Math.sin(z.imaginary));
return Complex.multiply(realPart, imaginaryPart);
};
|
Returns |
Complex.areEqual = function(lhs, rhs) {
if (lhs === rhs) return true;
if (lhs === null || rhs === null || lhs === undefined || rhs === undefined) return false;
return (Math.abs(lhs.real - rhs.real) < Complex.EPSILON) &&
(Math.abs(lhs.imaginary - rhs.imaginary) < Complex.EPSILON);
};
|
The small $\varepsilon$-value used for equality testing. |
Complex.EPSILON = 1e-10;
return Complex;
});
|