Math.random() using the same random seed and so is shuffle()

URL of experiment: https://run.pavlovia.org/vickup/brm_calc_valence_2/html

Description of the problem:
We have run this experiment on over 300ppl and they all get the rand_list_num of 8. We believe that Math.random() is using the same random seed, per (A) we found that the random seed is determined by the browser and cannot be changed manually. Additionally the shuffle() function is also shuffling the data in the same way every time.

Here’s the code:


// get random list number
shuffle = util.shuffle;
max_list_num = 40;
rand_list_num = Math.floor((Math.random() * max_list_num) + 1);
console.log("Random list number");
console.log(rand_list_num);

// filter words from stimuli
words = [];
for (var eachTrial, _pj_c = 0, _pj_a = valence_semantic_lists.trialList, _pj_b = _pj_a.length; (_pj_c < _pj_b); _pj_c += 1) {
    eachTrial = _pj_a[_pj_c];
    if ((eachTrial["list_num"] === rand_list_num)) {
        words.push(eachTrial["Word"]);
    }
words = shuffle(words);
}```

Things we've tried: 
We tried to change max_list num to an array from 1-40 and use max_list_num.length instead.

max_list_num = [];
for (var i = 0; i < 40; i++) {
max_list_num_array.push(i);
}
rand_list_num = Math.floor((Math.random() * max_list_num.length) + 1);


More Info:
valence_semantic_lists is a trialhandler.
```// read stimuli
valence_semantic_lists = new TrialHandler({
        psychoJS: psychoJS,
        trialList: 'valence_semantic_lists.csv',
        nReps: 1,
        method: TrialHandler.Method.RANDOM,
        extraInfo: expInfo,
        seed: 1,
        name: 'valence_semantic_lists'
});```

Thank you for any assistance.


(A) https://hackernoon.com/how-does-javascripts-math-random-generate-random-numbers-ef0de6a20131

The solution was that if you have Math.random() or util.shuffle after you manually read in a trialhandler it won’t be random for some reason. After I moved them above in my code it worked.

1 Like

Hi JP,

I just stumbled upon you post. Sounds like something interesting to examine (and fix) but I didn’t completely understand it. What do you mean with manually reading in a TrialHandler?

Best, Thomas

If use the code component and manually create a trialhandler object before I use Math.random() or shuffle() then every participant will get the same random number and their words will be shuffled in the same manner.

I think the issue is with when the new TrialHandler is created it resets the random seed that the browser generates some how.

JP

You are specifying a fixed seed value for the random number generator. This is what guarantees that you will get the same “random” sequence each time.

e.g. from the docs at psychopy.data - functions for storing/saving/analysing data — PsychoPy v2023.2.3

seed: an integer
If provided then this fixes the random number generator to use the same pattern of trials, by seeding its startpoint

i.e. you are getting a constant random order because you explicitly asked for one. Presumably any other random calls after this will also always give the same result, as they will continue from the same sequence. This is why you find that the order of the code matters: if you make a call to another random function before setting the seed explicitly in the trial handler function, the random number generator at that point will start with a seed based on the current time and/or other sources of randomness, depending on the library involved. From the moment you set the seed to a constant value, the random number output sequence will be repeated on every run.

1 Like