Looping through columns and rows without using Indexing in matlab - matlab

I'm fairly new to matlab and I'm currently working on MATLAB to create a loop that will go through each column and each row and then increment A and B as it goes. I know that there's indexing which you can do but I'd like to learn how to do it step by step. I've come up with the pseudo code for it but I'm struggling with the actual syntax in MATLAB to be able to do it.
Pseudocode:
For columns i 1-300;
Increment A
For rows j 1-4
Increment B
End
End
My actual code that I've been trying to get to work is:
%testmatrix = 4:300 Already defined earlier as a 4 row and 300 column matrix
for i = testmatrix (:,300)
for j = testmatrix (4,:)
B=B+1
end
A=A+1
end
I'm not 100% sure how I'm supposed to format the code so it'll read testmatrix(1,1) all the way through to testmatrix (4,300).
Any help would be greatly appreciated!

You could let it run through the first row to get the right column, then through that column. But you can't feed your running value from the matrix:
[rows cols] = size(testmatrix); %// rows=4, cols=300
for i = 1:cols
for j = 1:rows
temp = testmatrix (j,i); %// contains the element of your matrix at (j,i)
B=B+1;
end
A=A+1;
end
The semicolons ; suppress the output to the command line. Remove them if you want to output A and B at each step.
Here, temp will cycle through the elements (1,1) through (4,300) and you can do whatever you want with them. Note that this is generally an inefficient way to do most things. Matlab supports greatly efficient vectorized calculations, which you should use. But unless I know what exactly you're trying to achieve, I can't really help you with that. (If all you want is A and B's final values, it's as easy as A=A+cols;B=B+cols*rows;.)

Related

Find the Start Index and End Index of the same Element in a Matrix in Matlab

I want to get the start index and end Index of the same repetitive Element in a matrix?
for example this Matrix:
the result will be:
zero is not considered
You can go this way (example for 1):
a = rem(find(A==1),5)
a(a==0)=5;
startidx = min(a)
endidx = max(a)
The same way change A==1 to whatever you need and you'll get the result. You also can create a function with parameters A, number_you_want_to_find.
There are some ways to improve this code, for example instead 5 use size(A,1) and maybe there is some way to replace all this code with one line, but this works too!
Hope, it was helpful!

Error with code when run in a loop but none when run outside a loop

Hi and thank you for viewing my question.
I have a large spreadsheet (over 650,000 rows) that I am trying to spit up into separate parts of a structure. I am trying to split it up by the values in one of the columns of which there is 1132 unique text values. The rest of the columns are numerical. I have created a matrix of the numerical values with 4 columns called 'SectionID_Matrix' and a cell array for the text column I want to split the data up by called 'ELR'. I am also trying to name the parts in the structure by the text value I have split them up by. My code is as follows:
ELR_list = unique (ELR);
[m,~]=size(ELR_list);
n = 1;
b = [];
for j = 1:m
x = strcmp(ELR_list(n), char(ELR));
b(:,1) = SectionID_Matrix(x(:,1),1);
b(:,2) = SectionID_Matrix(x(:,1),2);
b(:,3) = SectionID_Matrix(x(:,1),3);
b(:,4) = SectionID_Matrix(x(:,1),4);
t = char(ELR_list(n));
s.(t) = b;
n = n+1;
end
clearvars -except *ELR_list* *ELR* *SectionID_Matrix* *s*
When I run this code though I get an error saying 'Subscripted assignment dimension mismatch'. Error in Sorting_Out_Locations (line 10). b(:,1) = SectionID_Matrix(x(:,1),1);
This is confusing me because when I remove the for loop and manually change the value of n, it works perfectly fine giving me a matrix in the structure with all the rows that contain the nth text value with the name of the text value.
I understand the error is caused by attempting to assign more elements to a section of a matrix or vector than that section can hold but I don't understand where that is happening.
Is there an error in my code that is causing the for loop to fail? because from my limited understanding the loop should just keep going around increase n by 1 each time until it has gone through all of the unique ELR values.
This is my very first time on Matlab (so any pointer on my code are very appreciated) and have spend all afternoon trying to get this working but no amount of internet help or the matlab website is helping.
Thank you for any help
In your code, the first time it runs through the loop, the size of the b matrix is set according to the number of true values in x. The next time it runs through the loop, that may be a different size, so you get the mismatch.
You can just clear b at the end of each loop iteration with b = []
The error Subscripted assignment dimension mismatch appears when you try to insert a matrix of a certain size into a matrix of a different size. For your code, it means that in the line
b(:,1) = SectionID_Matrix(x(:,1),1);
there is an attempted insertion of mismatching sizes: the size of SectionID_Matrix(x(:,1),1) and the size of b(:,1) are not the same. This is most likely because you only take certain values of each column of SectionID_Matrix using the logical indexing of x. To fix this you need the same logical indexing in b:
b(x(:,1),1) = SectionID_Matrix(x(:,1),1);

How to write a sparse matrix to a text file

