Collect response value with two for loops nested
2 views (last 30 days)
Show older comments
Hello everybody 'I'm new and this is my first approach to matlab, I have a matrix problem; maybe it is trivial but I have tried to search for it and couldn't find anything useful. This is a simplified version of my code. I used psychtoolbox to present visual stimuli and i want that, for each block, it shows the same number of trials in the right side of the screen and then in the left one. For each side I need it to record the response (the key pressed, the reaction time and other information). I was able to concatenate in horizontal the two matrix "left and right", but when the program saves my results it only keeps the last "block" of results( when you run it creates a response matrix 5x4 and not a 20x4 one). Can someone please help me to concatenate in vertical the results in a single matrix? Thank you in advance I hope I made myself clear
Cheers
numBlocks=4;
dx=2;
sx=1;%1=dx 0=sx
side=repmat( [ dx sx],numBlocks, 1);%1=dx 0=sx
numTrials=5;
responsesDx= zeros(numTrials,2);
responsesSx= zeros(numTrials,2);
responses=zeros(numTrials*numBlocks,4);
for i=1:numBlocks %how many time it has to repeat the loop
for j=1:size(side,2)
if j==side(sx)
for j=1:numTrials
key_pressed= 3;
reaction_time=5;
responsesDx(j,1)= key_pressed;
responsesDx(j,2)= reaction_time;
end
else
for j=1:numTrials
key_prressed= 4;
reaction_time=6;
responsesSx(j,1)= key_pressed;
responsesSx(j,2)= reaction_time;
end
end
responses=[ responsesDx responsesSx];
end
end
2 Comments
Andy L
on 11 Aug 2014
First of all I noticed that in your second loop key_pressed is spelt key_prressed - is this ok? Also Have you tried sticking a keyboard into your loop to test why it isn't behaving as you expect? This pauses the program each time it comes to that line, allowing you to see what the values are on each iteration and help with your debug. The program resumes execution when you type continue in the workspace.
Accepted Answer
Andy L
on 11 Aug 2014
Edited: Andy L
on 11 Aug 2014
It is only in the loops that the variable responses is changed to 5 x 4. If we deconstruct your code...
numBlocks = 4;
dx = 2;
sx = 1; %1=dx 0=sx
side = repmat( [ dx sx],numBlocks, 1); % 1 = dx 0 = sx
numTrials = 5;
responsesDx = zeros(numTrials,2);
responsesSx = zeros(numTrials,2);
responses = zeros(numTrials*numBlocks,4);
- responsesDx (5 x 2)
- responsesSx (5 x 2)
- responses (20 x 4)
for i = 1:numBlocks % for i = 1:4.
for j = 1:size(side,2) % size(side,2) = 2.
if j == side(sx) % logical indexing, sx = 1, side(1) = 2.
for j = 1:numTrials
j has now been reset to 1, and will be 5 when it exits this loop - suggest a new indexing variable here!
key_pressed = 3;
reaction_time = 5;
responsesDx(j,1) = key_pressed;
responsesDx(j,2) = reaction_time;
end
When this loop has completed, responsesDx/Sx are 5 x 1.
else
for j = 1:numTrials
j has now been reset to 1, and will be 5 when it exits this loop - suggest a new indexing variable here!
key_pressed = 4;
reaction_time = 6;
responsesSx(j,1) = key_pressed;
responsesSx(j,2) = reaction_time;
end
When this loop has completed, responsesDx/Sx are 5 x 1.
end
responses = [ responsesDx responsesSx];
responses is not indexed and so is rewritten on each loop. This is why your code provides you a 5x4 output. I would use a separate variable (block response) here, that then feeds into responses outside this loop.
end
end
Try the loop below!
for i = 1:numBlocks % how many time it has to repeat the loop
for j = 1:size(side,2)
if j == side(sx)
for k = 1:numTrials
key_pressed = 3;
reaction_time = 5;
responsesDx(k,1) = key_pressed;
responsesDx(k,2) = reaction_time;
end
else
for k = 1:numTrials
key_pressed = 4;
reaction_time = 6;
responsesSx(k,1) = key_pressed;
responsesSx(k,2) = reaction_time;
end
end
blockResponse = [responsesDx responsesSx];
end
p = ((i-1)*numTrials) + 1;
disp(['iteration ',num2str(i)]);
responses(p:p+4,:) = blockResponse
end
2 Comments
Andy L
on 12 Aug 2014
Edited: Andy L
on 12 Aug 2014
Not a problem Alice!
Your Matrix responses is already defined as a 20x4 matrix of zeros. At the end of each loop, blockResponse is a 5x4 matrix made up of two 5x2 matrices. The variable p is calculated to find out which area of the matrix responses, blockResponse should be written to - it is your index variable.
responses(p:p+4,:)
is just a 5x4 area of the matrix responses that is being written to on each loop. (The colon operator is used to index for all columns - can also be used for rows).
Lets look at the first two iterations:
p = ((i-1)*numTrials) + 1;
%%Loop 1
% numTrials = 5; (fixed in this case)
% i = 1;
% p = ((1-1)*5) + 1
% = 1;
% p+4 = 5;
% responses(1:5,:) = blockResponse;
%%Loop 2
% i = 2;
% p = ((2-1)*5) + 1
% = 6;
% p+4 = 10;
% responses(6:10,:) = blockResponse;
and so on.
However, upon thinking about it, it would be more appropriate to index as such:
p_end = p +(numTrials-1);
responses(p:p_end,:) = blockResponse;
This will account for different lengths of numTrials - which is intrinsically linked to the size of blockResponse .
I hope this is helpful in clearing things up?
More Answers (1)
Iain
on 11 Aug 2014
Change:
responsesDx= zeros(numTrials,2);
responsesSx= zeros(numTrials,2);
responses=zeros(numTrials*numBlocks,4);
responsesDx(j,1)= key_pressed;
responsesDx(j,2)= reaction_time;
(and the like)
to
responsesDx= zeros(numBlocks,numTrials,2);
responsesSx= zeros(numBlocks,numTrials,2);
responses=zeros(numBlocks,numTrials,4);
responsesDx(i,j,1)= key_pressed;
responsesDx(i,j,2)= reaction_time;
(and the like)
3 Comments
Iain
on 11 Aug 2014
Ok, then, your answer is to either reshape (and or permute) the output of what I suggested into what you want, or you simply need to retune the indexing to include i & j, like (i-1)*maxj + j
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!