Javascript Gaussian function

URL of experiment: Pavlovia

Description of the problem:
I am looking to set my experiment up to run online and my x coordinate for my stimulus position values are set in a code component.

Using python code I set the x position for my two stimuli to come from two gaussians where the value of the target becomes the mean of the cue:

target_coin_position = random.gauss (mu, priorsigma)

cue_coin_position = random.gass(target_coin_position, cuesigma)

Is there an equivalent method of getting values from a Gaussian distribution in java script?

I did some research online and found randomGaussian(mu, sigma)

So I tried the java script code:

target_coin_position = randomGaussian(mu, priorsigma);

cue_coin_position = randomGaussian(target_coin_position, cue_sigma);

For this my error was:

randomGausian() is not defined- see screen shot image

I also looked into Random.nextGaussian() but I think that was for Java not Java script.

If I want this to work online is there any adjustments I could make or is this function not available to PsychoJS currently?

Could I do this process manually in java script by creating function that takes the mean (mu) and SD (sigma) as parameters and creates a normal distribution from those parameters?

Hi Lucy,

There is no built-in function available, but there are some libraries on the web that you could use. Some aren’t very solid, but when I needed a quantile function for a d-prime (see dprime repo), I ran some tests and found the function in this repo to be reliable. Above, I linked directly to the function you need.

Now, I would recommend testing it first, for instance by generating a large set of numbers with a Gaussian distribution and draw a histogram with a normal curve overlaying it. If you run the script below in the browser console, you can get these numbers.

// Function from the gaussian repo, with a slight adjustment
function generateGaussian(mean,std){
  var _2PI = Math.PI * 2;
  var u1 = Math.random();
  var u2 = Math.random();
  
  var z0 = Math.sqrt(-2.0 * Math.log(u1)) * Math.cos(_2PI * u2);
  var z1 = Math.sqrt(-2.0 * Math.log(u1)) * Math.sin(_2PI * u2);

  return z0 * std + mean;
}
// Generate 10,000 Gaussian random numbers
result = [];
for (var i = 0; i < 10000; i++) {
  result.push(generateGaussian(0, 1));
}

Best, Thomas

I ran the test, using this function in R to plot a Histogram with an normal curve overlaid on top of it. Seems legit :slight_smile:

Thank you for getting back to me so quickly Thomas. It looks fantastic.

1 Like

Hi again Thomas,

I had a go with this and added the function to my code component where it is required. However I think the next problem I am having (I think) is importing the libraries at the very beginning (see .js file in R studio) because the experiment does initialise. I then type in the participant details then google chrome crashes and I have to reload (I’ve explored the help chrome offers for this deleting cache, updating and restarting etc.)

When I open the developer tools I get these errors (see below) which I am guessing relates to the fact it cannot import the sound libraries?

Never knew that RStudio supports syntax highlighting for JavaScript. Interesting!

The warnings RStudio gives on those lines nothing to worry about; it’s just a bit more modern style of JS than RStudio is familiar with.

When I fork and run your experiment, I notice my browser freezes. When I stop it, I get the message “script terminated by timeout” at a line inside of the loop below. My guess is that this while loop takes very long (maybe never ends).

  for (var j = 0, _pj_a = ntrials; (j < _pj_a); j += 1) {
      target_coin_position = result.push(generateGaussian(mu, priorsigma));
      cue_coin_position = result.push(generateGaussian(target_coin_position, cuesigma));
      while (((((target_coin_position < minposition) || (target_coin_position > maxposition)) || (cue_coin_position < minposition)) || (cue_coin_position > maxposition))) {
          target_coin_position = result.push(generateGaussian(mu, priorsigma));
          cue_coin_position = result.push(generateGaussian(target_coin_position, cuesigma));
          
      
      }
      target_list.append(target_coin_position);
      cue_list.append(cue_coin_position);
  }

Okay thank you I will try running it without the while loop (it only provides a constrain for the x axis value) and then see if I can adjust (add break or similar).

1 Like