X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Futils%2FStatisticUtils.ts;h=2ff71b0acb2ffa897a5d07f0e7bcd18719314903;hb=de7b9e0583275225509c099f75a2801371da54d0;hp=bb9a847091decf2ca488f83ad8c3d9d579d6e7fd;hpb=4884b8d37eebb90a39a8295f1b61cf822dcf0869;p=e-mobility-charging-stations-simulator.git diff --git a/src/utils/StatisticUtils.ts b/src/utils/StatisticUtils.ts index bb9a8470..2ff71b0a 100644 --- a/src/utils/StatisticUtils.ts +++ b/src/utils/StatisticUtils.ts @@ -1,7 +1,31 @@ -import { Utils } from './Utils'; +import { isEmptyArray, isNullOrUndefined } from './Utils'; +/** + * Computes the average of the given data set. + * + * @param dataSet - Data set. + * @returns The average of the given data set. + * @internal + */ +export const average = (dataSet: number[]): number => { + if (Array.isArray(dataSet) && dataSet.length === 0) { + return 0; + } + if (Array.isArray(dataSet) && dataSet.length === 1) { + return dataSet[0]; + } + return dataSet.reduce((accumulator, nb) => accumulator + nb, 0) / dataSet.length; +}; + +/** + * Computes the median of the given data set. + * + * @param dataSet - Data set. + * @returns The median of the given data set. + * @internal + */ export const median = (dataSet: number[]): number => { - if (Utils.isEmptyArray(dataSet)) { + if (isEmptyArray(dataSet)) { return 0; } if (Array.isArray(dataSet) === true && dataSet.length === 1) { @@ -18,7 +42,7 @@ export const nthPercentile = (dataSet: number[], percentile: number): number => if (percentile < 0 && percentile > 100) { throw new RangeError('Percentile is not between 0 and 100'); } - if (Utils.isEmptyArray(dataSet)) { + if (isEmptyArray(dataSet)) { return 0; } const sortedDataSet = dataSet.slice().sort((a, b) => a - b); @@ -30,7 +54,7 @@ export const nthPercentile = (dataSet: number[], percentile: number): number => } const percentileIndexBase = (percentile / 100) * (sortedDataSet.length - 1); const percentileIndexInteger = Math.floor(percentileIndexBase); - if (!Utils.isNullOrUndefined(sortedDataSet[percentileIndexInteger + 1])) { + if (!isNullOrUndefined(sortedDataSet[percentileIndexInteger + 1])) { return ( sortedDataSet[percentileIndexInteger] + (percentileIndexBase - percentileIndexInteger) * @@ -40,16 +64,27 @@ export const nthPercentile = (dataSet: number[], percentile: number): number => return sortedDataSet[percentileIndexInteger]; }; -export const stdDeviation = (dataSet: number[]): number => { - let totalDataSet = 0; - for (const data of dataSet) { - totalDataSet += data; - } - const dataSetMean = totalDataSet / dataSet.length; - let totalGeometricDeviation = 0; - for (const data of dataSet) { - const deviation = data - dataSetMean; - totalGeometricDeviation += deviation * deviation; - } - return Math.sqrt(totalGeometricDeviation / dataSet.length); +/** + * Computes the sample standard deviation of the given data set. + * + * @param dataSet - Data set. + * @param dataSetAverage - Average of the data set. + * @returns The sample standard deviation of the given data set. + * @see https://en.wikipedia.org/wiki/Unbiased_estimation_of_standard_deviation + * @internal + */ +export const stdDeviation = ( + dataSet: number[], + dataSetAverage: number = average(dataSet), +): number => { + if (isEmptyArray(dataSet)) { + return 0; + } + if (Array.isArray(dataSet) && dataSet.length === 1) { + return 0; + } + return Math.sqrt( + dataSet.reduce((accumulator, num) => accumulator + Math.pow(num - dataSetAverage, 2), 0) / + (dataSet.length - 1), + ); };