I want to write a sparse matrix to a text file. Let's say my sparse matrix is A.The first row of A has non zero values at 10,11th index. The second row has non zero values at 1,2nd index. Then when I write the data to a text file it should look something like this
10 11
1 2
......
....
How can I do this in MATLAB?
First post, so not sure if posting code is allowed, but maybe this is what you're looking for?
[rows, cols] = size(A);
outFile = fopen('sparse.txt', 'a');
for m = 1:rows
n = 1;
while n <= cols
if A(m, n) ~= 0
fprintf(outFile, '%d ', A(m, n));
end
n = n+1;
end
fprintf(outFile, '\r\n');
end
Given the constraints, I only really see one sensible option for the given format:
f = fopen('out.txt', 'w');
for ii=1:size(mat, 1)
fprintf(f, '%u ', find(mat(ii, :));
fprintf(f, '\n');
end
fclose(f);
Since the number of elements per row isn't constant, this means two things:
We can't construct a single matrix to pass to a vectorised function, so we're stuck with some form of per-row operation.
We also can't give fprintf a constant format string to write one or more whole rows in a single call, so we're stuck with multiple fprintf calls.
So, optimising for those constraints;
Iterate over the rows directly - yes, we could pull out the row and column indices all at once with find, but then we've wasted memory effectively copying the entire dataset, and we'd still have to iterate over that somehow.
Minimise the amount of high-level work - let the low-level internals of find and vectorised fprintf at least make processing a single row as quick as feasibly possible.
Sometimes a simple loop really is the best option - it's liable to be I/O-bound anyway, so the overhead of the loop itself really should be negligible compared to even the minimal number of fprintf calls.

How to add elements to a vector in matlab

I've looked around on the internet a bit and cannot seem to find the answer to this question. I want to declare a vector in matlab and then have a for loop that will add an element to the vector each time I go through the for loop.
This is what I've tried and it doesn't seem to be working
vector[];
for k = 1 ; 10
%calculate some value
%calculated value stored in temp variable
vector(k) = temp;
end
This does not work. Does anybody know how to solve this issue?
As ypnos said, you don't need to declare the vector variable upfront. For example if you did:
vector(50) = 1;
MATLAB would make a vector of length 50 with the 50th value being 1. If you want to improve performance and want to create a vector of the proper size beforehand then do the following:
vector = zeros(10, 1);
The code as you have it (as long as you fix the loop as ypnos said) will work, except for how you declare vector, which is not correct. I bet you are getting the error message: "Error: Unbalanced or unexpected parenthesis or bracket." You do not specify whether a variable is a matrix/vector in MATLAB.
vector = [vector; temp];
or
vector(end+1) = temp;

Extract parts of a big matrix and allocate them in new variables with loop function

I am a total beginner in MATLAB and I hope to find some help here. I have some model prediction results for 80 individuals alltogether in one large matrix. I need to extract the data for each individual from the big matrix, assign them in a new variable/matrix, do some extra calculations and then plot certain information as needed.
To do so, I am trying to write a script with a loop function but in a complicated, or maybe more accurately: in a primitive way!
Simplified Example:
My matrix is called: All_Indi_Data .... its dimension is: 600 rows x 21 columns
%Column 1: grouping variable (e.g., code or ID with values 1,2,3,4,5, etc.);
%Column 2: independent var.;
%Column 3: t;
%Column 4: OBS;
%Column 5: PRED;
i= length (All_Indi_Data);
%% First Indi.
q=1; % indicating the ID of the indi for which I want to extract the data
j=1; % variable added to insure writing start from the first row
for r=1:i
if All_Indi_Data (r,1)==q
Indi_1 (j,1:21) = All_Indi_Data (r,1:21)
j=j+1
end
end
%% Second Indi.
q=q+1
j=1
for r=1:i
if All_Indi_Data (r,1)==q
Indi_2 (j,1:21) = All_Indi_Data (r,1:21)
j=j+1
end
end
.
.
.
1) My first question is: can I allocate these data in new variables (Indi_1, Indi_2, ect.) in a more simple way with or without the loop function?!!! I would appreciate your help a lot.
2) Is there any code or any way to plot these selected parts (according to the grouping variable, e.g. data for Indi_1) from the previously mentioned big matrix without wasting a lot of time and space (wto recopying the core part of the code again and again) for the script, and using the loop function?! in other words, I would like to detect - with loop function & the grouping variable- which values are of interest and then to plot them (e.g. data in colum 3 with data from column 4 for each individual, starting from the first to the last)?!
I hope that I described my problem clearly and hope to hear something from the expert guys :) ...
Thanks a lot in advance ..
Try the following code:
for idx=1:80
pos=find(All_Indi_Data(:,1)==idx);
eval(['Indi_' num2str(idx) '=All_Indi_Data(pos,:);']);
end
What I do is: in each iteration, I search for a value of the ID, indicated in the variable idx. Note that I do not use ´i´ as the name of a variable, because Matlab uses it and ´j´ and the imaginary unit for complex numbers and that could cause problems.
Then, using find I search for the position (or positions) of All_Indi_Data in which I can find the information of that individual. Now I have in the variable ´pos´ the indexes of the rows in which there is information for the individual of interest.
Finally, using eval I extract the data for each individual into a variable. Note that eval combined with a loop makes it easy to create lots of variables. I indicate the rows I want to extract with ´pos´ and, as I want all the columns, I use just ´:´ (you could use ´1:21´ too).
With another similar loop you can plot the information you want. For example:
for idx=1:80
eval(['x=Indi_' num2str(idx) ';']);
% Now I have in X the information for this individual
%Plot the columns of x I want
plot(x(:, 3), x(:,4));
pause; %stay here until a press a key
end