New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

numbers

Package Overview
Dependencies
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

numbers - npm Package Compare versions

Comparing version 0.0.2 to 0.4.0

.jshintrc

21

lib/numbers.js
/**
* numbers.js
* http://github.com/sjkaliski/numbers.js
*
* top level management of numbers extensions
* Copyright 2012 Stephen Kaliski
*
* (C) 2012 Steve Kaliski
* MIT License
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var numbers = exports;

@@ -16,6 +27,8 @@

numbers.calculus = require('./numbers/calculus');
numbers.complex = require('./numbers/complex');
numbers.dsp = require('./numbers/dsp');
numbers.matrix = require('./numbers/matrix');
numbers.prime = require('./numbers/prime');
numbers.statistic = require('./numbers/statistic');
numbers.useless = require('./numbers/useless');
numbers.generate = require('./numbers/generators');

@@ -22,0 +35,0 @@ /**

@@ -0,17 +1,38 @@

/**
* basic.js
* http://github.com/sjkaliski/numbers.js
*
* Copyright 2012 Stephen Kaliski
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var basic = exports;
/**
* Determine the summation of numbers in a given array
* Determine the summation of numbers in a given array.
*
* @param {Array} collection of numbers
* @return {Number} sum of numbers in array
* @param {Array} collection of numbers.
* @return {Number} sum of numbers in array.
*/
basic.addition = function (arr) {
basic.sum = function (arr) {
if (Object.prototype.toString.call(arr) === '[object Array]') {
var total = 0;
for (var i = 0 ; i < arr.length ; i++) {
if (typeof(arr[i]) === 'number')
if (typeof(arr[i]) === 'number') {
total = total + arr[i];
else
} else {
throw new Error('All elements in array must be numbers');
}
}

@@ -29,4 +50,4 @@ return total;

*
* @param {Array} collection of numbers
* @return {Number} difference
* @param {Array} collection of numbers.
* @return {Number} difference.
*/

@@ -37,6 +58,7 @@ basic.subtraction = function (arr) {

for (var i = arr.length - 2; i >= 0; i--) {
if (typeof(arr[i]) === 'number')
if (typeof(arr[i]) === 'number') {
total -= arr[i];
else
} else {
throw new Error('All elements in array must be numbers');
}
}

@@ -50,6 +72,6 @@ return total;

/**
* Product of all elements in an array
* Product of all elements in an array.
*
* @param {Array} collection of numbers
* @return {Number} product
* @param {Array} collection of numbers.
* @return {Number} product.
*/

@@ -59,7 +81,8 @@ basic.product = function (arr) {

var total = arr[0];
for (var i = 1; i < arr.length; i++) {
if (typeof(arr[i]) === 'number')
for (var i = 1, length = arr.length; i < length; i++) {
if (typeof(arr[i]) === 'number') {
total = total * arr[i];
else
} else {
throw new Error('All elements in array must be numbers');
}
}

@@ -73,20 +96,48 @@ return total;

/**
* Factorial for some integer
* Return the square of any value.
*
* @param {Number} integer
* @return {Number} result
* @param {Number} number
* @return {Number} square of number
*/
basic.factorial = function (num) {
basic.square = function (num) {
return num * num;
};
/**
* Calculate the binomial coefficient (n choose k)
*
* @param {Number} available choices
* @param {Number} number chosen
* @return {Number} number of possible choices
*/
basic.binomial = function (n, k) {
var arr = [];
function _factorial(n) {
if (n === 0 || n === 1) return 1;
function _binomial (n, k) {
if (n >= 0 && k === 0) return 1;
if (n === 0 && k > 0) return 0;
if (arr[n] && arr[n][k] > 0) return arr[n][k];
if (!arr[n]) arr[n] = [];
if (arr[n] > 0) return arr[n];
return arr[n][k] = _binomial(n - 1, k - 1) + _binomial(n - 1, k);
}
else return arr[n] = _factorial(n - 1) * n;
return _binomial(n, k);
};
/**
* Factorial for some integer.
*
* @param {Number} integer.
* @return {Number} result.
*/
basic.factorial = function (num){
var i = 2, o = 1;
while (i <= num) {
o *= i++;
}
return _factorial(num);
return o;
};

@@ -96,31 +147,20 @@

* Calculate the greastest common divisor amongst two integers.
*
* @param {Number} number A
* @param {Number} number B
* @return {Number} greatest common divisor for integers A, B
* Taken from Ratio.js https://github.com/LarryBattle/Ratio.js
*
* @param {Number} number A.
* @param {Number} number B.
* @return {Number} greatest common divisor for integers A, B.
*/
basic.gcd = function (num1, num2) {
var result;
if (num1 > num2) {
for (var i = 0 ; i <= num2 ; i++) {
if (num2 % i === 0) {
if (num1 % i === 0) {
result = i;
}
}
}
return result;
} else if (num2 > num1) {
for (var j = 0 ; j <= num2 ; j++) {
if (num1 % j === 0) {
if (num2 % j === 0) {
result = j;
}
}
}
return result;
} else {
result = num1 * num2 / num1;
return result;
basic.gcd = function (a, b) {
var c;
b = (+b && +a) ? +b : 0;
a = b ? a : 1;
while (b) {
c = a % b;
a = b;
b = c;
}
return Math.abs(a);
};

@@ -131,8 +171,8 @@

*
* @param {Number} number A
* @param {Number} number B
* @return {Number} least common multiple for integers A, B
* @param {Number} number A.
* @param {Number} number B.
* @return {Number} least common multiple for integers A, B.
*/
basic.lcm = function (num1, num2) {
return Math.abs(num1 * num2) / basic.gcd(num1,num2);
return Math.abs(num1 * num2) / basic.gcd(num1, num2);
};

@@ -143,11 +183,20 @@

*
* @param {Array} set of values to select from
* @param {Number} quantity of elements to retrieve
* @return {Array} random elements
* @param {Array} set of values to select from.
* @param {Number} quantity of elements to retrieve.
* @param {Boolean} allow the same number to be returned twice.
* @return {Array} random elements.
*/
basic.random = function (arr, quant) {
if (arr.length <= quant){
basic.random = function (arr, quant, allowDuplicates) {
if (arr.length === 0){
throw new Error('Empty array');
} else if (quant > arr.length && !allowDuplicates){
throw new Error('Quantity requested exceeds size of array');
} else if (arr.length === 0){
throw new Error('Empty array');
}
if (allowDuplicates === true) {
var result = [], i;
for (i = 0; i < quant; i++) {
result[i] = arr[Math.floor(Math.random() * arr.length)];
}
return result;
} else {

@@ -159,6 +208,6 @@ return basic.shuffle(arr).slice(0, quant);

/**
* Shuffle an array, in place
* Shuffle an array, in place.
*
* @param {Array} array to be shuffled
* @return {Array} shuffled array
* @param {Array} array to be shuffled.
* @return {Array} shuffled array.
*/

@@ -178,1 +227,157 @@ basic.shuffle = function (array) {

};
/**
* Find maximum value in an array.
*
* @param {Array} array to be traversed.
* @return {Number} maximum value in the array.
*/
basic.max = function (array) {
return Math.max.apply(Math, array);
};
/**
* Find minimum value in an array.
*
* @param {Array} array to be traversed.
* @return {Number} minimum value in the array.
*/
basic.min = function (array) {
return Math.min.apply(Math, array);
};
/**
* Create a range of numbers.
*
* @param {Number} The start of the range.
* @param {Number} The end of the range.
* @return {Array} An array containing numbers within the range.
*/
basic.range = function (start, stop, step) {
var array, i = 0, len;
if (arguments.length <= 1) {
stop = start || 0;
start = 0;
}
step = step || 1;
if (stop < start) {
step = 0 - Math.abs(step);
}
len = Math.max(Math.ceil((stop - start) / step) + 1, 0);
array = new Array(len);
while (i < len) {
array[i++] = start;
start += step;
}
return array;
};
/**
* Determine if the number is an integer.
*
* @param {Number} the number
* @return {Boolean} true for int, false for not int.
*/
basic.isInt = function (n) {
return n % 1 === 0;
};
/**
* Calculate the divisor and modulus of two integers.
*
* @param {Number} int a.
* @param {Number} int b.
* @return {Array} [div, mod].
*/
basic.divMod = function (a, b) {
if (!basic.isInt(a) || !basic.isInt(b)) return false;
return [Math.floor(a / b), a % b];
};
/**
* Calculate:
* if b >= 1: a^b mod m.
* if b = -1: modInverse(a, m).
* if b < 1: finds a modular rth root of a such that b = 1/r.
*
* @param {Number} Number a.
* @param {Number} Number b.
* @param {Number} Modulo m.
* @return {Number} see the above documentation for return values.
*/
basic.powerMod = function (a, b, m) {
// If b < -1 should be a small number, this method should work for now.
if (b < -1) return Math.pow(a, b) % m;
if (b === 0) return 1 % m;
if (b >= 1) {
var result = 1;
while (b > 0) {
if ((b % 2) === 1) {
result = (result * a) % m;
}
a = (a * a) % m;
b = b >> 1;
}
return result;
}
if (b === -1) return basic.modInverse(a, m);
if (b < 1) {
return basic.powerMod(a, Math.pow(b, -1), m);
}
};
/**
* Calculate the extended Euclid Algorithm or extended GCD.
*
* @param {Number} int a.
* @param {Number} int b.
* @return {Array} [a, x, y] a is the GCD. x and y are the values such that ax + by = gcd(a, b) .
*/
basic.egcd = function (a, b) {
var x = (+b && +a) ? 1 : 0,
y = b ? 0 : 1,
u = (+b && +a) ? 0 : 1,
v = b ? 1 : 0;
b = (+b && +a) ? +b : 0;
a = b ? a : 1;
while (b) {
var dm = basic.divMod(a, b),
q = dm[0],
r = dm[1];
var m = x - u * q,
n = y - v * q;
a = b;
b = r;
x = u;
y = v;
u = m;
v = n;
}
return [a, x, y];
};
/**
* Calculate the modular inverse of a number.
* @param {Number} Number a.
* @param {Number} Modulo m.
* @return {Number} if true, return number, else throw error.
*/
basic.modInverse = function (a, m) {
var r = basic.egcd(a, m);
if (r[0] != 1) throw new Error('No modular inverse exists');
return r[1] % m;
};

158

lib/numbers/calculus.js

@@ -0,5 +1,24 @@

/**
* calculus.js
* http://github.com/sjkaliski/numbers.js
*
* Copyright 2012 Stephen Kaliski
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var numbers = require('../numbers');
var calculus = exports;
/**

@@ -9,14 +28,13 @@ * Calculate point differential for a specified function at a

*
* @param {Function} math function to be evaluated
* @param {Number} point to be evaluated
* @return {Number} result
* @param {Function} math function to be evaluated.
* @param {Number} point to be evaluated.
* @return {Number} result.
*/
calculus.pointDiff = function (func, point) {
var a = func(point - 0.00001);
var b = func(point + 0.00001);
var a = func(point - 0.001);
var b = func(point + 0.001);
return (b - a) / (0.00002);
return (b - a) / (0.002);
};
/**

@@ -26,13 +44,15 @@ * Calculate riemann sum for a specified, one variable, function

*
* @param {Function} math function to be evaluated
* @param {Number} point to initiate evaluation
* @param {Number} point to complete evaluation
* @param {Number} quantity of divisions
* @param {Function} math function to be evaluated.
* @param {Number} point to initiate evaluation.
* @param {Number} point to complete evaluation.
* @param {Number} quantity of divisions.
* @param {Function} (Optional) Function that returns which value
* to sample on each interval; if none is provided, left endpoints
* will be used.
* @return {Number} result
* to sample on each interval; if none is provided, left endpoints
* will be used.
* @return {Number} result.
*/
calculus.riemann = function (func, start, finish, n, sampler) {
var inc = (finish - start) / n, totalHeight = 0, i;
calculus.Riemann = function (func, start, finish, n, sampler) {
var inc = (finish - start) / n;
var totalHeight = 0;
var i;

@@ -52,3 +72,2 @@ if (typeof sampler === 'function') {

/**

@@ -58,8 +77,8 @@ * Helper function in calculating integral of a function

*
* @param {Function} math function to be evaluated
* @param {Number} point to initiate evaluation
* @param {Number} point to complete evaluation
* @return {Number} evaluation
* @param {Function} math function to be evaluated.
* @param {Number} point to initiate evaluation.
* @param {Number} point to complete evaluation.
* @return {Number} evaluation.
*/
function simpsonDef (func, a, b) {
function SimpsonDef (func, a, b) {
var c = (a + b) / 2;

@@ -70,3 +89,2 @@ var d = Math.abs(b - a) / 6;

/**

@@ -77,13 +95,13 @@ * Helper function in calculating integral of a function

*
* @param {Function} math function to be evaluated
* @param {Number} point to initiate evaluation
* @param {Number} point to complete evaluation
* @param {Number} total value
* @param {Number} Error bound (epsilon)
* @return {Number} recursive evaluation of left and right side
* @param {Function} math function to be evaluated.
* @param {Number} point to initiate evaluation.
* @param {Number} point to complete evaluation.
* @param {Number} total value.
* @param {Number} Error bound (epsilon).
* @return {Number} recursive evaluation of left and right side.
*/
function simpsonRecursive (func, a, b, whole, eps) {
var c = a + b,
left = simpsonDef(func, a, c),
right = simpsonDef(func, c, b);
function SimpsonRecursive (func, a, b, whole, eps) {
var c = a + b;
var left = SimpsonDef(func, a, c);
var right = SimpsonDef(func, c, b);

@@ -93,38 +111,36 @@ if (Math.abs(left + right - whole) <= 15 * eps) {

} else {
return simpsonRecursive(func, a, c, eps/2, left) + simpsonRecursive(func, c, b, eps / 2, right);
return SimpsonRecursive(func, a, c, eps / 2, left) + SimpsonRecursive(func, c, b, eps / 2, right);
}
}
/**
* Evaluate area under a curve using adaptive simpson quadrature.
*
* @param {Function} math function to be evaluated
* @param {Number} point to initiate evaluation
* @param {Number} point to complete evaluation
* @param {Function} math function to be evaluated.
* @param {Number} point to initiate evaluation.
* @param {Number} point to complete evaluation.
* @param {Number} Optional error bound (epsilon);
* global error bound will be used as a fallback.
* @return {Number} area underneath curve
* global error bound will be used as a fallback.
* @return {Number} area underneath curve.
*/
calculus.adaptiveSimpson = function (func, a, b, eps) {
eps = (typeof eps === "undefined") ? numbers.EPSILON : eps;
eps = (typeof eps === 'undefined') ? numbers.EPSILON : eps;
return simpsonRecursive(func, a, b, simpsonDef(func, a, b), eps);
return SimpsonRecursive(func, a, b, SimpsonDef(func, a, b), eps);
};
/**
* Calculate limit of a function at a given point. Can approach from
* Calculate limit of a function at a given point. Can approach from
* left, middle, or right.
*
* @param {Function} math function to be evaluated
* @param {Number} point to evaluate
* @param {String} approach to limit
* @return {Number} limit
* @param {Function} math function to be evaluated.
* @param {Number} point to evaluate.
* @param {String} approach to limit.
* @return {Number} limit.
*/
calculus.limit = function (func, point, approach) {
if (approach === 'left') {
return func(point - 0.001);
return func(point - 1e-15);
} else if (approach === 'right') {
return func(point + 0.001);
return func(point + 1e-15);
} else if (approach === 'middle') {

@@ -136,1 +152,41 @@ return (calculus.limit(func, point, 'left') + calculus.limit(func, point, 'right')) / 2;

};
/**
* Calculate Stirling approximation gamma.
*
* @param {Number} number to calculate.
* @return {Number} gamma.
*/
calculus.StirlingGamma = function (num) {
return Math.sqrt(2 * Math.PI / num) * Math.pow((num / Math.E), num);
};
/**
* Calculate Lanczos approximation gamma.
*
* @param {Number} number to calculate.
* @return {Number} gamma.
*/
calculus.LanczosGamma = function (num) {
var p = [
0.99999999999980993, 676.5203681218851, -1259.1392167224028,
771.32342877765313, -176.61502916214059, 12.507343278686905,
-0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7
];
var i;
var g = 7;
if(num < 0.5) return Math.PI / (Math.sin(Math.PI * num) * calculus.LanczosGamma(1 - num));
num -= 1;
var a = p[0];
var t = num + g + 0.5;
for (i = 1; i < p.length; i++) {
a += p[i] / (num + i);
}
return Math.sqrt(2 * Math.PI) * Math.pow(t, num + 0.5) * Math.exp(-t) * a;
};

@@ -0,8 +1,60 @@

/**
* matrix.js
* http://github.com/sjkaliski/numbers.js
*
* Copyright 2012 Stephen Kaliski
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var matrix = exports;
/**
* Return a deep copy of the input matrix.
*
* @param {Array} matrix to copy.
* @return {Array} copied matrix.
*/
matrix.deepCopy = function(arr) {
if (arr[0][0] === undefined) {
throw new Error('Input cannot be a vector.');
}
var result = new Array(arr.length);
for (var i = 0; i < arr.length; i++) {
result[i] = arr[i].slice();
}
return result;
};
/**
* Return true if matrix is square, false otherwise.
*
* @param {Array} arr
*/
matrix.isSquare = function(arr) {
var rows = arr.length;
var cols = arr[0].length;
return rows === cols;
};
/**
* Add two matrices together. Matrices must be of same dimension.
*
* @param {Array} matrix A
* @param {Array} matrix B
* @param {Array} matrix A.
* @param {Array} matrix B.
* @return {Array} summed matrix.

@@ -28,9 +80,8 @@ */

/**
* Scalar multiplication on an matrix.
*
* @param {Array} matrix
* @param {Number} scalar
* @return {Array} updated matrix
* @param {Array} matrix.
* @param {Number} scalar.
* @return {Array} updated matrix.
*/

@@ -43,10 +94,10 @@ matrix.scalar = function (arr, val) {

}
return arr;
};
/**
* Transpose a matrix
* Transpose a matrix.
*
* @param {Array} matrix
* @param {Array} matrix.
* @return {Array} transposed matrix.

@@ -60,14 +111,14 @@ */

for (var j = 0; j < arr.length; j++){
for (var j = 0; j < arr.length; j++) {
result[i][j] = arr[j][i];
}
}
return result;
};
/**
* Create an identity matrix of dimension n x n.
*
* @param {Number} dimension of the identity array to be returned
* @param {Number} dimension of the identity array to be returned.
* @return {Array} n x n identity matrix.

@@ -77,18 +128,19 @@ */

var result = new Array(n);
for (var i = 0 ; i < n ; i++) {
for (var i = 0; i < n ; i++) {
result[i] = new Array(n);
for (var j = 0 ; j < n ; j++) {
for (var j = 0; j < n; j++) {
result[i][j] = (i === j) ? 1 : 0;
}
}
return result;
};
/**
* Evaluate dot product of two vectors. Vectors must be of same length.
*
* @param {Array} vector
* @param {Array} vector
* @return {Array} dot product
* @param {Array} vector.
* @param {Array} vector.
* @return {Array} dot product.
*/

@@ -98,3 +150,3 @@ matrix.dotproduct = function (vectorA, vectorB) {

var result = 0;
for (var i = 0 ; i < vectorA.length ; i++) {
for (var i = 0; i < vectorA.length; i++) {
result += vectorA[i] * vectorB[i];

@@ -108,3 +160,2 @@ }

/**

@@ -116,5 +167,5 @@ * Multiply two matrices. They must abide by standard matching.

*
* @param {Array} matrix
* @param {Array} matrix
* @return {Array} result of multiplied matrices
* @param {Array} matrix.
* @param {Array} matrix.
* @return {Array} result of multiplied matrices.
*/

@@ -125,3 +176,3 @@ matrix.multiply = function (arrA, arrB) {

for (var x = 0 ; x < arrA.length ; x++) {
for (var x = 0; x < arrA.length; x++) {
result[x] = new Array(arrB[0].length);

@@ -132,4 +183,4 @@ }

for (var i = 0 ; i < result.length ; i++) {
for (var j = 0 ; j < result[i].length ; j++) {
for (var i = 0; i < result.length; i++) {
for (var j = 0; j < result[i].length; j++) {
result[i][j] = matrix.dotproduct(arrA[i],arrB_T[j]);

@@ -144,23 +195,327 @@ }

/**
* Evaluate determinate of matrix. Matrix must be of dimension
* 2 or 3.
* Evaluate determinate of matrix. Expect speed
* degradation for matrices over 4x4.
*
* @param {Array} matrix
* @return {Number} determinant
* @param {Array} matrix.
* @return {Number} determinant.
*/
matrix.determinant = function (m) {
if ((m.length === 2) && (m[0].length === 2)) {
var numRow = m.length;
var numCol = m[0].length;
var det = 0;
var row, col;
var diagLeft, diagRight;
if (numRow !== numCol) {
throw new Error("Not a square matrix.")
}
if (numRow === 1) {
return m[0][0];
}
else if (numRow === 2) {
return m[0][0] * m[1][1] - m[0][1] * m[1][0];
} else if ((m.length === 3) && (m[0].length === 3)) {
return m[0][0] * m[1][1] * m[2][2] +
m[0][1] * m[1][2] * m[2][0] +
m[0][2] * m[1][0] * m[2][1] -
m[0][2] * m[1][1] * m[2][0] -
m[0][1] * m[1][0] * m[2][2] -
m[0][0] * m[1][2] * m[2][1];
}
for (col = 0; col < numCol; col++) {
diagLeft = m[0][col];
diagRight = m[0][col];
for( row=1; row < numRow; row++ ) {
diagRight *= m[row][(((col + row) % numCol) + numCol) % numCol];
diagLeft *= m[row][(((col - row) % numCol) + numCol) % numCol];
}
det += diagRight - diagLeft;
}
return det;
};
/**
* Returns a LUP decomposition of the given matrix such that:
*
* A*P = L*U
*
* Where
* A is the input matrix
* P is a pivot matrix
* L is a lower triangular matrix
* U is a upper triangular matrix
*
* This method returns an array of three matrices such that:
*
* matrix.luDecomposition(array) = [L, U, P]
*
* @param {Array} arr
* @return {Array} array of matrices [L, U, P]
*/
matrix.lupDecomposition = function(arr) {
if (!matrix.isSquare(arr)) {
throw new Error("Matrix must be square.");
}
var size = arr.length;
var LU = matrix.deepCopy(arr);
var P = matrix.transpose(matrix.identity(size));
var currentRow;
var currentColumn = new Array(size);
this.getL = function(a) {
var m = a[0].length;
var L = matrix.identity(m);
for (var i = 0; i < m; i++) {
for (var j = 0; j < m; j++) {
if (i > j) {
L[i][j] = a[i][j];
}
}
}
return L;
};
this.getU = function(a) {
var m = a[0].length;
var U = matrix.identity(m);
for (var i = 0; i < m; i++) {
for (var j = 0; j < m; j++) {
if (i <= j) {
U[i][j] = a[i][j];
}
}
}
return U;
};
for (var j = 0; j < size; j++) {
var i;
for (i = 0; i < size; i++) {
currentColumn[i] = LU[i][j];
}
for (i = 0; i < size; i++) {
currentRow = LU[i];
var minIndex = Math.min(i,j);
var s = 0;
for (var k = 0; k < minIndex; k++) {
s += currentRow[k]*currentColumn[k];
}
currentRow[j] = currentColumn[i] -= s;
}
//Find pivot
var pivot = j;
for (i = j + 1; i < size; i++) {
if (Math.abs(currentColumn[i]) > Math.abs(currentColumn[pivot])) {
pivot = i;
}
}
if (pivot != j) {
LU = matrix.rowSwitch(LU, pivot, j);
P = matrix.rowSwitch(P, pivot, j);
}
if (j < size && LU[j][j] !== 0) {
for (i = j + 1; i < size; i++) {
LU[i][j] /= LU[j][j];
}
}
}
return [this.getL(LU), this.getU(LU), P];
};
/**
* Rotate a two dimensional vector by degree.
*
* @param {Array} point.
* @param {Number} degree.
* @param {String} direction - clockwise or counterclockwise.
* @return {Array} vector.
*/
matrix.rotate = function (point, degree, direction) {
if (point.length === 2) {
var negate = direction === 'clockwise' ? -1 : 1;
var radians = degree * (Math.PI / 180);
var transformation = [
[Math.cos(radians), -1 * negate * Math.sin(radians)],
[negate * Math.sin(radians), Math.cos(radians)]
];
return matrix.multiply(transformation, point);
} else {
throw new Error('Matrix must be dimension 2 x 2 or 3 x 3');
throw new Error('Only two dimensional operations are supported at this time');
}
};
/**
* Scale a two dimensional vector by scale factor x and scale factor y.
*
* @param {Array} point.
* @param {Number} sx.
* @param {Number} sy.
* @return {Array} vector.
*/
matrix.scale = function (point, sx, sy) {
if (point.length === 2) {
var transformation = [
[sx, 0],
[0, sy]
];
return matrix.multiply(transformation, point);
} else {
throw new Error('Only two dimensional operations are supported at this time');
}
};
/**
* Shear a two dimensional vector by shear factor k.
*
* @param {Array} point.
* @param {Number} k.
* @param {String} direction - xaxis or yaxis.
* @return {Array} vector.
*/
matrix.shear = function (point, k, direction) {
if (point.length === 2) {
var xplaceholder = direction === 'xaxis' ? k : 0;
var yplaceholder = direction === 'yaxis' ? k : 0;
var transformation = [
[1, xplaceholder],
[yplaceholder, 1]
];
return matrix.multiply(transformation, point);
} else {
throw new Error('Only two dimensional operations are supported at this time');
}
};
/**
* Perform an affine transformation on the given vector.
*
* @param {Array} point.
* @param {Number} tx.
* @param {Number} ty.
* @return {Array} vector.
*/
matrix.affine = function (point, tx, ty) {
if (point.length === 2) {
var transformation = [
[1, 0, tx],
[0, 1, ty],
[0, 0, 1 ]
];
var newpoint = [
[point[0][0]],
[point[1][0]],
[1]
];
var transformed = matrix.multiply(transformation, newpoint);
return [
[transformed[0][0]],
[transformed[1][0]]
];
} else {
throw new Error('Only two dimensional operations are supported at this time');
}
};
/**
* Scales a row of a matrix by a factor and returns the updated matrix.
* Used in row reduction functions.
*
* @param {Array} matrix.
* @param {Number} row.
* @param {Number} scale.
*/
matrix.rowScale = function (m, row, scale) {
var result = new Array(m.length);
for (var i = 0; i < m.length; i++) {
result[i] = new Array(m[i].length);
for (var j = 0; j < m[i].length; j++) {
if (i === row) {
result[i][j] = scale * m[i][j];
} else {
result[i][j] = m[i][j];
}
}
}
return result;
};
/**
* Swaps two rows of a matrix and returns the updated matrix.
* Used in row reduction functions.
*
* @param {Array} matrix.
* @param {Number} row1.
* @param {Number} row2.
*/
matrix.rowSwitch = function (m, row1, row2) {
var result = new Array(m.length);
for (var i = 0; i < m.length; i++) {
result[i] = new Array(m[i].length);
for (var j = 0; j < m[i].length; j++) {
if (i === row1) {
result[i][j] = m[row2][j];
} else if (i === row2) {
result[i][j] = m[row1][j];
} else {
result[i][j] = m[i][j];
}
}
}
return result;
};
/**
* Adds a multiple of one row to another row
* in a matrix and returns the updated matrix.
* Used in row reduction functions.
*
* @param {Array} matrix.
* @param {Number} row1.
* @param {Number} row2.
*/
matrix.rowAddMultiple = function (m, from, to, scale){
var result = new Array(m.length);
for (var i = 0; i < m.length; i++) {
result[i] = new Array(m[i].length);
for (var j = 0; j < m[i].length; j++) {
if (i === to) {
result[to][j] = m[to][j] + scale * m[from][j];
} else {
result[i][j] = m[i][j];
}
}
}
return result;
};

@@ -0,1 +1,21 @@

/**
* prime.js
* http://github.com/sjkaliski/numbers.js
*
* Copyright 2012 Stephen Kaliski
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var basic = require('./basic');

@@ -7,3 +27,3 @@ var prime = exports;

*
* @param {Number} number to evaluate
* @param {Number} number to evaluate.
* @return {Boolean} return true if value is prime. false otherwise.

@@ -15,50 +35,114 @@ */

else if (val !== undefined) {
var start = 2;
var result = true;
while (start < val) {
var start = 1;
var valSqrt = Math.ceil(Math.sqrt(val));
while (++start <= valSqrt) {
if (val % start === 0) {
result = false;
break;
} else {
start++;
return false;
}
}
return result;
return true;
}
};
/**
* Returns the prime factors of a number.
* More info (http://bateru.com/news/2012/05/code-of-the-day-javascript-prime-factors-of-a-number/)
* Taken from Ratio.js
*
* @param {Number} num
* @return {Array} an array of numbers
* @example prime.factorization(20).join(',') === "2,2,5"
**/
prime.factorization = function (num) {
num = Math.floor(num);
var root;
var factors = [];
var x;
var sqrt = Math.sqrt;
var doLoop = 1 < num && isFinite(num);
while (doLoop) {
root = sqrt(num);
x = 2;
if (num % x) {
x = 3;
while ((num % x) && ((x += 2) < root)) {}
}
x = (root < x) ? num : x;
factors.push(x);
doLoop = (x !== num);
num /= x;
}
// TODO: The maximum call stack size exceeds on this call. Either resolve this
// or abolish the call.
return factors;
};
/**
* Using trial method, evaluate the prime factorization of a value.
* Determine if a number is prime in Polynomial time, using a randomized algorithm.
* http://en.wikipedia.org/wiki/Miller-Rabin_primality_test
*
* @param {Number} number to evaluate
* @return {Array} array of prime factors for value
* @param {Number} number to Evaluate.
* @param {Number} number to Determine accuracy rate (number of trials) default value = 20.
* @return {Boolean} return true if value is prime. false otherwise.
*/
// prime.factorization = function (num) {
// if (num === 1) return [1];
// var primes = [],
// result = [];
// loadPrimes(num, function(p) {
// trial(num);
// });
prime.millerRabin = function(n, k) {
if (arguments.length === 1) k = 20;
if (n === 2) return true;
if (!basic.isInt(n) || n <= 1 || n % 2 === 0) return false;
// function loadPrimes (n, callback) {
// for (var i = 0 ; i < n ; i++) {
// if (prime.simple(i)) primes.push(i);
// }
var s = 0;
var d = n - 1;
// callback(primes);
// }
while (true) {
var dm = basic.divMod(d, 2);
var quotient = dm[0];
var remainder = dm[1];
// function trial (n) {
// var quant = Math.floor(Math.random() * primes.length),
// temp = basic.random(primes, quant);
// if (basic.product(temp) === num) {
// return temp;
// } else {
// trial(n);
// }
// }
// };
if (remainder === 1) break;
s += 1;
d = quotient;
}
var tryComposite = function (a) {
if (basic.powerMod(a, d, n) === 1) return false;
for (var i = 0; i < s; i ++) {
if (basic.powerMod(a, Math.pow(2, i) * d, n) === n - 1) return false;
}
return true;
}
for (var i = 0; i < k; i++) {
var a = 2 + Math.floor(Math.random() * (n - 2 - 2));
if (tryComposite(a)) return false;
}
return true;
};
/**
* Return a list of prime numbers from 1...n, inclusive.
*
* @param {Number} upper limit of test n.
* @return {Array} list of values that are prime up to n.
*/
prime.sieve = function (n) {
if (n < 2) return [];
var result = [2];
for (var i = 3; i <= n; i++) {
var notMultiple = false;
for (var j in result) {
notMultiple = notMultiple || (0 === i % result[j]);
}
if (!notMultiple) {
result.push(i);
}
}
return result;
};

@@ -0,1 +1,21 @@

/**
* statistic.js
* http://github.com/sjkaliski/numbers.js
*
* Copyright 2012 Stephen Kaliski
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var basic = require('./basic');

@@ -7,76 +27,111 @@ var statistic = exports;

*
* @param {Array} set of values
* @return {Number} mean value
* @param {Array} set of values.
* @return {Number} mean value.
*/
statistic.mean = function (arr) {
var count = arr.length;
var sum = basic.addition(arr);
var sum = basic.sum(arr);
return sum / count;
};
/**
* Calculate the median value of a set of numbers in array.
*
* @param {Array} set of values
* @return {Number} median value
* @param {Array} set of values.
* @return {Number} median value.
*/
statistic.median = function (arr) {
var count = arr.length;
var middle;
if (count % 2 === 0) {
return (arr[count/2] + arr[(count/2 - 1)])/2;
} else {
return arr[Math.floor(count / 2)];
}
return statistic.quantile(arr, 1, 2);
};
/**
* Calculate the mode value of a set of numbers in array.
*
* @param {Array} set of values
* @return {Number} mode value
* @param {Array} set of values.
* @return {Number} mode value.
*/
statistic.mode = function (arr) {
//sort array
var maxIndex = 0, maxOccurence = 0, tempIndex = 0, tempOccurence = 0;
arr = arr.sort();
while (tempIndex < arr.length) {
for (var j = tempIndex; j < arr.length; j++) {
if (arr[j] == arr[tempIndex]) {
tempOccurence++;
} else {
break;
var counts = {};
for (var i = 0, n = arr.length; i < n; i++) {
if (counts[arr[i]] === undefined) {
counts[arr[i]] = 0;
} else {
counts[arr[i]]++;
}
}
var highest;
for (var number in counts) {
if (counts.hasOwnProperty(number)) {
if (highest === undefined || counts[number] > counts[highest]) {
highest = number;
}
}
if (tempOccurence > maxOccurence) {
maxOccurence = tempOccurence;
maxIndex = tempIndex;
}
tempIndex = j;
tempOccurence = 0;
}
return arr[maxIndex];
return Number(highest);
};
/**
* Calculate the kth q-quantile of a set of numbers in an array.
* As per http://en.wikipedia.org/wiki/Quantile#Quantiles_of_a_population
* Ex: Median is 1st 2-quantile
* Ex: Upper quartile is 3rd 4-quantile
*
* @param {Array} set of values.
* @param {Number} index of quantile.
* @param {Number} number of quantiles.
* @return {Number} kth q-quantile of values.
*/
statistic.quantile = function (arr, k, q) {
var sorted, count, index;
if (k === 0) return Math.min.apply(null, arr);
if (k === q) return Math.max.apply(null, arr);
sorted = arr.slice(0);
sorted.sort(function (a, b) { return a - b; });
count = sorted.length;
index = count * k / q;
if (index % 1 === 0) return 0.5 * sorted[index - 1] + 0.5 * sorted[index];
return sorted[Math.floor(index)];
};
/**
* Return a set of summary statistics provided an array.
*
* @return {Object} summary statistics.
*/
statistic.report = function(array) {
return {
mean: statistic.mean(array),
firstQuartile: statistic.quantile(array, 1, 4),
median: statistic.median(array),
thirdQuartile: statistic.quantile(array, 3, 4),
standardDev: statistic.standardDev(array)
}
};
/**
* Return a random sample of values over a set of bounds with
* a specified quantity.
*
* @param {Number} lower bound
* @param {Number} upper bound
* @param {Number} quantity of elements in random sample
* @return {Array} random sample
* @param {Number} lower bound.
* @param {Number} upper bound.
* @param {Number} quantity of elements in random sample.
* @return {Array} random sample.
*/
statistic.randomSample = function (lower, upper, n) {
var sample = [];
var temp = 0;
for (var i = 0 ; i < n ; i++) {
temp = Math.random() * upper;
if (temp > lower)
sample[i] = temp;
while (sample.length < n) {
var temp = Math.random() * upper;
if (lower <= temp <= upper) {
sample.push(temp)
}
}

@@ -87,8 +142,7 @@

/**
* Evaluate the standard deviation for a set of values.
*
* @param {Array} set of values
* @return {Number} standard deviation
* @param {Array} set of values.
* @return {Number} standard deviation.
*/

@@ -104,24 +158,128 @@ statistic.standardDev = function (arr) {

return Math.sqrt((1 / count) * basic.addition(squaredArr));
return Math.sqrt((1 / count) * basic.sum(squaredArr));
};
/**
* Evaluate the correlation amongst a set of values.
*
* @param {Array} set of values
* @return {Number} correlation
* @param {Array} set of values.
* @return {Number} correlation.
*/
statistic.correlation = function (arrX, arrY) {
if (arrX.length == arrY.length) {
var numerator = 0;
var denominator = (arrX.length) * (statistic.standardDev(arrX)) * (statistic.standardDev(arrY));
var xMean = statistic.mean(arrX);
var yMean = statistic.mean(arrY);
var covarXY = statistic.covariance(arrX, arrY);
var stdDevX = statistic.standardDev(arrX);
var stdDevY = statistic.standardDev(arrY);
for (var i = 0 ; i < arrX.length ; i++) {
numerator += (arrX[i] - xMean) * (arrY[i] - yMean);
return covarXY / (stdDevX * stdDevY);
} else {
throw new Error('Array mismatch');
}
};
/**
* Calculate the Coefficient of Determination of a dataset and regression line.
*
* @param {Array} Source data.
* @param {Array} Regression data.
* @return {Number} A number between 0 and 1.0 that represents how well the regression line fits the data.
*/
statistic.rSquared = function (source, regression) {
var residualSumOfSquares = basic.sum(source.map(function (d,i) {
return basic.square(d - regression[i]);
}));
var totalSumOfSquares = basic.sum(source.map(function (d) {
return basic.square(d - statistic.mean(source));
}));
return 1 - (residualSumOfSquares / totalSumOfSquares);
};
/**
* Create a function to calculate the exponential regression of a dataset.
*
* @param {Array} set of values.
* @return {Function} function to accept X values and return corresponding regression Y values.
*/
statistic.exponentialRegression = function (arrY) {
var n = arrY.length;
var arrX = basic.range(1,n);
var xSum = basic.sum(arrX);
var ySum = basic.sum(arrY);
var yMean = statistic.mean(arrY);
var yLog = arrY.map(function (d) { return Math.log(d); });
var xSquared = arrX.map(function (d) { return d * d; });
var xSquaredSum = basic.sum(xSquared);
var yLogSum = basic.sum(yLog);
var xyLog = arrX.map(function (d, i) { return d * yLog[i]; });
var xyLogSum = basic.sum(xyLog);
var a = (yLogSum * xSquaredSum - xSum * xyLogSum) / (n * xSquaredSum - (xSum * xSum));
var b = (n * xyLogSum - xSum * yLogSum) / (n * xSquaredSum - (xSum * xSum));
var fn = function(x) {
if (typeof x === 'number') {
return Math.exp(a) * Math.exp(b * x);
} else {
return x.map(function (d) {
return Math.exp(a) * Math.exp(b * d);
});
}
};
return numerator / denominator;
fn.rSquared = statistic.rSquared(arrY, arrX.map(fn));
return fn;
};
/**
* Create a function to calculate the linear regression of a dataset.
*
* @param {Array} X array.
* @param {Array} Y array.
* @return {Function} A function which given X or array of X values will return Y.
*/
statistic.linearRegression = function (arrX, arrY) {
var n = arrX.length;
var xSum = basic.sum(arrX);
var ySum = basic.sum(arrY);
var xySum = basic.sum(arrX.map(function (d, i) { return d * arrY[i]; }));
var xSquaredSum = basic.sum(arrX.map(function (d) { return d * d; }));
var xMean = statistic.mean(arrX);
var yMean = statistic.mean(arrY);
var b = (xySum - 1 / n * xSum * ySum) / (xSquaredSum - 1 / n * (xSum * xSum));
var a = yMean - b * xMean;
return function(x) {
if (typeof x === 'number') {
return a + b * x;
} else {
return x.map(function (d) {
return a + b * d;
});
}
}
};
/**
* Evaluate the covariance amongst 2 sets.
*
* @param {Array} set 1 of values.
* @param {Array} set 2 of values.
* @return {Number} covariance.
*/
statistic.covariance = function (set1, set2) {
if (set1.length == set2.length) {
var n = set1.length;
var total = 0;
var sum1 = basic.sum(set1);
var sum2 = basic.sum(set2);
for (var i = 0; i < n; i++) {
total += set1[i] * set2[i];
}
return (total - sum1 * sum2 / n) / n;
} else {

@@ -128,0 +286,0 @@ throw new Error('Array mismatch');

@@ -5,3 +5,3 @@ {

"description": "Advanced Mathematics Library for JavaScript",
"version": "0.0.2",
"version": "0.4.0",
"homepage": "https://github.com/sjkaliski/numbers.js",

@@ -26,8 +26,12 @@ "repository": {

],
"dependencies": {
"mocha": "~1.5.0"
"devDependencies": {
"mocha": "~1.5.0",
"browserify": "~1.16.6",
"uglify-js": "~2.2.2",
"jshint": "~0.9.1"
},
"scripts": {
"test": "make test"
"test": "make test",
"build": "make build"
}
}

@@ -0,1 +1,2 @@

# numbers.js [![Build Status](https://travis-ci.org/sjkaliski/numbers.js.png)](https://travis-ci.org/sjkaliski/numbers.js)
Numbers - an advanced mathematics toolkit for JavaScript and Node.js

@@ -32,20 +33,27 @@ developed by Steve Kaliski, [@sjkaliski](http://twitter.com/sjkaliski)

Use riemann integrals (with 200 subdivisions)
```javascript
var numbers = require('numbers');
var func = function(x) {
return Math.sin(x);
}
numbers.calculus.riemann(func, -2, 4, 200);
numbers.calculus.riemann(Math.sin, -2, 4, 200);
```
Or adaptive simpson quadrature (with epsilon .0001)
Or use adaptive simpson quadrature (with epsilon .0001)
```javascript
numbers.calculus.adaptiveSimpson(func, -2, 4, .0001);
numbers.calculus.adaptiveSimpson(Math.sin, -2, 4, .0001);
```
Say we wanted to run some matrix calculations:
User-defined functions can be used too:
```
var myFunc = function(x) {
return 2*Math.pow(x,2) + 1;
}
numbers.calculus.riemann(myFunc, -2, 4, 200);
numbers.calculus.adaptiveSimpson(myFunc, -2, 4, .0001);
```
Now say we wanted to run some matrix calculations:
We can add two matrices

@@ -66,3 +74,3 @@

Numeric.ly also includes some basic prime number analysis. We can check if a number is prime:
Numbers also includes some basic prime number analysis. We can check if a number is prime:

@@ -97,5 +105,33 @@ ```javascript

## Contributors
## Build
To update the public JavaScript, run
```
make build
```
This will compile the entire library into a single file accessible at public/numbers.js. It will also minify the file into public/numbers.min.js.
## Core Team
* Steve Kaliski - [@sjkaliski](http://twitter.com/sjkaliski)
* David Byrd - [@davidbyrd11](http://twitter.com/davidbyrd11)
* Ethan Resnick - [@studip101](http://twitter.com/studip101)
* Ethan Resnick - [@studip101](http://twitter.com/studip101)
## Contributors
In no particular order:
* [Ethan aka `altercation`](https://github.com/altercation)
* [Hrishikesh Paranjape aka `hrishikeshparanjape`](https://github.com/hrishikeshparanjape)
* [Greg Leppert aka `leppert`](https://github.com/leppert)
* [Lars-Magnus Skog aka `ralphtheninja`](https://github.com/ralphtheninja)
* [Tim Wood aka `codearachnid`](https://github.com/codearachnid)
* [Miles McCrocklin aka `milroc`](https://github.com/milroc)
* [Nate Kohari aka `nkohari`](https://github.com/nkohari)
* [Eric LaForce aka `elaforc`](https://github.com/elaforc)
* [Kartik Talwar aka `KartikTalwar`](https://github.com/KartikTalwar)
* [btmills aka `btmills`](https://github.com/btmills)
* [swair shah aka `swairshah`](https://github.com/swairshah)
* [Jason Hutchinson aka `Zikes`](https://github.com/Zikes)
* [Philip I. Thomas aka `philipithomas`](https://github.com/philipithomas)
* [Brandon Benvie aka `Benvie`](https://github.com/Benvie)
* [Larry Battle aka `LarryBattle`](https://github.com/LarryBattle)

@@ -9,23 +9,94 @@ var assert = require('assert');

// numbers.addition
test('addition should return the sum of items in an array', function (done) {
assert.equal(6, basic.addition([0,1,2,3]));
assert.equal(0, basic.addition([0,-3,5,-2]));
// basic.sum
test('sum should return the sum of items in an array', function (done) {
assert.equal(6, basic.sum([0, 1, 2, 3]));
assert.equal(0, basic.sum([0, -3, 5, -2]));
done();
});
// numbers.subtraction
test('sum should throw an exception when given anything but an array', function (done) {
assert.throws(
function() {
basic.sum(1);
},
/Input must be of type Array/
);
done();
});
test('sum should throw an exception when given anything objects other than numbers', function (done) {
assert.throws(
function() {
basic.sum([1, 2, "error"]);
},
/All elements in array must be numbers/
);
done();
});
// basic.substraction
test('subtraction should return the difference of items in an array', function (done) {
assert.equal(0, basic.subtraction([0,1,2,3]));
assert.equal(0, basic.subtraction([0, 1, 2, 3]));
done();
});
// numbers.product
test('subtraction should throw an exception when given anything but an array', function (done) {
assert.throws(
function() {
basic.subtraction(1);
},
/Input must be of type Array/
);
done();
});
test('subtraction should throw an exception when given anything objects other than numbers', function (done) {
assert.throws(
function() {
basic.subtraction(["test", 1, 1, 2]);
},
/All elements in array must be numbers/
);
done();
});
// basic.product
test('product should return the product of items in an array', function (done) {
assert.equal(24, basic.product([1,2,3,4]));
assert.equal(-6, basic.product([-3,2]));
assert.equal(24, basic.product([1, 2, 3, 4]));
assert.equal(-6, basic.product([-3, 2]));
done();
});
// numbers.factorial
test('product should throw an exception when given anything but an array', function (done) {
assert.throws(
function() {
basic.product(1);
},
/Input must be of type Array/
);
done();
});
test('product should throw an exception when given anything objects other than numbers', function (done) {
assert.throws(
function() {
basic.product([1, 2, "error"]);
},
/All elements in array must be numbers/
);
done();
});
test('square should return the square of a number', function(done) {
assert.equal(16, basic.square(4));
done();
});
// basic.binomial
test('binomial should return the binomial coefficient (n choose k) of two numbers', function(done) {
assert.equal(10, basic.binomial(5, 3));
done();
});
// basic.factorial
test('factorial should return the product of n * (n - 1) * (n - 2) * ... * 1', function (done) {

@@ -37,3 +108,3 @@ assert.equal(24, basic.factorial(4));

// numbers.gcd
// basic.gcd
test('gcd should return the greatest common denominator of two integers', function (done) {

@@ -45,3 +116,3 @@ assert.equal(6, basic.gcd(1254, 5298));

// numbers.lcm
// basic.lcm
test('lcm should return the least common multiple of two integers', function (done) {

@@ -51,2 +122,78 @@ assert.equal(240, basic.lcm(12, 80));

});
// basic.max
test('max should return the biggest number in an array', function (done) {
assert.equal(42, basic.max([1,2,3,42]));
done();
});
// basic.min
test('min should return the smallest number in an array', function (done) {
assert.equal(1, basic.min([2,1,3,42]));
done();
});
// basic.range
test('range should return an appropriate range for the given start, stop, and step parameters', function (done) {
assert.deepEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10],basic.range(1, 10));
assert.deepEqual([10, 9, 8, 7, 6, 5, 4, 3, 2, 1],basic.range(10, 1));
assert.deepEqual([1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5],basic.range(1, 5, 0.5));
assert.deepEqual([5, 4.5, 4, 3.5, 3, 2.5, 2, 1.5, 1],basic.range(5, 1, 0.5));
done();
});
// basic.isInt
test('isInt checks for an integer', function (done) {
assert.equal(false, basic.isInt(2.32));
assert.equal(false, basic.isInt("true"));
assert.equal(true, basic.isInt("2")); //based off impelementation change
assert.equal(true, basic.isInt(2));
done();
});
// basic.divMod
test('divMod should return an array of both the division and modulus values of two integers', function (done) {
assert.deepEqual([2, 0], basic.divMod(12, 6));
assert.deepEqual([3, 1], basic.divMod(10, 3));
done();
});
// basic.egcd
test('egcd should return the array [a, x, y] which is the solved linear equation for GCD', function(done) {
assert.deepEqual([5, -3, 5], basic.egcd(65, 40));
assert.deepEqual([5, 5, -3], basic.egcd(40, 65));
assert.deepEqual([21, -16, 27], basic.egcd(1239, 735));
assert.deepEqual([21, 5, -2], basic.egcd(105, 252));
assert.deepEqual([21, -2, 5], basic.egcd(252, 105));
done();
});
// basic.modInverse
test('modInverse will return the modulo m inverse of a', function(done) {
assert.equal(1, basic.modInverse(1, 5));
done();
});
test('modInverse will throw an exception if no modular inverse exists', function(done) {
assert.throws(
function() {
basic.modInverse(65, 40);
},
/No modular inverse exists/
);
done();
});
// basic.powerMod
test('powerMod should return the answer to a^b mod m', function (done) {
assert.equal(1, basic.powerMod(1, -1, 5));
assert.equal(1, basic.powerMod(2, 10, 3));
assert.equal(16, basic.powerMod(2, Math.pow(10, 9), 18));
assert.equal(6, basic.powerMod(6, 0.5, 10));
assert.equal(445, basic.powerMod(4, 13, 497));
done();
});
});

@@ -10,3 +10,3 @@ var assert = require('assert');

test('pointDiff should return the derivative at a point, provided function', function(done) {
var func = function(x) {
var func = function (x) {
return 2 * x + 2;

@@ -22,7 +22,7 @@ };

test('riemann should return an estimated definite integral of a function', function(done) {
var func = function(x) {
var func = function (x) {
return 2 * Math.pow(x, 2);
};
var res = calculus.riemann(func, 0, 100, 10);
var res = calculus.Riemann(func, 0, 100, 10);

@@ -34,3 +34,3 @@ assert.equal(570000, res);

test('adaptive simpson should return an estimated definite integral of a function', function(done) {
var func = function(x) {
var func = function (x) {
return 2 * Math.pow(x, 2);

@@ -46,3 +46,3 @@ };

test('limit should return the limit of a function at a given point from left, middle, or right', function(done) {
var func = function(x) {
var func = function (x) {
return Math.pow(x, 2) * Math.sin(2 * x);

@@ -57,2 +57,17 @@ };

});
test('Stirling approximation gamma should return correct values', function (done) {
assert.equal(true, numbers.EPSILON > 5.69718714897717 - calculus.StirlingGamma(0.1));
assert.equal(true, numbers.EPSILON > 3.3259984240223925 - calculus.StirlingGamma(0.2));
assert.equal(true, numbers.EPSILON > 2.3625300362696198 - calculus.StirlingGamma(0.3));
assert.equal(true, numbers.EPSILON > 0.8426782594483921 - calculus.StirlingGamma(1.3));
done();
});
test('Lanczos approximation gamma should return correct values', function (done) {
assert.equal(true, numbers.EPSILON > 9.513507698668736 - calculus.LanczosGamma(0.1));
assert.equal(true, numbers.EPSILON > 4.590843711998803 - calculus.LanczosGamma(0.2));
assert.equal(true, numbers.EPSILON > 2.9915689876875904 - calculus.LanczosGamma(0.3));
assert.equal(true, numbers.EPSILON > 0.8974706963062777 - calculus.LanczosGamma(1.3));
done();
});
});

@@ -9,2 +9,26 @@ var assert = require('assert');

test('should create a deep copy of a matrix', function(done) {
var input = [[1,2],[2,1]];
var copy = matrix.deepCopy(input);
assert.notEqual(input, copy);
assert.throws(
function() {
matrix.deepCopy([1,2])
},
/Input cannot be a vector./
);
done();
});
test('should be able to tell if a matrix is square', function(done) {
assert.equal(matrix.isSquare([[1,2],[3,4]]), true);
assert.equal(matrix.isSquare([[1,2,3],[4,5,6]]), false);
done();
});
test('should return sum of two matrices', function(done) {

@@ -102,3 +126,28 @@ var arrA = [

test('should return product of matrix and a vector', function(done) {
var matrixA = [
[0, 1, 2],
[3, 4, 5]
];
var matrixB = [
[0],
[1],
[2]
];
var res = matrix.multiply(matrixA, matrixB);
assert.deepEqual([[5], [14]], res);
done();
});
test('should return determinant of matrix', function(done) {
var m0 = [
[1]
];
var res0 = matrix.determinant(m0);
assert.equal(1, res0);
var m1 = [

@@ -123,3 +172,240 @@ [2, 3],

});
test('should throw an error for calculating the determinant of a non-square matrix', function(done) {
var m3 = [
[3, -7, 8, 9, -6],
[0, 2, -5, 7, 3],
[0, 0, 1, 5, 0],
[0, 0, 0, -2, 0]
];
assert.throws(function() {
matrix.determinant(m3);
},
/Not a square matrix/
);
done();
});
test('should throw an error if trying to get LU decomposition of non-square matrix', function(done) {
assert.throws(
function() {
matrix.lupDecomposition([[1,2,3],[4,5,6]]);
},
/Matrix must be square./
);
done();
});
test('should return the LU decomposition of a matrix', function(done) {
var inputMatrix = [[1, 0, 0, 2], [2, -2, 0, 5], [1, -2, -2, 3], [5, -3, -5, 2]];
var firstLup = matrix.lupDecomposition(inputMatrix);
assert.deepEqual(matrix.multiply(firstLup[0], firstLup[1]),
matrix.multiply(firstLup[2], inputMatrix));
var secondInputMatrix = [[1, 0, 0, 2], [1, -2, 0, 5], [1, -2, 0, 3], [1, -3, -5, 0]];
var secondLup = matrix.lupDecomposition(secondInputMatrix);
assert.deepEqual(matrix.multiply(secondLup[0], secondLup[1]),
matrix.multiply(secondLup[2], secondInputMatrix));
done();
});
test('should return a new vector that has been rotated by the transformation matrix', function(done) {
var vectorA = [[0], [1]];
var degree = 90;
var res = matrix.rotate(vectorA, degree, 'clockwise');
assert.equal((res[0][0] > (1 - numbers.EPSILON)), true);
assert.equal((res[0][0] < (1 + numbers.EPSILON)), true);
assert.equal((res[1][0] > (0 - numbers.EPSILON)), true);
assert.equal((res[1][0] < (0 + numbers.EPSILON)), true);
done();
});
test('should throw an error if a vector larger than two is given for rotation', function(done) {
var vectorA = [[0], [1], [2]];
var degree = 90;
assert.throws(
function() {
matrix.rotate(vectorA, degree, 'clockwise');
},
/Only two dimensional operations are supported at this time/
);
done();
});
test('should return a new vector that has been scaled by the transformation matrix', function(done) {
var vectorA = [[2], [5]];
var sx = 10;
var sy = 5;
var expected = [ [20], [25] ];
var res = matrix.scale(vectorA, sx, sy);
assert.deepEqual(expected, res);
done();
});
test('should throw an error if a vector larger than two is given for scaling', function(done) {
var vectorA = [[0], [1], [2]];
var sx = 10;
var sy = 5;
assert.throws(
function() {
var res = matrix.scale(vectorA, sx, sy);
},
/Only two dimensional operations are supported at this time/
);
done();
});
test('should return a new vector that has been sheared in the x direction by the transformation matrix', function(done) {
var vectorA = [[2], [5]];
var k = 10;
var direction = "xaxis"
var expected = [ [52], [5] ];
var res = matrix.shear(vectorA, k, direction);
assert.deepEqual(expected, res);
done();
});
test('should return a new vector that has been sheared in the y direction by the transformation matrix', function(done) {
var vectorA = [[2], [5]];
var k = 10;
var direction = "yaxis"
var expected = [ [2], [25] ];
var res = matrix.shear(vectorA, k, direction);
assert.deepEqual(expected, res);
done();
});
test('should throw an error if a vector larger than two is given for shearing', function(done) {
var vectorA = [[0], [1], [2]];
var k = 10;
var direction = "yaxis"
assert.throws(
function() {
var res = matrix.shear(vectorA, k, direction);
},
/Only two dimensional operations are supported at this time/
);
done();
});
test('should return a new vector that has been transformed by the affine transformation matrix', function(done) {
var vectorA = [[2], [5]];
var tx = 10;
var ty = 10;
var expected = [ [12], [15] ];
var res = matrix.affine(vectorA, tx, ty);
assert.deepEqual(expected, res);
done();
});
test('should throw an error if a vector larger than two is given for the affine transform', function(done) {
var vectorA = [[0], [1], [2]];
var tx = 10;
var ty = 10;
assert.throws(
function() {
var res = matrix.affine(vectorA, tx, ty);
},
/Only two dimensional operations are supported at this time/
);
done();
});
test('should return a new matrix that has a scaled row for the rowScale function', function(done) {
var m = [
[0, 1, 2],
[3, -1, 5],
[1, 2, 5]
];
var expected1 = [
[0, 0, 0],
[3, -1, 5],
[1, 2, 5]
];
var res1 = matrix.rowScale(m,0,0);
assert.deepEqual(res1,expected1);
var expected2 = [
[0, 1, 2],
[-6, 2, -10],
[1, 2, 5]
];
var res2 = matrix.rowScale( m , 1 , -2 );
assert.deepEqual( res2 , expected2 );
done();
});
test('should return a new matrix that has rows changed with the rowSwitch function', function(done) {
var m = [
[0, 1, 2],
[3, -1, 5],
[1, 2, 5]
];
var expected1 = [
[3, -1, 5],
[0, 1, 2],
[1, 2, 5]
];
var res1 = matrix.rowSwitch(m,0,1);
assert.deepEqual(res1,expected1);
var res2 = matrix.rowScale(m,1,1);
assert.deepEqual(res2,m);
done();
});
test('should return a new matrix that has a multiple of one row added to another using the rowAddMultiple function', function(done) {
var m = [
[0, 1, 2],
[3, -1, 5],
[1, 2, 5]
];
var expected1 = [
[0, 1, 2],
[3, 1, 9],
[1, 2, 5]
];
var res1 = matrix.rowAddMultiple(m,0,1,2);
assert.deepEqual(res1,expected1);
var res2 = matrix.rowScale(m,1,1,0);
assert.deepEqual(res2,m);
done();
});
});

@@ -6,12 +6,67 @@ var assert = require('assert');

suite('numbers', function() {
var primes = [2, 17, 839, 3733, 999983];
var composites = [1, 4, 18, 25, 838, 3007];
console.log('\n\n\033[34mTesting Prime Number Mathematics\033[0m');
// prime.simple
test('simple should be able to determine if a number is prime or not', function(done) {
for (var i = 0; i < primes.length; i++) {
assert.equal(true, prime.simple(primes[i]), primes[i] + " should be prime");
}
for (i = 0; i < composites.length; i++) {
assert.equal(false, prime.simple(composites[i]), composites[i] + " should not be prime");
}
done();
});
// prime.millerRabin
test('millerRabin should be able to determine if a number is prime or not', function(done) {
for (var i = 0; i < primes.length; i++) {
assert.equal(true, prime.millerRabin(primes[i]), primes[i] + " should be prime");
}
for (i = 0; i < composites.length; i++) {
assert.equal(false, prime.millerRabin(composites[i]), composites[i] + " should not be prime");
}
done();
});
// prime.sieve
test('should be able to determine if a number is prime or not', function(done) {
assert.equal(false, prime.simple(1));
assert.equal(true, prime.simple(2));
assert.equal(true, prime.simple(17));
done()
assert.deepEqual([], prime.sieve(1));
assert.deepEqual([2], prime.sieve(2));
assert.deepEqual([2, 3, 5, 7, 11, 13, 17], prime.sieve(17));
done();
});
//prime.factorization when values < 2
test("factorization should return an empty array for values < 2, infinite or not numeric", function (done) {
var func = prime.factorization;
assert.deepEqual(func(Infinity), []);
assert.deepEqual(func({}), []);
assert.deepEqual(func(null), []);
assert.deepEqual(func(-1), []);
assert.deepEqual(func(0), []);
assert.deepEqual(func(1), []);
done();
});
//prime.factorization when 1 < values < infinity
test("factorization should return the prime factors for x where 1 < x < infinity", function (done) {
var func = prime.factorization;
assert.deepEqual(func(2), [2]);
assert.deepEqual(func(6), [2, 3]);
assert.deepEqual(func(9), [3, 3]);
assert.deepEqual(func("729"), [3, 3, 3, 3, 3, 3]);
assert.deepEqual(func(3333333791), [2347, 1420253]);
assert.deepEqual(func(123456789), [3, 3, 3607, 3803]);
assert.deepEqual(func(9876543210), [2, 3, 3, 5, 17, 17, 379721]);
assert.deepEqual(func("103103103"), [3, 103, 333667]);
done();
});
});
var assert = require('assert');
var numbers = require('../index.js');
var statistic = numbers.statistic;
var basic = numbers.basic;

@@ -11,13 +12,27 @@ suite('numbers', function() {

var res = statistic.mean([0, 1, 2]);
assert.equal(1, res);
assert.equal(1, res);
done();
});
test('median should return middle value in array', function(done) {
var res1 = statistic.median([0, 1, 2]);
test('median should return middle value in array for a sorted array with an odd number of values', function(done) {
var res1 = statistic.median([0, 2, 15]);
assert.equal(2, res1);
done();
});
test('median should return middle value in array for an unsorted array with an odd number of values', function(done) {
var res1 = statistic.median([1, 0, 2]);
assert.equal(1, res1);
done();
});
test('median should return average of two middle values in array for a sorted array with an even number of values', function(done) {
var res2 = statistic.median([0, 1, 2, 3]);
assert.equal(1.5, res2);
done();
});
test('median should return average of two middle values in array for an unsorted array with an even number of values', function(done) {
var res2 = statistic.median([1, 3, 2, 0]);
assert.equal(1.5, res2);
done();

@@ -32,2 +47,28 @@ });

test('quantile should return lowest value in array for 0th q-quantile of an unsorted array', function(done) {
var arr = [5, 2, 4];
var res = statistic.quantile(arr, 0, 1);
assert.equal(2, res);
done();
});
test('quantile should return highest value in array for qth q-quantile of an unsorted array', function(done) {
var arr = [5, 2, 4];
var res = statistic.quantile(arr, 6, 6);
assert.equal(5, res);
done();
});
test('quantile should return average of two values in array for an unsorted array\'s length is a multiple of (k / q)', function(done) {
var res = statistic.quantile([9, 1, 1, 9], 2, 4);
assert.equal(5, res);
done();
});
test('quantile should return value at 0-based index floor(k/q) in array for an unsorted array\'s length is not a multiple of (k/q)', function(done) {
var res = statistic.quantile([3, 6, 7, 8, 8, 9, 10, 13, 15, 16, 20], 1, 4);
assert.equal(7, res);
done();
});
test('randomSample should return an array of random numbers in a certain bound', function(done) {

@@ -56,6 +97,55 @@ var res = statistic.randomSample(5, 100, 5);

assert.equal(0.43413125731182345, res);
assert.equal(0.43413125731182334, res);
done();
});
test('should return a function to calculate the linear regression of a set of points', function (done) {
var arrX = [1,2,3,4,5,7,8,9];
var arrY = [1,2,3,4,5,7,7,9];
var regression_function = statistic.linearRegression(arrX,arrY);
assert.equal(19.07218683651805, regression_function(20));
done();
});
test('should return a function to calculate the exponential regression of an array of numbers', function (done) {
var input = [10,9,8,8,7,7,6,6.5,6.4,6.3,6.2];
var output = [
9.077131929916444, 8.66937771538526, 8.279940244595563, 7.907996710352883,
7.552761266818376, 7.213483369166244, 6.8894461878255076, 6.579965093955639,
6.284386212956255, 6.002085042954625, 5.732465135352174
];
var regression_function = statistic.exponentialRegression(input);
assert.equal(0.8491729985314136, regression_function.rSquared);
assert.deepEqual(output, regression_function(basic.range(1, input.length)));
assert.equal(9.077131929916444, regression_function(1));
assert.equal(4.769782016165231, regression_function(15));
done();
});
test('should return an appropriate Coefficient of Determination for a given dataset and regression', function (done) {
var input = [10,9,8,8,7,7,6,6.5,6.4,6.3,6.2];
var output = [
9.077131929916444, 8.66937771538526, 8.279940244595563, 7.907996710352883,
7.552761266818376, 7.213483369166244, 6.8894461878255076, 6.579965093955639,
6.284386212956255, 6.002085042954625, 5.732465135352174
];
assert.equal(0.8491729985314136, statistic.rSquared(input, output));
done();
});
test('should return covariance between two arrays', function(done) {
var arr1 = [-5, -4, -1, 0, 5, 100];
var arr2 = [-6, 5, 2, 5, 2, 6];
var res = statistic.covariance(arr1, arr2);
assert.equal(66.05555555555556, res);
done();
});
});

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc