How to select non-consecutive values from an array, or generate non-consecutive values?

20 visualizaciones (últimos 30 días)
Hello all,
I have the following question. I am creating trials where participants listen to a series of 50 ms tones in a classic oddball paradigm, with 114 total tones in a trial. For those unfamiliar with oddball paradigms, the large majority of these tones will be the same tone, called the 'standards.' A minority of these tones will be 'deviant' tones, which the participant will be asked to respond to. I want these deviant tones to occur randomly, but they cannot occur consecutively. So if the fourth tone is a deviant, the fifth (or the third tone) cannot be deviants.
If it helps, i have included some code that randomly selects which tones will be deviants, but I don't know how to make sure that no deviants occur consecutively. Randperm doesn't seem to have this capability
num_deviants=29; %arbitrary number, each trial will have a different number of deviants
%% 3. Initialize static variable (stay the same across trials)
num_stim_total=114; %total number of tones
stim_times=[0,50]; %this matrix will have start and stop times for the stimuli, in columns 1 and 2 respectively
%% 4. Create interstimulus intervals and stimulus onset/offset times
ISI_generator=randi([700 1000],1,113); %creates 113 random samplings from 700 to 1000
for i=1:113
stim_times(i+1,1)=stim_times(i,2)+ISI_generator(i); %adds ISI to the end time of the last stimulus to create start time of next stim
stim_times(i+1,2)=stim_times(i+1,1)+50; %adds 50ms to stim start time to signify the stimulus stop time
end
%% 5. Randomly decides deviants vs standards
deviant_decider=randperm(num_stim_total,num_deviants)'; %randomly decides which start times will become deviant sounds (designated by a '1')
stim_times(deviant_decider,3)= 1;
standard_array=1:114; %create an array of 1 to 114
standard_decider=setdiff(standard_array,deviant_decider'); %returns all the numbers 1-114 that aren't in deviant_decider, and makes them standards

Respuesta aceptada

John D'Errico
John D'Errico el 5 de Abr. de 2020
Editada: John D'Errico el 5 de Abr. de 2020
I'd argue that requiring that the outliers/deviants NOT be consecutive biases your results.
But this is easy enough to do.
Start by deciding how many deviants you need. In the example, you had 29 of them.
Now, insert one standard tones between every deviant. That insures you will not have anything consecutive. You may decide to insert a standard tone before the first, and after the last. I chose that as the desired behavior.
Finally, you now have a total of 29 + 30 tones in place. You want a total of 114 tones, so you need to choose random places to insert new tones. There are several ways you can do that, but even if you just pick a random spot one at a time, who cares? There will be only 114 - 59 = 55 new tones to insert. The code I wrote below is fully vectorized however.
In the example I'll give, the final result will have a 1 in it, where a deviant tone will live. There will ALWAYS be at least one standard tone between every deviant tone. (Even though I disagree with that. Your experiment however, so your choice.)
ndev = 29;
ntot = 114;
seq = zeros(1,ndev*2 + 1);
seq(2:2:end) = 1;
seqfinal = zeros(1,ntot);
seqfinal(sort(randperm(ntot,ndev*2 + 1))) = seq;
So the final sequence chosen is:
seqfinal =
Columns 1 through 21
0 1 0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 1
Columns 22 through 42
0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0
Columns 43 through 63
0 1 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 1
Columns 64 through 84
0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 1 0 0 1 0 1
Columns 85 through 105
0 0 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 0 1 0
Columns 106 through 114
1 0 0 1 0 1 0 1 0
There are exactly 29 ones in the vector, with no pair of consecutuve ones. I set it up so that the first and last point are not 1, but that behavior could easily be changed.
  7 comentarios
Matthieu Sherwood
Matthieu Sherwood el 6 de Abr. de 2020
Editada: Matthieu Sherwood el 6 de Abr. de 2020
Ironically i understood best what you were doing on the left side of the assignment, ie the stuff with the randperm and sort since i did essentially just that in my original script. the part i was a bit hung up on was th '=seq' part since seq is a vector and it seemed like you were setting individual indices of seqfinal equal to a vector. but now i realize that if you said a=seqfinal(sort(randperm(ntot,ndev*2 + 1)), a would be a row vector of zeros, indexed from seqfinal, that is the same size as seq. so when you say seqfinal(sort(randperm(num_stim_total,num_targets*2 + 1)))=seq, it becomes identical to seq. but the other values in seqfinal remain zeros, and i get how that ensures there are no consecutive 1's. what i just wrote might not have been the best written explanation but i get visually and procedurally what happened.
John D'Errico
John D'Errico el 6 de Abr. de 2020
It is always difficult to know online how to explain something. I find it far easier to explain a topic like that in person, because I can watch the student's eyes as I explain a concept. You know when someone understands what you are saying because yuou can see the light go on, so you can then go on to the part of the problem they don't understand. That does force me to tend to over-explain. :)
Viewed as I want to view what I did, this was a vectorized scheme to essentially insert zeros into the vector we already had, by implicitly spreading out the elements in the vector seq. The sort forced them to stay in the same order, and the randperm implicitly chose random places for the spreading/zero insertion to happen.
A trick with using MATLAB effectively in vectorized schemes is always to visualize your data as a whole. You get used to working with vectors and arrays, and how the elements in that vectors and arrays live in memory, where they live, how you can move them around. Then you can use the tools of MATLAB to their fullest potential. This is what makes a language like MATLAB a great one.

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Get Started with MATLAB en Help Center y File Exchange.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by