Put data from user in matrix with loop in matlab - matlab

I'm new in matlab, I've searched a lot but I didn't find my answer. I want to get data from user in a for loop and put that data in matrix. I used this code:
npattern=inputdlg('Enter the number of Patterns');
a=npattern(1,1);
for i=1 : a(1,1);
r=inputdlg('Enter Data');
end
end
But it doesn't work for me. What should I do now?

Assuming your r can contain strings (not just numbers):
npattern=inputdlg('Enter the number of Patterns');
a=str2num(npattern{1});
for ii=1:a;
r{ii}=inputdlg('Enter Data');
end
Comments:
inputdlg returns a cell array of strings
it's bet not to use i as a variable (i is sqrt(-1) by default)
r in your code is overwritten at each iteration. Better use a cell array
there is one end too many

x=inputdlg('Enter the number of Patterns');
data = str2num(x{:});
r = zeros(data, 1);
for i=1:data
x = inputdlg('Enter Data');
r(i, 1) = str2num(x{:});
end

Related

Matlab: use variable with different index in loop

I have big data files with currents and voltages. I measure several times my devices but the number of measurements varies. I first ask the user how many rounds of measurements there are, after which I make a loop to extract the currents from the data. My current variables are arrays of 200x3000 doubles. I call them for example Isd_round1, Isd_round2, etc...
for i=1:rounds_number
[filename,pathname]=uigetfile('*.mat', 'Select matlab data');
pathname = cd(pathname);
pathname = strcat(pathname, '\', filename);
Val=load(pathname);
assignin('base', ['Isd1_round' num2str(i)], Val.Isd1)
...etc...
end
After that, I want to plot and compare the currents, but I cannot seem to find a way to call the variables by changing the index. I would like to do something like this:
figure
hold on
for j=1:rounds_number
plot(V, Isd_roundj)
end
And I don't know how to call the variables by changing the index in the loop.
I could also do an array of all the currents but as each current is already an array of (n, m) doubles, how can I create a variable "current" where I would assign "Isd_round1" ?
I would recommend using a cell array to store the data, as was mentioned before. Here is some example code how, to do this:
dataCell = cell(rounds_number,1)
% read data in
for i=1:rounds_number
[filename,pathname]=uigetfile('*.mat', 'Select matlab data');
pathname = cd(pathname);
pathname = strcat(pathname, '\', filename);
Val=load(pathname);
dataCell{i} =Val
end
%plot
for i=1:rounds_number
plot(dataCell{i})
end
%quicker, warning this plots all rounds at once
cellfun(#(x) plot(x),dataCell)

Naming Image using index of for loop in each iteration

I am working in MATLAB for my image processing project.
I am using a for loop to generate some kind of image data (size of image varies) with each loop iteration. My problem is how do stop it from overwriting the image in next iteration.
Img(i,j)=data
Ideally I would like it to have
Img_1 = data (for 1st iteration)
Img_2 = data (for 2nd iteration)
Img_3 = data (for 3rd iteration)
and so on...
Is there any way, it can be acheived?
Yes, you can use dynamic field names with structures. I wouldn't recommend using separate variable names because your workspace will become unwieldy. Do something like this:
img_struct = struct(); %// Create empty structure
for ii = 1 : num_iterations
%// Do your processing on data
%...
%...
img_struct.(['Img_' num2str(ii)]) = data; %// After iteration
end
This will create a structure called img_struct where it will have fields that are named Img_1, Img_2, etc. To access a particular data from an iteration... say... iteration 1, do:
data = img_struct.Img_1;
Change the _1 to whatever iteration you choose.
Alternatively, you can use cell arrays... same line of thinking:
%// Create empty cell array
img_cell = cell(num_iterations, 1);
for ii = 1 : num_iterations
%// Do your processing on data
%...
%...
img_cell{ii} = data; %// After iteration
end
Cell arrays are arrays that take on any type per element - or they're non-homogeneous arrays. This means that each element can be whatever you want. As such, because your image data varies in size at each iteration, this will do very nicely. To access data at any iteration, simply do:
data = img_cell{ii};
ii is the index of the iteration you want to access.
If you want to literally obtain what you are asking for, you can use the eval() function, which takes a string as input that it will evaluate as if it were a line of code. Example:
for i=1:3
data=ones(i); % assign data, 'ones(i)' used as dummy for test
eval(['Img_' num2str(i) '=data;'])
end
However, I would recommend using cell arrays {}, or alternatively the struct function that rayryeng both suggested.

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

Creating matrix names iteratively in MATLAB and performing operations

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

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