Randomising conditions with transition probabilities

I’m trying to code an experiment where the probability that one trial follows another depends on the trial before, i.e. trials are ordered with Markovian transition probabilities. The probability you are about to see A, given you have just seen B, is denoted by P(A|B), and this is different from P(B|A). There are only two different conditions (A and B).

Ultimately, I will upload this to Pavlovia, so it needs to be a format which enables that. Is there a way to code this with the loop function? If not, how could I do it?

Many thanks in advance :slight_smile:

Hi @verdi,

When you say “trials are ordered with Markovian transition probabilities”, do you mean that you will have a conditions file that already has all the trials in the correct order? If that is the case, all you would need to do is set “loopType” to “sequential”.


1 Like

I’m going to guess that you want to run this randomly on each session, rather than have a pre-specified order in a conditions file. If so, the loop settings won’t be able to handle this for you, it will require some custom code. So I’d suggest you just have a loop set to run the required number of trials, and containing both A and B trial routines. Insert a code component on the first one, and in its “begin routine” tab, put something like this (this is Python code, you’ll need to translate it to JavaScript to run online):

# use your actual values:
p_A_given_B = 0.7
p_B_given_B = 1.0 - p_A_given_B # not used, just being explicit

p_B_given_A = 0.4
p_A_given_A = 1.0 - p_B_given_A # not used, just being explicit

p = random() # between 0 and 1

if your_loop_name.thisN == 0: # dummy value needed for first trial
    last_type = np.random.choice(['A', 'B'])

if last_type == 'A':
    if p < p_B_given_A:
        current_type = 'B'
        current_type = 'A'
elif p < p_A_given_B:
    current_type = 'A'
    current_type = 'B'
last_type = current_type

# store stuff in the data so you can test this is doing the right thing:

thisExp.addData('last_type', last_type)
thisExp.addData('p', p)
thisExp.addData('current_type', current_type)

# now only run this routine if it is the correct type:
if current_type == 'B':
    continueRoutine = False

Then in the “B” routine, insert a code component and put something like this in its “begin routine” tab:

if current_type == 'A':
    continueRoutine = False

The code above REALLY NEEDS TO BE TESTED. It is very easy to get this sort of nested boolean logic wrong, but hopefully this at least shows the sort of approach to take.

1 Like

Thank you both so much, this is really helpful, I appreciate it. I will try both methods. I am happy to hardcode the probabilities into a sequence, but I’d like a different sequence block to be used for each participant. Is there a way of doing this through Pavlovia? For example, I’m happy to hardcode 1000 different blocks, but how do I make sure that each participant uses a different block rather than the same one?

@verdi, if you were to opt for a solution involving pre-randomised condition files, a simple solution would be to randomly select a condition file (of course, this would not guarantee that all condition files are unique). If unique files are required, you could use participant numbers generated by Wakefield’s web app to select the conditions file.

Please find a minimal working example for random selection attached (note that this only includes the JavaScript code).


random_input.psyexp (6.5 KB)
input1.xlsx (8.5 KB)
input2.xlsx (8.5 KB)
input3.xlsx (8.5 KB)

1 Like

@Michael can i ask you how to use this code when my condition are actually not a stimulus but a whole loop ?

i want to write a code that uses the participants prolific ID number and using their ID i want to assign them to group A and B

I am not sure of to randomly assign them to:
A will get: a control condition (meaning skip all the pretreatments)
B will randomly assigned between 4 pretreatments.

currently i dont have condition files but i could create them if needed

Thank you!

You can use the code above to instead set a variable that you use in the nReps field of a loop dialog. If that variable is set to 0, then the loop won’t run.

1 Like

Thanks so much! This is really helpful :slight_smile: