what is the meaning/output of this piece of MATLAB code? - matlab

Can someone explain to me the meaning/significance of this code line by line? I am a beginner in MATLAB/programming so please use simple terminology particularly when explaining the fprintf function. (I tried to use the 'help' function in MATLAB to understand the 'fprintf' function and I still dont understand it... also if its simple enough, what is the expected output?
A = zeros(1,3); %pre-allocate space
k = 1; %count loop iterations
valueMatrix = [1 2 3; 5 6 7];
for jj = valueMatrix
fprintf('iteration %d:\n', k)
A(k) = jj(1) + jj(2);
jj, A %display variables on terminal
k = k + 1;
end

Sure. Let's go through each line of code separately. Bear in mind that I'm answering mainly because the for loop uses a matrix instead of a vector, and not many people know what that actually does.
A = zeros(1,3); %pre-allocate space
This creates an empty vector of three elements and this is stored in A.
k = 1; %count loop iterations
This I will explain later.
valueMatrix = [1 2 3; 5 6 7];
Declare a matrix of size 2 x 3, which looks like this:
1 2 3
5 6 7
for jj = valueMatrix
This is a for loop. I'm assuming you know what that is. for loops allow you to execute a piece of code inside the for syntax a given number of times. You specify a vector or a matrix and the loop executes the piece of code within the for construct again and again... and each time it executes, it pulls each value from the vector or matrix and stores it into a loop counter variable. In this case, that variable is jj. For example, if we did this:
for jj = 1 : 8
disp(jj);
end
This loop will start with jj = 1, and we will display this in the console. Next, we go jj = 2 and we display this in the console and we will keep going until jj = 8 then we stop. Now with a matrix this is slightly different. How it works is that at each iteration, we pull out a column at a time. For example, if we did:
for jj = [1 2 3; 4 5 6; 7 8 9]
disp(jj);
end
We would display:
1
4
7
... at the first iteration, then:
2
5
8
... then finally at the last iteration:
3
6
9
As such, if we did:
for jj = valueMatrix
... this means that we will run this loop three times. At the first iteration, jj would be:
1
5
The next iteration:
2
6
The last iteration:
3
7
What's important is that at each iteration, jj is a 2 element vector.
fprintf('iteration %d:\n', k)
fprintf stands for formatted print to file. However, the way it is being called prints to the screen instead of a text file. This may look unfamiliar to you because this is essentially the same way you'd call printf in C. The first parameter to this function is a string that you want to display to the screen. What you can also do is display the contents of a variable by putting the right specifiers inside the string. You use what are known as formatting strings. In this case, %d specifies an integer you want to print out, and \n means to move to the next line. Each formatting string is accompanied by the variable you want to print. In our case, %d is paired with the variable k, so you want to print out the variable k at each iteration. It would look like this at each iteration:
iteration 1:
iteration 2:
iteration 3:
A(k) = jj(1) + jj(2);
You'll notice that k starts at 1 and increments by 1 each time the loop iterates (the k = k + 1 statement two lines later). Therefore, at each iteration, we populate each entry in A with the addition of the two elements in jj.
jj, A %display variables on terminal
Self-explanatory. We show these variables to the screen, on top of the iteration print out statements... a bit messy IMHO.
k = k + 1;
Talked about this already. Increments at each iteration.
end
End the loop.
Therefore, the expected result that the three element vector stored in A has its contents changed, where each element sums from a column from valueMatrix. As such, for A you should get:
A = [6 8 10];

Related

How do I print values from a loop and see how they're being used in a function in matlab?

I have a main matlab file. The main file accesses several functions. There is a loop in one of the functions and I want to see each part of the loop even though those variables aren't being stored. I am new to matlab and I don't understand whether the inputs are matrices, vectors or elements. How do I do that?
matrix1 = [1 2 3 4; 4 5 6 5; 7 8 1 0;3 5 7 6]
list1 = [1;3;5;4]
i=0
for a=1:1:4 %no. of rows
for b=2:1:4 % no. of col
x=matrix1(a,b);
s=1
n3=list1(a,1); %vector
mult=(s.*sin(i)./n3);
end
end
This is a part of a function that the main file calls. x, n3, mult are all being used but none of them are being saved. How can I see what these values are?

Build the matrix of all the combinations of given numbers using recursion [matlab]

Let say we have the vector v=[1,2,3] and we want to build the matrix of all the combinations of the numbers contained in v, i.e.
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
Since I'm not good in recursion, firstly I tried to write the code to build such a matrix by using for loops
makeLoop([1,2,3])
function A = makeLoop(v)
loops=length(v);
for i = 1:loops
dummy=v;
m=factorial(loops)/loops;
A((1+m*(i-1)):m*i,1)=v(i);
v(i)=[];
loops2=length(v);
for j = 1:loops2
dummy2=v;
m2=factorial(loops2)/loops2;
A(((1+m2*(j-1))+m*(i-1)):(m2*j+m*(i-1)),2)=v(j);
v(j)=[];
loops3=length(v);
for k = 1:loops3
m3=factorial(loops3)/loops3;
A(((1+m2*(j-1))+m*(i-1)):(m2*j+m*(i-1)),3)=v(k);
end
v=dummy2;
end
v=dummy;
end
end
it seems like it work, but obviously write it all for a bigger v would be like hell. Anyway I don't understand how to properly write the recursion, I think the recursive structure will be something like this
function A = makeLoop(v)
if length(v)==1
"do the last for loop"
else
"do a regular loop and call makeLoop(v) (v shrink at each loop)"
end
but I don't get which parts should I remove from the original code, and which to keep.
You were very close! The overall structure that you proposed is sound and your loopy-code can be inserted into it with practically no changes:
function A = makeLoop(v)
% number of (remaining) elements in the vector
loops = length(v);
if loops==1 %"do the last for loop"
A = v; %Obviously, if you input only a single number, the output has to be that number
else %"do a regular loop and call makeLoop(v) (v shrink at each loop)"
%preallocate matrix to store results
A = zeros(factorial(loops),loops);
%number of results per vector element
m = factorial(loops)/loops;
for i = 1:loops
%For each element of the vector, call the function again with that element missing.
dummy = v;
dummy(i) = [];
AOut = makeLoop(dummy);
%Then add that element back to the beginning of the output and store it.
A((1+m*(i-1)):m*i,:) = [bsxfun(#times,v(i),ones(m,1)) AOut];
end
end
Explanation bsxfun() line:
First, read the bsxfun documentation, it explains how it works way better than I could. But long story short, with bsxfun() we can replicate a scalar easily by multiplying it with a column vector of ones. E.g. bsxfun(#times,5,[1;1;1]) will result in the vector [5;5;5]. Note that since Matlab 2016b, bsxfun(#times,5,[1;1;1]) can written shorter as 5.*[1;1;1]
To the task at hand, we want to add v(i) in front (as the first column) of all permutations that may occur after it. Therefore we need to replicate the v(i) into the 1. dimension to match the number of rows of AOut, which is done with bsxfun(#times,v(i),ones(m,1)). Then we just horizontally concatenate this with AOut.
You can simply use the perms function to achieve this:
v = [1 2 3];
perms(v)
ans =
3 2 1
3 1 2
2 3 1
2 1 3
1 3 2
1 2 3
If you want them sorted using the same criterion you applied in the desired output, use the following code (refer to this page for an official documentation of the sortrows functon):
v = [1 2 3];
p = perms(v);
p = sortrows(p)
p =
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

Matlab: How do I use two nested for-loops to generate a consecutive list of numbers in ascending order?

I would like to obtain an array of consecutive numbers from 1 to the product of the limits of two nested loops. I hope the example below will clarify the question. If I have the nested loop:
for i = 1:limit_loop_1
for j = 1:limit_loop_2
a = ???;
disp(a)
end
end
I would like to obtain a = (1:(limit_loop_1*limit_loop_2))'
For example, having:
for i = 1:3
for j = 1:5
a = ????;
disp(a)
end
end
I would like to get:
a=
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
I found similar questions for Java (like here), but nothing for Matlab. Thanks in advance.
Edit: I need this particular procedure because I will use the index to refer to another array. So, if I have for example a 3D array A of size (100,1,15) within the nested loops, I want to consider each one of the 15 elements of the array at each iteration. In code this would be:
for k = 1:100
for i = 1:3
for j = 1:5
something = A (k,1,????)
end
end
end
That is why ????? should go from 1 to 15. Hope this clarify my issue.
Obviously the solution you already provided (a = (1:(limit_loop_1*limit_loop_2))') is correct and absolutely nice. However if you must use a nested loop, just treat a as an external counter
a=0;
for i = 1:3
for j = 1:5
a = a+1;
disp(a)
end
end
This basically counts how many iteration are made by using the nested loop (3*5 in this case).
Or if you want to exploit the indices i and j you can re-adapt the Java example in Matlab by taking into account that in Matlab the indices start at 1 whereas in Java they start at 0:
for i = 1:3
for j = 1:5
c =1+(j-1)*1+(i-1)*(5);
disp(c)
end
end
I have no idea why you'd want to do it this way, but I'll take you at your word. This will give you the results you require:
for ii = 1:3
for jj = 1:5
a = 5*(ii-1)+jj;
disp(a)
end
end
(I changed your loop variables from i and j because they're the imaginary unit variables by default, and some folks get upset if you overwrite them.)
Results:
>> loop15
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

Save to array in for loop, with steps - Matlab

Okay, this is a bit tricky to explain, but I have a long .txt file with data (only one column). It could look like this:
data=[18
32
50
3
19
31
48
2
18
33
51
4]
Now, every fourth value (e.g. 18, 19, 18) represents the same physical quantity, just from different measurements. Now, I want Matlab to take every fourth value and put it into an array X=[18 19 18], and like wise for the other quantities.
My solution so far looks like this:
for i=1:3;
for j=1:4:12;
X(i)=data(j);
end
end
... in this example, because there are three of each quantity (therefore i=1:3), and there are 12 datapoints in total (therefore j=1:4:12, in steps of 4). data is simply the loaded list of datapoints (this works fine, I can test it in command window - e.g. data(2)=32).
My problem, doing this, is, that my array turns out like X=[18 18 18] - i.e. only the last iteration is put into the array
Of course, in the end, I would like to do it for all points; saving the 2nd, 6th, and 10th datapoint into Y and so on. But this is simply having more for-loops I guess.
I hope this question makes sense. I guess it is an easy problem to solve.
Why don't you just do?
>> X = data(1:4:end)
X =
18
19
18
>> Y = data(2:4:end)
Y =
32
31
33
You can reshape the data and then either split it up into different variables or just know that each column is a different variable (I'm now assuming each measurement occurs the same number of times i.e. length(data) is a multiple of 4)
data = reshape(data, 4, []).';
So now if you want
X = data(:,1);
Y = data(:,2);
%// etc...
But also you could just leave it as data all in one variable since calling data(:,1) is hardly more hassle than X.
Now, you should NOT use for-loops for this, but I'm gong to address what's wrong with your loops and how to solve this using loops purely as an explanation of the logic. You have a nested loop:
for i=1:3;
for j=1:4:12;
X(i)=data(j);
end
end
Now what you were hoping was that i and j would each move one iteration forward together. So when i==1 then j==1, when i==2 then j==5 etc but this is not what happens at all. To best understand what's going on I suggest you print out the variables at each iteration:
disp(sprintf('i: \tj:'));
for i=1:3;
for j=1:4:12;
disp(sprintf(' %d\t %d',i,j));
end
end
This prints out
i: j:
1 1
1 5
1 9
2 1
2 5
2 9
3 1
3 5
3 9
What you wanted was
disp(sprintf('i: \tj:'));
for i=1:3;
disp(sprintf(' %d\t %d',i,4*i-3));
end
which outputs:
i: j:
1 1
2 5
3 9
applied to your problem:
%// preallocation!
X = zeros(size(data,1)/4, 1)
for i=1:3
X(i)=data(i*4 - 3);
end
Or alternatively you can keep a separate count of either i or j:
%// preallocation!
X = zeros(size(data,1)/4, 1)
i = 1;
for j=1:4:end;
X(i)=data(j);
i = i+1;
end
Just for completeness your own solution should have read
i = 0;
for j=1:4:12;
i = i+1;
X(i)=data(j);
end
Of course am304's answer is a better way of doing it.

How can I shift array element using a for loop in Matlab?

I'm trying to shift all the elements of an array to the left, so that the first element would become the last element, the second becomes the first, the third the second, etc. I know about the circshift commands, but I would like to do this using a for loop.
Here's what I did.
old=[]
n=length(old)
for i=1;i<(n-1);i=i+1;
for j=2;j<n;j=j+1;
new(j)=old(i)
end
end
But it of course didn't work. I'm having trouble figuring out to make an array of n elements, without specifying n, which is why I used old=[], but I think that created an array of 0 elements.
How can I make this code work?
If you want to avoid specifying the n length of the array, you have to give it as an input argument in a function.
For example you can do something like this:
function new = shiftLeft(old)
n = length(old);
for i =1:n
new(i) = old(mod(i,n)+1);
end
return
So with this one, if you have an array for example old = [1 2 3 4]; you can will get something like new = [2 3 4 1];
mod(a,b) is the modulo operator, you can find more information if you type help mod.
So your irst step is to learn how to specify a for loop in Matlab, what you have is like C syntax. This is not Matlab syntax at all.
The following is how to do it using forloops but this is not good matlab programming. You could easily do it without loops too.
vec = 1:10;
temp = [];
shiftby = 2;
for ii = 1:shiftby %Each iteration shifts by one
temp = vec(end); %Store the last element of vec
for jj = size(vec, 2):-1:2; %inner loop must shift each element from the end to element 2
vec(jj) = vec(jj-1);
end
vec(1) = temp; %put the old end value at the beginning
end
but you could also just do this which is a much more Matlabesque way to code it:
vec = [vec(end - shiftby + 1: end), vec(1:end - shiftby)]