mathjs/test/unit-tests/function/probability/combinationsWithRep.test.js
Waseem Yusuf c0e87c4b71 Make combinationsWithRep.js more efficient (#1602)
* Implemented the `multicombinations` function

* Write unit tests for `multicombinations` function

* Integrate the `multicombinations` function throughout codebase

1. Include multicombinations factory function in factoriesAny.js and factoriesNumber.js
2. Write embedded docs for multicombinations
3. Added latex support
4. Refer to multicombinations in the "see also"-section of related functions

* Change name from `multichoose` to `combinationsWithRep`

* Update combinationsWithRep.js

Instead of always cancelling `n-1 factorial` from the denominator and ignoring `k factorial`, added a conditional to cancel the the larger of the two, therefore further reducing redundant calculations.

* Revert "Update combinationsWithRep.js"

This reverts commit efef6d3bd4c381aa12f00869a7624a622268805c.

* Update combinationsWithRep.js

Instead of always cancelling `n-1 factorial` from the denominator and ignoring `k factorial`, added a conditional to cancel the the larger of the two, therefore further reducing redundant calculations.

* Add one more test for the case: k > n-1

* Refactor single for-loop into two separate ones
2019-08-28 15:10:24 +02:00

46 lines
2.4 KiB
JavaScript

import assert from 'assert'
import math from '../../../../src/bundleAny'
const combinationsWithRep = math.combinationsWithRep
describe('combinations', function () {
it('should calculate the combinations of a number taking k at a time', function () {
assert.strictEqual(combinationsWithRep(7, 5), 462)
assert.strictEqual(combinationsWithRep(3, 10), 66)
assert.strictEqual(combinationsWithRep(8, 33), 18643560)
assert.strictEqual(combinationsWithRep(63, 7), 1078897248)
assert.strictEqual(combinationsWithRep(25, 6), 593775)
})
it('should calculate the combinations of n items taken k at a time with BigNumbers', function () {
assert.deepStrictEqual(combinationsWithRep(math.bignumber(7), math.bignumber(5)), math.bignumber(462))
assert.deepStrictEqual(combinationsWithRep(math.bignumber(3), math.bignumber(10)), math.bignumber(66))
assert.deepStrictEqual(combinationsWithRep(math.bignumber(8), math.bignumber(33)), math.bignumber(18643560))
assert.deepStrictEqual(combinationsWithRep(math.bignumber(63), math.bignumber(7)), math.bignumber(1078897248))
assert.deepStrictEqual(combinationsWithRep(math.bignumber(25), math.bignumber(6)), math.bignumber(593775))
})
it('should not work with non-integer and negative input', function () {
assert.throws(function () { combinationsWithRep(-12, 6) }, TypeError)
assert.throws(function () { combinationsWithRep(12, -6) }, TypeError)
assert.throws(function () { combinationsWithRep(0.5, 3) }, TypeError)
assert.throws(function () { combinationsWithRep(4, 0.5) }, TypeError)
assert.throws(function () { combinationsWithRep(math.bignumber(3.5), math.bignumber(-3)) }, TypeError)
assert.throws(function () { combinationsWithRep(math.bignumber(3.5), 1 / 3) }, TypeError)
})
it('should fail loudly when k is larger than n + k - 1', function () {
assert.throws(function () { combinationsWithRep(0, 0) }, TypeError)
assert.throws(function () { combinationsWithRep(0, 3) }, TypeError)
})
it('should not work with the wrong number or type of arguments', function () {
assert.throws(function () { combinationsWithRep(5, 3, 2) })
assert.throws(function () { combinationsWithRep(true, 'hello world') })
})
it('should LaTeX combinations', function () {
const expression = math.parse('combinationsWithRep(3, 2)')
assert.strictEqual(expression.toTex(), '\\left(\\!\\!{\\binom{3}{2}}\\!\\!\\right)')
})
})