Skip to content

Commit 3a51a97

Browse files
committed
feat: add xDistributionStats
1 parent 2ef1edb commit 3a51a97

File tree

6 files changed

+109
-12
lines changed

6 files changed

+109
-12
lines changed

src/__tests__/__snapshots__/index.test.ts.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ exports[`test existence of exported functions 1`] = `
2121
"xCostMatrix",
2222
"xCrossCorrelation",
2323
"xCumulative",
24+
"xDistributionStats",
2425
"xDivide",
2526
"xDotProduct",
2627
"xEnsureFloat64",

src/matrix/matrixCuthillMckee.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010
* copies of the Software, and to permit persons to whom the Software is
1111
* furnished to do so, subject to the following conditions:
1212
*
13-
The above copyright notice and this permission notice shall be included in
14-
all copies or substantial portions of the Software.
15-
16-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1919
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2020
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2121
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { expect, test } from 'vitest';
2+
3+
import { xDistributionStats } from '../xDistributionStats';
4+
5+
test('empty array', () => {
6+
const data: number[] = [];
7+
expect(() => xDistributionStats(data)).toThrow('input must not be empty');
8+
});
9+
10+
test('one element', () => {
11+
const data = [15];
12+
const stats = xDistributionStats(data);
13+
expect(stats).toStrictEqual({
14+
q1: 15,
15+
median: 15,
16+
q3: 15,
17+
min: 15,
18+
max: 15,
19+
mean: 15,
20+
sd: Number.NaN,
21+
nb: 1,
22+
});
23+
});
24+
25+
test('4 elements', () => {
26+
const data = [15, 13, 17, 7];
27+
const stats = xDistributionStats(data);
28+
expect(stats).toBeDeepCloseTo({
29+
min: 7,
30+
q1: 11.5,
31+
median: 14,
32+
q3: 15.5,
33+
max: 17,
34+
mean: 13,
35+
sd: 4.320493798938574,
36+
nb: 4,
37+
});
38+
});
39+
40+
test('5 elements', () => {
41+
const data = [1, 2, 3, 4, 5];
42+
const stats = xDistributionStats(data);
43+
expect(stats).toBeDeepCloseTo({
44+
min: 1,
45+
q1: 2,
46+
median: 3,
47+
q3: 4,
48+
max: 5,
49+
mean: 3,
50+
sd: 1.5811388300841898,
51+
nb: 5,
52+
});
53+
});
54+
55+
test('typed array', () => {
56+
const data = [15, 13, 17, 7];
57+
const typedArray = Uint16Array.from(data);
58+
expect(xDistributionStats(typedArray)).toStrictEqual(
59+
xDistributionStats(data),
60+
);
61+
});

src/x/__tests__/xStandardDeviation.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@ import { xStandardDeviation } from '../xStandardDeviation';
44

55
test('standard deviation', () => {
66
const data = [15, 13, 17, 7];
7-
const s = xStandardDeviation(data);
8-
expect(s).toBeCloseTo(Math.sqrt(18.667), 3);
9-
expect(xStandardDeviation(data, { unbiased: true })).toBe(s);
7+
const sd = xStandardDeviation(data);
8+
expect(sd).toBeCloseTo(Math.sqrt(18.667), 3);
9+
expect(xStandardDeviation(data, { unbiased: true })).toBe(sd);
1010
expect(xStandardDeviation(data, { unbiased: false })).toBe(Math.sqrt(14));
1111
});
1212

1313
test('standard deviation of typed array', () => {
1414
const data = [15, 13, 17, 7];
1515
const typedArray = Uint16Array.from(data);
16-
const s = xStandardDeviation(typedArray);
17-
expect(s).toBeCloseTo(Math.sqrt(18.667), 3);
18-
expect(xStandardDeviation(data, { unbiased: true })).toBe(s);
16+
const sd = xStandardDeviation(typedArray);
17+
expect(sd).toBeCloseTo(Math.sqrt(18.667), 3);
18+
expect(xStandardDeviation(data, { unbiased: true })).toBe(sd);
1919
expect(xStandardDeviation(data, { unbiased: false })).toBe(Math.sqrt(14));
2020
});
2121

src/x/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export * from './xCorrelation';
1313
export * from './xCostMatrix';
1414
export * from './xCrossCorrelation';
1515
export * from './xCumulative';
16+
export * from './xDistributionStats';
1617
export * from './xDivide';
1718
export * from './xDotProduct';
1819
export * from './xEnsureFloat64';

src/x/xDistributionStats.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import type { NumberArray } from 'cheminfo-types';
2+
3+
import { xBoxPlot } from './xBoxPlot';
4+
import { xMean } from './xMean';
5+
import { xStandardDeviation } from './xStandardDeviation';
6+
7+
export interface XDistributionStats {
8+
mean: number;
9+
min: number;
10+
q1: number;
11+
median: number;
12+
q3: number;
13+
max: number;
14+
sd: number;
15+
nb: number;
16+
}
17+
18+
/**
19+
* Calculate distribution statistics of an array without providing options
20+
* This ensure that the statistics are calculated in the same way in all the packages
21+
* If the array is empty it will throw an error
22+
* If the array has a length of 1, sd will be NaN (unbiased calculation of sd)
23+
* @param array - data
24+
* @param options
25+
* @returns - q1, median, q3, min, max
26+
*/
27+
export function xDistributionStats(array: NumberArray): XDistributionStats {
28+
return {
29+
...xBoxPlot(array),
30+
mean: xMean(array),
31+
sd: xStandardDeviation(array),
32+
nb: array.length,
33+
};
34+
}

0 commit comments

Comments
 (0)