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

indexindexingrandom number generator

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

Best Answer

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.