From ebebc1744a11c6f8aedbac76a73473514edbe01f Mon Sep 17 00:00:00 2001 From: michealroberts Date: Wed, 8 Jan 2025 12:51:19 +0000 Subject: [PATCH] feat: add mean() to stats module in @observerly/fits feat: add mean() to stats module in @observerly/fits --- src/stats/__tests__/mean.spec.ts | 65 ++++++++++++++++++++++++++++++++ src/stats/index.ts | 1 + src/stats/mean.ts | 13 +++++++ 3 files changed, 79 insertions(+) create mode 100644 src/stats/__tests__/mean.spec.ts create mode 100644 src/stats/mean.ts diff --git a/src/stats/__tests__/mean.spec.ts b/src/stats/__tests__/mean.spec.ts new file mode 100644 index 0000000..0010fc1 --- /dev/null +++ b/src/stats/__tests__/mean.spec.ts @@ -0,0 +1,65 @@ +/*****************************************************************************************************************/ + +// @author Michael Roberts +// @package @observerly/fits +// @license Copyright © 2021-2025 observerly + +/*****************************************************************************************************************/ + +import { describe, expect, it } from 'vitest' + +import { mean } from '../mean' + +/*****************************************************************************************************************/ + +describe('mean', () => { + it('should calculate the mean of an array with positive numbers', () => { + const input = [1, 2, 3, 4, 5] + const result = mean(input) + expect(result).toBe(3) // (1 + 2 + 3 + 4 + 5) / 5 = 3 + }) + + it('should calculate the mean of an array with negative numbers', () => { + const input = [-1, -2, -3, -4, -5] + const result = mean(input) + expect(result).toBe(-3) // (-1 + -2 + -3 + -4 + -5) / 5 = -3 + }) + + it('should calculate the mean of an array with mixed positive and negative numbers', () => { + const input = [-3, -2, -1, 1, 2, 3] + const result = mean(input) + expect(result).toBe(0) // (-3 + -2 + -1 + 1 + 2 + 3) / 6 = 0 + }) + + it('should calculate the mean of an array with a single element', () => { + const input = [42] + const result = mean(input) + expect(result).toBe(42) // Mean of a single element is the element itself + }) + + it('should handle an empty array gracefully', () => { + const input: number[] = [] + expect(mean(input)).toBeNaN() + }) + + it('should calculate the mean of an array with floating-point numbers', () => { + const input = [1.5, 2.5, 3.5, 4.5] + const result = mean(input) + expect(result).toBe(3) // (1.5 + 2.5 + 3.5 + 4.5) / 4 = 3 + }) + + it('should handle arrays with repeated values', () => { + const input = [2, 2, 2, 2] + const result = mean(input) + expect(result).toBe(2) // Mean of identical values is the value itself + }) + + it('should not mutate the original array', () => { + const input = [1, 2, 3, 4] + const original = [...input] + mean(input) + expect(input).toEqual(original) + }) +}) + +/*****************************************************************************************************************/ diff --git a/src/stats/index.ts b/src/stats/index.ts index a79af2d..36509a8 100644 --- a/src/stats/index.ts +++ b/src/stats/index.ts @@ -6,6 +6,7 @@ /*****************************************************************************************************************/ +export { mean } from './mean' export { median } from './median' /*****************************************************************************************************************/ diff --git a/src/stats/mean.ts b/src/stats/mean.ts new file mode 100644 index 0000000..fc0e828 --- /dev/null +++ b/src/stats/mean.ts @@ -0,0 +1,13 @@ +/*****************************************************************************************************************/ + +// @author Michael Roberts +// @package @observerly/fits +// @license Copyright © 2021-2025 observerly + +/*****************************************************************************************************************/ + +export const mean = (arr: number[]): number => { + return arr.reduce((a, b) => a + b, 0) / arr.length +} + +/*****************************************************************************************************************/