Creating matrix names iteratively in MATLAB and performing operations - matlab

I have a 3-Dimensional matrix K(i,j,l). I would like to create a new matrices from K, which would be a slice for each value of i. I also have to transpose the newly formed 2-D matrix.
for l=1:40
for j=1:15
K1(l,j)=K(1,j,l);
K2(l,j)=K(2,j,l);
.
.
.
K35(l,j)=K(35,j,l);
end;
end;
I want to create another loop where the names of new matrices are created within the loop.
i.e.;
K1(l,j)=K(1,j,l) (when i=1)
K2(l,j)=K(2,j,l) when i=2...
The problem that I faced is that I cannot seem to iteratively name of the matrices (K1,K2...K35) with in the loop and at the same time perform the dimension change operation. I tried num2str, sprintf, but they don't seem to work for some reason. If any of you have an idea, please let me know. Thanks!

I don't understand why you want to assign different names to your matrices. Can't you just store them in a cell like this:
K = cell(35, 1);
for ii=1:35
K{ii} = squeeze(K_DEA(ii, :, :))';
end
Otherwise, if you really need to have different names, then do this:
K = cell(35, 1);
for ii=1:35
eval(sprintf('K%d = squeeze(K_DEA(ii, :, :))'';', ii));
end

If I understand your question correctly, following should solve your problem:
K1=squeeze(K(1,:,:))';
K2=squeeze(K(2,:,:))';
.
.
.
K35=squeeze(K(35,:,:))';
For looping over i=1:35
for i=1:35
name = sprintf("K%d",i);
A = squeeze(K(i,:,:))';
eval([name ' = A']);
end
Or more concisely,
for i=1:35
eval([sprintf("K%d = squeeze(K(i,:,:))'",i)]);
end

Related

How to save matrixes as a vector

I have a text file that is a matrix 2819x10.
I have splited it into 5x5x563 matrix using code below
Matrix = dlmread('det.txt');
for j=1:1:563
for i=1:1:5
M(i,1,j) = Matrix(temp,3);
M(i,2,j)= Matrix(temp,4);
M(i,3,j)= Matrix(temp,5);
M(i,4,j) = Matrix(temp,6);
M(i,5,j) = 1;
temp=temp+1;
end
end
After this code I have Matrix 5x5x563. Right now I would like to to create a array like is presented bellow, that consist only one row, and each column is my matrix of 5x5.
I have tried with mat2cell:
MatrixNew= mat2cell(M, 5, 5);
But I have still an error. I dont have clue how to fix it. I am not try to find a ready code but just advice.
How can I accomplish this?
I think reshape should do the job for you. For example:
x=reshape(M,[1 5*5*563]);
or you can use other variations of the reshape function by playing around with it.

Using loops to get multiple values into a cell

I have 31 subjects (S1, S2, S3, S4, etc.). Each subject has 3 images, contrast1.img, contrast2.img, and contrast3.img. I would like to use a loop to get all paths to the contrasts from all the subjects into a nx1 cell called P. P should be something like this:
Data/S1/contrast1.img
Data/S1/contrast2.img
Data/S1/contrast3.img
Data/S2/contrast1.img
Data/S2/contrast2.img
Data/S2/contrast3.img
...
Data/S31/contast3.img
This is what I've tried:
A={'S1','S2','S3',...,'S31'}; % all the subjects
C={'contrast1.img','contrast2.img','contrast3.img'}; % contrast images needed for each subject
P=cell(31*3,1)
for i=1:length(A)
for j=1:length(C)
P{j}=spm_select('FPList', fullfile(data_path, Q{i}) sprintf('%s',cell2mat(C(j)))); % this is to select the three contrast images for each subject. It works in my script. It might not be 100% correct here since I had to simplify for this example.
end
end
This, however, only give me P with the 3 contrast images of the last subject. Previous subjects get overwritten. This indicates that the loop is wrong but I'm not sure how to fix it. Could anyone help?
No loop needed. Use ndgrid to generate the combinations of numbers, num2str with left alignment to convert to strings, and strcat to concatenate without trailing spaces:
M = 31;
N = 3;
[jj ii] = ndgrid(1:N, 1:M);
P = strcat('Data/S',num2str(ii(:),'%-i'),'/contrast',num2str(jj(:),'%-i'),'.img')
I would use a cell matrix, which directly represents the subject index and the contrast index.
To preallocate use P=cell(length(A),length(C)) and to fill it use P{i,j}=...
When you want to access the 3rd image of the 5th subject, use P{5,3}
The problem is where you assign P{j}.
Since j only loops 1:3 and doesn't care about i, you are just rewriting all three values for P{j}. I think you want to concatenate the new values to the cell array instead
for i=1:length(A)
for j=1:length(C)
P ={P; spm_select('FPList', fullfile(data_path, Q{i}) sprintf('%s',cell2mat(C(j))));}
end
end
or you could assign each value directly such as
for i=1:length(A)
for j=1:length(C)
P{3*(i-1)+j} =spm_select('FPList', fullfile(data_path, Q{i}) sprintf('%s',cell2mat(C(j))));
end
end

Foreach loop problems in MATLAB

