build(deps-dev): apply updates
[e-mobility-charging-stations-simulator.git] / src / utils / StatisticUtils.ts
CommitLineData
9bf0ef23 1import { isEmptyArray, isNullOrUndefined } from './Utils';
4884b8d3
JB
2
3export const median = (dataSet: number[]): number => {
9bf0ef23 4 if (isEmptyArray(dataSet)) {
4884b8d3
JB
5 return 0;
6 }
7 if (Array.isArray(dataSet) === true && dataSet.length === 1) {
8 return dataSet[0];
9 }
10 const sortedDataSet = dataSet.slice().sort((a, b) => a - b);
11 return (
12 (sortedDataSet[(sortedDataSet.length - 1) >> 1] + sortedDataSet[sortedDataSet.length >> 1]) / 2
13 );
14};
15
16// TODO: use order statistics tree https://en.wikipedia.org/wiki/Order_statistic_tree
17export const nthPercentile = (dataSet: number[], percentile: number): number => {
18 if (percentile < 0 && percentile > 100) {
19 throw new RangeError('Percentile is not between 0 and 100');
20 }
9bf0ef23 21 if (isEmptyArray(dataSet)) {
4884b8d3
JB
22 return 0;
23 }
24 const sortedDataSet = dataSet.slice().sort((a, b) => a - b);
25 if (percentile === 0 || sortedDataSet.length === 1) {
26 return sortedDataSet[0];
27 }
28 if (percentile === 100) {
29 return sortedDataSet[sortedDataSet.length - 1];
30 }
31 const percentileIndexBase = (percentile / 100) * (sortedDataSet.length - 1);
32 const percentileIndexInteger = Math.floor(percentileIndexBase);
9bf0ef23 33 if (!isNullOrUndefined(sortedDataSet[percentileIndexInteger + 1])) {
4884b8d3
JB
34 return (
35 sortedDataSet[percentileIndexInteger] +
36 (percentileIndexBase - percentileIndexInteger) *
37 (sortedDataSet[percentileIndexInteger + 1] - sortedDataSet[percentileIndexInteger])
38 );
39 }
40 return sortedDataSet[percentileIndexInteger];
41};
42
43export const stdDeviation = (dataSet: number[]): number => {
44 let totalDataSet = 0;
45 for (const data of dataSet) {
46 totalDataSet += data;
47 }
48 const dataSetMean = totalDataSet / dataSet.length;
49 let totalGeometricDeviation = 0;
50 for (const data of dataSet) {
51 const deviation = data - dataSetMean;
52 totalGeometricDeviation += deviation * deviation;
53 }
54 return Math.sqrt(totalGeometricDeviation / dataSet.length);
55};