diff --git a/src/threshold/freedmanDiaconis.js b/src/threshold/freedmanDiaconis.js index b1e62472..c78cff40 100644 --- a/src/threshold/freedmanDiaconis.js +++ b/src/threshold/freedmanDiaconis.js @@ -2,5 +2,6 @@ import count from "../count.js"; import quantile from "../quantile.js"; export default function thresholdFreedmanDiaconis(values, min, max) { - return Math.ceil((max - min) / (2 * (quantile(values, 0.75) - quantile(values, 0.25)) * Math.pow(count(values), -1 / 3))); + const c = count(values), d = quantile(values, 0.75) - quantile(values, 0.25); + return c && d ? Math.ceil((max - min) / (2 * d * Math.pow(c, -1 / 3))) : 1; } diff --git a/src/threshold/scott.js b/src/threshold/scott.js index 1f1c35a1..2541d2dc 100644 --- a/src/threshold/scott.js +++ b/src/threshold/scott.js @@ -2,5 +2,6 @@ import count from "../count.js"; import deviation from "../deviation.js"; export default function thresholdScott(values, min, max) { - return Math.ceil((max - min) * Math.cbrt(count(values)) / (3.49 * deviation(values))); + const c = count(values), d = deviation(values); + return c && d ? Math.ceil((max - min) * Math.cbrt(c) / (3.49 * d)) : 1; } diff --git a/src/threshold/sturges.js b/src/threshold/sturges.js index 93aa4d74..3370968e 100644 --- a/src/threshold/sturges.js +++ b/src/threshold/sturges.js @@ -1,5 +1,5 @@ import count from "../count.js"; export default function thresholdSturges(values) { - return Math.ceil(Math.log(count(values)) / Math.LN2) + 1; + return Math.max(1, Math.ceil(Math.log(count(values)) / Math.LN2) + 1); } diff --git a/test/deviation-test.js b/test/deviation-test.js index 3daae413..3be39522 100644 --- a/test/deviation-test.js +++ b/test/deviation-test.js @@ -2,6 +2,7 @@ import assert from "assert"; import {deviation} from "../src/index.js"; it("deviation(array) returns the standard deviation of the specified numbers", () => { + assert.strictEqual(deviation([1, 1, 1, 1, 1]), 0); assert.strictEqual(deviation([5, 1, 2, 3, 4]), Math.sqrt(2.5)); assert.strictEqual(deviation([20, 3]), Math.sqrt(144.5)); assert.strictEqual(deviation([3, 20]), Math.sqrt(144.5)); diff --git a/test/threshold/freedmanDiaconic-test.js b/test/threshold/freedmanDiaconic-test.js index bd11f965..6bc6d800 100644 --- a/test/threshold/freedmanDiaconic-test.js +++ b/test/threshold/freedmanDiaconic-test.js @@ -4,3 +4,15 @@ import {thresholdFreedmanDiaconis} from "../../src/index.js"; it("thresholdFreedmanDiaconis(values, min, max) returns the expected result", () => { assert.strictEqual(thresholdFreedmanDiaconis([4, 3, 2, 1, NaN], 1, 4), 2); }); + +it("thresholdFreedmanDiaconis(values, min, max) handles values with zero deviation", () => { + assert.strictEqual(thresholdFreedmanDiaconis([1, 1, 1, 1], 1, 4), 1); +}); + +it("thresholdFreedmanDiaconis(values, min, max) handles single-value arrays", () => { + assert.strictEqual(thresholdFreedmanDiaconis([1], 1, 4), 1); +}); + +it("thresholdFreedmanDiaconis(values, min, max) handles empty arrays", () => { + assert.strictEqual(thresholdFreedmanDiaconis([], 1, 4), 1); +}); diff --git a/test/threshold/scott-test.js b/test/threshold/scott-test.js index e85c400c..d51faae6 100644 --- a/test/threshold/scott-test.js +++ b/test/threshold/scott-test.js @@ -4,3 +4,15 @@ import {thresholdScott} from "../../src/index.js"; it("thresholdScott(values, min, max) returns the expected result", () => { assert.strictEqual(thresholdScott([4, 3, 2, 1, NaN], 1, 4), 2); }); + +it("thresholdScott(values, min, max) handles values with zero deviation", () => { + assert.strictEqual(thresholdScott([1, 1, 1, 1], 1, 4), 1); +}); + +it("thresholdScott(values, min, max) handles single-value arrays", () => { + assert.strictEqual(thresholdScott([1], 1, 4), 1); +}); + +it("thresholdScott(values, min, max) handles empty arrays", () => { + assert.strictEqual(thresholdScott([], 1, 4), 1); +}); diff --git a/test/threshold/sturges-test.js b/test/threshold/sturges-test.js index 7e57995e..fd15837b 100644 --- a/test/threshold/sturges-test.js +++ b/test/threshold/sturges-test.js @@ -3,4 +3,9 @@ import {thresholdSturges} from "../../src/index.js"; it("thresholdSturges(values, min, max) returns the expected result", () => { assert.strictEqual(thresholdSturges([4, 3, 2, 1, NaN], 1, 4), 3); + assert.strictEqual(thresholdSturges([1], 1, 4), 1); +}); + +it("thresholdSturges(values, min, max) handles empty arrays", () => { + assert.strictEqual(thresholdSturges([], 1, 4), 1); });