Skip to content

Instantly share code, notes, and snippets.

@owenkellogg
Created October 14, 2023 02:58
Show Gist options
  • Save owenkellogg/061d7f58c3735e8d1f75cf31855f924d to your computer and use it in GitHub Desktop.
Save owenkellogg/061d7f58c3735e8d1f75cf31855f924d to your computer and use it in GitHub Desktop.
Generates N values in a standard distribution summing to X
/**
* 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)}`);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment