From 2aa2f29e2b287799b20e3d99a15aa6a0033b1fbc Mon Sep 17 00:00:00 2001 From: Devan Patel Date: Mon, 27 Apr 2015 12:41:04 -0400 Subject: [PATCH] Adding support for Bell Numbers in Combinatorics Module. --- lib/function/combinatorics/bellNumbers.js | 69 +++++++++++++++++++ lib/math.js | 1 + lib/util/latex.js | 1 + .../combinatorics/bellNumbers.test.js | 37 ++++++++++ 4 files changed, 108 insertions(+) create mode 100644 lib/function/combinatorics/bellNumbers.js create mode 100644 test/function/combinatorics/bellNumbers.test.js diff --git a/lib/function/combinatorics/bellNumbers.js b/lib/function/combinatorics/bellNumbers.js new file mode 100644 index 000000000..3c02f2be8 --- /dev/null +++ b/lib/function/combinatorics/bellNumbers.js @@ -0,0 +1,69 @@ +'use strict'; + +module.exports = function (math) { + var util = require('../../util/index'), + + BigNumber = math.type.BigNumber, + collection = math.collection, + + isNumber = util.number.isNumber, + isInteger = util.number.isInteger; + + /** + * The Bell Numbers count the number of partitions of a set. A partition is a pairwise disjoint subset of S whose union is S. + + * bellNumbers only take integer arguments. + * The following condition must be enforced: n >= 0 + * + * Syntax: + * + * math.bellNumbers(n) + * + * Examples: + * + * math.bellNumbers(4, 3); //returns 10 + * + * + * @param {Number | BigNumber} n Total number of objects in the set + * @return {Number | BigNumber} B(n) + */ + + math.bellNumbers = function bellNumbers (n) { + var result = 0; + var arity = arguments.length; + if (arity != 1) { + throw new math.error.ArgumentsError('bellNumbers', arguments.length, 1); + } + + if (isNumber(n)) { + if (!isInteger(n) || n < 0) { + throw new TypeError('Positive integer value expected in function bellNumbers'); + } + // Sum (k=0, n) S(n,k). + for(var i = 0; i <= n; i++) { + var stirlingS2 = math.stirlingS2(n,i); + result += stirlingS2; + } + return result; + // } else if (n instanceof BigNumber) { + // result = new BigNumber(0); + // for (var i = new BigNumber(1); i.lte(n); i = i.plus(1)) { + // result += (math.stirlingS2(n, i)); + // } + // return result; + // } else{ + throw new math.error.UnsupportedTypeError('bellNumbersg', math['typeof'](n)); + } + }; + + + + /** + * Test whether BigNumber n is a positive integer + * @param {BigNumber} n + * @returns {boolean} isPositiveInteger + */ + var isPositiveInteger = function(n) { + return n.isInteger() && n.gte(0); + }; + }; diff --git a/lib/math.js b/lib/math.js index b1c3f3934..4dc8e7a15 100644 --- a/lib/math.js +++ b/lib/math.js @@ -270,6 +270,7 @@ function create (config) { //functions - combinatorics require('./function/combinatorics/stirlingS2')(math, _config); + require('./function/combinatorics/bellNumbers')(math, _config); // functions - complex require('./function/complex/arg')(math, _config); diff --git a/lib/util/latex.js b/lib/util/latex.js index 98bc967ac..3deac3845 100644 --- a/lib/util/latex.js +++ b/lib/util/latex.js @@ -169,6 +169,7 @@ var functions = { //combinatorics 'stirlingS2': '\\mathrm{S}\\left(%0%,%1%\\right)', + 'bellNumbers': '\\mathrm{B}_{%0%}', //construction 'bignumber': { diff --git a/test/function/combinatorics/bellNumbers.test.js b/test/function/combinatorics/bellNumbers.test.js new file mode 100644 index 000000000..e383e3a0f --- /dev/null +++ b/test/function/combinatorics/bellNumbers.test.js @@ -0,0 +1,37 @@ +var assert = require('assert'), +error = require('../../../lib/error/index'), +math = require('../../../index'), +bellNumbers = math.bellNumbers; + +describe('bellNumbers', function() { + + it('should calculate the number of partitions of a set', function() { + assert.equal(bellNumbers(3), 5); + assert.equal(bellNumbers(0), 1); + assert.equal(bellNumbers(8), 4140); + }); + + // it('should calculate the bellNumbers of n items with BigNumbers', function(){ + // assert.deepEqual(bellNumbers(math.bignumber(2)), math.bignumber(2)); + // // assert.deepEqual(bellNumbers(math.bignumber(10), math.bignumber(4)),math.bignumber(34105)); + // // assert.deepEqual(bellNumbers(math.bignumber(8), math.bignumber(6)),math.bignumber(266)); + // }); + + it('should not work with non-integer and negative input', function() { + assert.throws(function() {bellNumbers(0.5)}, TypeError); + assert.throws(function() {bellNumbers(-1)}, TypeError); + // assert.throws(function() {bellNumbers(math.bignumber(-3))}, TypeError); + // assert.throws(function() {bellNumbers(math.bignumber(3.5))}, TypeError); + }); + + it('should not work with the wrong number or type of arguments', function() { + assert.throws(function() {bellNumbers(5, 3, 2)}); + assert.throws(function() {bellNumbers(true, "hello world")}); + }); + + it('should LaTeX bellNumbers', function () { + var expression = math.parse('bellNumbers(3)'); + assert.equal(expression.toTex(), '\\mathrm{B}_{3}'); + }); + +});