import type { TrendDirection } from "../models/types.js"; /** * Calculate arithmetic mean of values. * Returns 0 for empty array. */ export function mean(values: number[]): number { if (values.length === 0) return 0; const sum = values.reduce((acc, val) => acc + val, 0); return sum / values.length; } /** * Calculate population standard deviation. * Returns 0 for empty or single-element array. */ export function standardDeviation(values: number[]): number { if (values.length <= 1) return 0; const avg = mean(values); const squaredDiffs = values.map((val) => Math.pow(val - avg, 2)); const variance = mean(squaredDiffs); return Math.sqrt(variance); } /** * Determine trend direction based on percentage change. * Returns "up" if change > threshold, "down" if change < -threshold, "stable" otherwise. * Default threshold is 5%. */ export function trendDirection( current: number, previous: number, threshold: number = 5 ): TrendDirection { const change = percentChange(current, previous); if (change > threshold) return "up"; if (change < -threshold) return "down"; return "stable"; } /** * Calculate percentage change between current and previous values. * Returns 0 if previous is 0. */ export function percentChange(current: number, previous: number): number { if (previous === 0) return 0; return ((current - previous) / previous) * 100; } /** * Calculate how many standard deviations a value is from the mean. * Returns 0 if standard deviation is 0. */ export function deviationsFromMean(value: number, values: number[]): number { const avg = mean(values); const stdDev = standardDeviation(values); if (stdDev === 0) return 0; return (value - avg) / stdDev; }