I have the following piece of code:
for query = queryFiles
queryImage = imread(strcat('Queries/', query));
queryImage = im2single(rgb2gray(queryImage));
[qf,qd] = vl_covdet(queryImage, opts{:}) ;
for databaseEntry = databaseFiles
entryImage = imread(databaseEntry.name);
entryImage = im2single(rgb2gray(entryImage));
[df,dd] = vl_covdet(entryImage, opts{:}) ;
[matches, H] = matchFeatures(qf,qf,df,dd) ;
result = [result; query, databaseEntry, length(matches)];
end
end
It is my understanding that it should work as a Java/C++ for(query:queryFiles), however the query appears to be a copy of the queryFiles. How do I iterate through this vector normally?
I managed to sort the problem out. It was mainly to my MATLAB ignorance. I wasn't aware of cell arrays and that's the reason I had this problem. That and the required transposition.
From your code it appears that queryFiles is a numeric vector. Maybe it's a column vector? In that case you should convert it into a row:
for query = queryFiles.'
This is because the for loop in Matlab picks a column at each iteration. If your vector is a single column, it picks the whole vector in just one iteration.
In MATLAB, the for construct expects a row vector as input:
for ii = 1:5
will work (loops 5 times with ii = 1, 2, ...)
x = 1:5;
for ii = x
works the same way
However, when you have something other than a row vector, you would simply get a copy (or a column of data at a time).
To help you better, you need to tell us what the data type of queryFiles is. I am guessing it might be a cell array of strings since you are concatenating with a file path (look at fullfile function for the "right" way to do this). If so, then a "safe" approach is:
for ii = 1:numel(queryFiles)
query = queryFiles{ii}; % or queryFiles(ii)
It is often helpful to know what loop number you are in, and in this case ii provides that count for you. This approach is robust even when you don't know ahead of time what the shape of queryFiles is.
Here is how you can loop over all elements in queryFiles, this works for scalars, row vectors, column vectors and even high dimensional matrices:
for query = queryFiles(:)'
% Do stuff
end
Is queryFiles a cell array? The safest way to do this is to use an index:
for i = 1:numel(queryFiles)
query = queryFiles{i};
...
end

copy certain rows in a new matrix within a loop

I'm trying to split a matrix in smaller matrices depending on one characteristic (i use 'if').
for jj = 1:length(FailureHoopUP_sorted)
if FailureHoopUP_sorted(jj,1)==20
FailureHoopUP_20(jj,:) = FailureHoopUP_sorted(jj,:);
elseif FailureHoopUP_sorted(jj,1)==30
FailureHoopUP_30(jj,:) = FailureHoopUP_sorted(jj,:);
else
FailureHoopUP_40(jj,:) = FailureHoopUP_sorted(jj,:);
end
end
The problem I have is that there are rows of zeroes that get in between the rows with data in the new created matrices.
I was wondering how i could avoid this?
Thank you for your help.
You don't need a loop, you can use logical indexing. For example:
FailureHoopUP_20=FailureHoopUP_sorted(FailureHoopUP_sorted(:,1)==20,:)
...
...
This should also solve the zeros issue (that happens because you keep the original index jj that is related to the length of FailureHoopUP_sorted).

How can I create/process variables in a loop in MATLAB?

I need to calculate the mean, standard deviation, and other values for a number of variables and I was wondering how to use a loop to my advantage. I have 5 electrodes of data. So to calculate the mean of each I do this:
mean_ch1 = mean(ch1);
mean_ch2 = mean(ch2);
mean_ch3 = mean(ch3);
mean_ch4 = mean(ch4);
mean_ch5 = mean(ch5);
What I want is to be able to condense that code into a line or so. The code I tried does not work:
for i = 1:5
mean_ch(i) = mean(ch(i));
end
I know this code is wrong but it conveys the idea of what I'm trying to accomplish. I want to end up with 5 separate variables that are named by the loop or a cell array with all 5 variables within it allowing for easy recall. I know there must be a way to write this code I'm just not sure how to accomplish it.
You have a few options for how you can do this:
You can put all your channel data into one large matrix first, then compute the mean of the rows or columns using the function MEAN. For example, if each chX variable is an N-by-1 array, you can do the following:
chArray = [ch1 ch2 ch3 ch4 ch5]; %# Make an N-by-5 matrix
meanArray = mean(chArray); %# Take the mean of each column
You can put all your channel data into a cell array first, then compute the mean of each cell using the function CELLFUN:
meanArray = cellfun(#mean,{ch1,ch2,ch3,ch4,ch5});
This would work even if each chX array is a different length from one another.
You can use EVAL to generate the separate variables for each channel mean:
for iChannel = 1:5
varName = ['ch' int2str(iChannel)]; %# Create the name string
eval(['mean_' varName ' = mean(' varName ');']);
end
If it's always exactly 5 channels, you can do
ch = {ch1, ch2, ch3, ch4, ch5}
for j = 1:5
mean_ch(j) = mean(ch{j});
end
A more complicated way would be
for j = 1:nchannels
mean_ch(j) = eval(['mean(ch' num2str(j) ')']);
end
Apart from gnovice's answer. You could use structures and dynamic field names to accomplish your task. First I assume that your channel data variables are all in the format ch* and are the only variables in your MATLAB workspace. The you could do something like the following
%# Move the channel data into a structure with fields ch1, ch2, ....
%# This could be done by saving and reloading the workspace
save('channelData.mat','ch*');
chanData = load('channelData.mat');
%# Next you can then loop through the structure calculating the mean for each channel
flds = fieldnames(chanData); %# get the fieldnames stored in the structure
for i=1:length(flds)
mean_ch(i) = mean(chanData.(flds{i});
end