Madmutt
Madmutt

Reputation: 1

Given min, max, mean and sample size, return a normal distribution as an array using javascript

For example, given:

min = 1
max = 5
Ave = 3
size = 5

ie. at this stage, we have [1,?,?,?,5]

How can I calculate the missing numbers? (This one is easy -> [1,2,3,4,5] - but how do I write a JS function to return this array)

or, given:

min = 23
max = 2500
Ave = 1007
size = 800

ie. at this stage, we have [23,?..,2500]

How can I calculate the missing numbers? (ie. return a completed array (I think this is called uniform distribution...))

Some info about the returned Array

  1. The numbers in the returned array must be rounded to 2 decimal places.
  2. Each number in the array is >= the preceding number.
  3. I expect the distribution if plotted to return a shallow S shaped curve.

This is what I have so far:

const min = 1;      //lowest value
const max = 5;      //highest value
const ave = 4;      //not currently used
const supply = 3;   //supply (- 2 because min and max are appended)

const data = Array.from({length: supply}, (_, i) => i + 1);
const distArray = [];
data.map(n => {
    distArray.push(Math.round((min+n*(max-min) / (supply+1)) * 1e2 ) / 1e2);
});
distArray.unshift(min);//append min value
distArray.push(max);//append max value
console.log(distArray); // returns [1,2,3,4,5]

The above function returns an array of length supply+2 between the min and max values.

The next step is to include the ave variable. What if you were now told that the average of the 5 numbers was 2.5, not 3 (as it is in the normal distribution from min to max). This would return a different array based on the average value... This is my question - how do I do that?

This is what I have tried, but it's wrong... It kinda works for small arrays, but for larger arrays, the distribution is all concentrated around the middle - I need a better formula to calculate the distribution...

const min = 5;      //lowest value
const max = 12;      //highest value
const supply = 5;   //supply (- 2 because min and max are appended)
const ave = 8;      //Average value

const data = Array.from({length: supply}, (_, i) => i + 1);
const distArray = [];

const ksum = (supply + 2) * ave; //known sum
const usum = ksum - (min + max); // unknown sum
const parts = data.reduce((a, n) => a + n, 0);//Num of remainder to share
const b = Math.floor(usum / supply); //base value to add to each
const r = usum % supply; //remainder to share in parts

data.map(n => {
    distArray.push(Math.round((b + (n/parts * r)) * 1e2 ) / 1e2);
});
distArray.unshift(min);//append min value
distArray.push(max);//append max value

console.log(distArray); // returns [5, 7.27, 7.53, 7.8, 8.07, 8.33, 12]

Upvotes: 0

Views: 370

Answers (1)

gog
gog

Reputation: 11347

Consider the following "math"

avg = sum(all) / size
sum(all) = sum(known) + sum(unknown)
sum(unknown) = avg x size - sum(known)
unknown = sum(unknown) / (size - size(known))

Would that work for you?

Upvotes: 1

Related Questions