/** * Generates a normally distributed random number with an absolute value. * @returns A positive random number following a standard normal distribution. */ function boxMullerRandomPositive(): number { let u = 0, v = 0; while (u === 0) u = Math.random(); while (v === 0) v = Math.random(); return Math.abs(Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v)); } /** * Generates an array of N positive values in a standard distribution that sum to X. * @param N - The number of values to generate. * @param X - The target sum for the generated values. * @returns An array of N positive numbers in a standard distribution that sum to X. */ function generatePositiveStandardDistribution(N: number, X: number): number[] { let generatedValues: number[] = new Array(N).fill(0).map(() => boxMullerRandomPositive()); // Calculate the current sum of generated values const currentSum = generatedValues.reduce((acc, val) => acc + val, 0); // Scale the values so that their sum becomes X const scalingFactor = X / currentSum; generatedValues = generatedValues.map(val => val * scalingFactor); return generatedValues; } // Example usage const N = 100; const X = 10; const result = generatePositiveStandardDistribution(N, X); console.log(`Generated positive values: ${result}`); console.log(`Sum: ${result.reduce((acc, val) => acc + val, 0)}`);