Saving data generated at each iteration in multidimensional array in MATLAB - matlab

I have this code:
for h= 1:length ( bb1{CH(i)})
for k= 1:length( bb2{CH(j)})
if NN(bb1{CH(i)}(h),bb2{CH(j)}(k))==1
d = [bb1{CH(i)}(h),bb2{CH(j)}(k)]
end
end
end
When I run this code, the value of d takes the value of the last iteration. I want to save its value for all the iterations. For example, I want to have a rows_nb by 2 matrix.

This is highly unoptimized code, but the reason is pretty obvious. Your code is assigning to d at every iteration in that code and it keeps overwriting itself.
As such, you need to append to d if you want to save all of the values in the matrix. Therefore, do this:
for h= 1:length ( bb1{CH(i)})
for k= 1:length( bb2{CH(j)})
if NN(bb1{CH(i)}(h),bb2{CH(j)}(k))==1
d = [d; bb1{CH(i)}(h),bb2{CH(j)}(k)]; %// Concatenate
end
end
end
This way, you are adding two columns every time to the matrix and add an additional row at each iteration.

Related

How to avoid element being overwritten by second loop?

I want to generate an array using two loops and a given equation. In my code, the first for-loop overwrites each time the elements that were generated in the previous run. My array ends up having only the last set of elements (for a=9). Here is the code:
%Pixel information generated
n=3
m=3
for a=7:9
for r=1:3
k(r)=a+ (r-1)*(n*m)
disp(k);
r=r+1
end
a=a+1
end
How can I avoid this and obtain all values of K for each value of "a"?
Thanks
Manoj
Since r is your index, your index will only vary from 1 to 3. And this each time you go through the first loop. Therefore, you need an independent index. You also don't need to increase r and a because the for-loop function does this automatically. Last, it's better to work with a cell array for k because it keeps growing throughout the for-loops.
Code:
n=3;
m=3;
k = cell(1,1); % cell array
index = 1; % independent index
for a=7:9
for r=1:3
k{index}=a+(r-1)*(n*m);
index = index + 1;
end
end
k = cell2mat(k)
Output:
k =
7 16 25 8 17 26 9 18 27

Save output from multiple loops matlab

Hello I have 3 variables i,j and k. I want to run a loop on each of them such that for each value of i, one value of j is considered and iterated over all values of k.Then for same i, take second value of j and iterate over all values of k and so on... Then repeat this process for all the values of i and save the output. For example for i=1,j=1 iterate over all values of k.Then for i=1, j=2 iterate over all values of k so on. Then save the output m for all the values of i and j over k iterations.
for i=1:30
for j=1:5
for k=1:100
m=i*0.5*j*sin(k);
end
end
end
May be my code is not right as well?
Using ndgrid you can accomplish this without any explicit for loops:
[i,j,k] = ndgrid(1:30,1:5,1:100);
m = 0.5*i.*j.*sin(k);
Or with meshgrid if you flip the first two inputs:
[j,i,k] = meshgrid(1:5,1:30,1:100);
m = 0.5*i.*j.*sin(k);
The easiest thing you can do is to define m as a 3D array; also, since you know in advance the final size of the array you can initialize it before the loops to avoid MatLab allocating the memory at each iteration:
% Initialize the array
m=zeros(30,5,100);
for i=1:30
for j=1:5
for k=1:100
% Set the values in the array "m"
m(i,j,k)=i*0.5*j*sin(k);
end
end
end
EDIT
In case you want, for each i and j the value of m be computed over k iterations, the variable m should be present also on the right of the = sign.
It should, for example, be somenthing like:
m=m+i+j+k
you can try the following modified version of the above code
% Initialize the array
m=zeros(30,5);
for i=1:30
for j=1:5
% Initialize the temporary varaible at each iteration
tmp_var=0;
for k=1:100
% Compute the value of "tmp_var" over "k" iteration
tmp_var=tmp_var+i*0.5*j*sin(k);
end
% Assign the value of "tmp_var" computed for a given (i,j) couple
m(i,j)=tmp_var;
end
end
In this example you need to define a temporary varaible to be used inside the k loop; at the end of the k loop the value of the temporary variable will be stored in the m matrix.
At the end of the script, you will have a matrix m of size (30 x 5).
Hope this helps.
In cases where the computation in the loop is only depending on the loop index you could just write:
[j,i,k]=meshgrid(1:5,1:30,1:100);
m=.5*i.*j.*sin(k);
meshgrid will create the appropriate 3D arrays of the indices i,j,k and m will be of the same dimension when the elementwise multiplication (.* instead of *) is used.

How to create a matrix with the increments within a loop in matlab?

I have created one loop inside another in matlab, and i want to create a matrix inside this second loop that gives the values of the two increments plus a parameter that is being calculated. I made the following code but the matrix is just saving the last values, so it is not a matrix is a vector:
for inclin=29:1:39
for alfa=1:1:90
Ii_perc=...
Di_perc=...
Gi_perc=...
r=...
matriz=[inclin alfa r]
end
end
So, i want to have a matrix with the different combinations of inclin/alfa/r that the loop gives in each loop, i.e, something like this:
matriz =[29 1 0.34
29 2 0.32
29 3 0.40
...........]
I really need some help to solve this problem..
Thanks!
If I correctly you understand I can offer this variation:
Matrix = zeros((39-29+1)*90,3);
count = 1;
for inclin=29:1:39
for alfa=1:1:90
r=rand();
Matrix(count,:)=[inclin alfa r];
count = count+1;
end
end
The problem is that
matriz=[inclin alfa r]
is a vector. If you want to append an additional row every loop iteration, you need to index it like this:
matriz(i, :)=[inclin alfa r]
Using the colon in this way says to assign the right hand side of the equation to the ith row of matriz.

expand matrix in matlab?

I would like to expand matrix row by row under a conditional statement without initializing the matrix. In C++, simply I use std::vector and push_back method without initializing the size of the vector in C++. However, I want to do same scenario in Matlab. This is my pseudo code
for i = 1:lengt(data)
if ( condition )
K = [data(1) data(2) i]
end
K
Let us assume some working code to resemble your pseudo-code.
%// Original code
for i = 1:10
if rand(1)>0.5
data1 = rand(2,1)
K = [data1(1) data1(2) i]
end
end
Changes for "pushing data without initialization/pre-allocation":
To save data at each iteration we keeping on "stacking" data along a chosen dimension. This could be thought of as pushing data. For a 2D case, use either a "row vector push" or a "column vector push". For this case we are assuming a former case.
We don't index into K using the original iterator, but use a custom one,
that only increments when the condition is satisfied.
The code below must make it clear.
%// Modified code
count = 1; %// Custom iterator; initialize it for the iteration when condition would be satisfied for the first time
for i = 1:10
if rand(1)>0.5
data1 = rand(2,1)
K(count,:) = [data1(1) data1(2) i] %// Row indexing to save data at each iteration
count = count +1; %// We need to manually increment our custom iterator
end
end
If we assume from the above that data is an Nx2 matrix, and that you only want to save the rows that satisfy some condition, then you almost have the correct code to update your K matrix without having to initialize it to some size:
K = []; % initialize to an empty matrix
for i=1:size(data,1) % iterate over the rows of data
if (condition)
% condition is satisfied so update K
K = [K ; data(i,:) i];
end
end
K % contains all rows of data and the row number (i) that satisfied condition
Note that to get all elements from a row, we use the colon to say get all column elements from row i.

In an assignment A(I) = B, the number of elements in B and I must be the same

Now, I understand the problem here, what I don't understand however is that how should 'I' be initialized??
For instance, in my case variable 'p' generates an array at the end of every for loop, which is programmed to run for 101 times. The output of p looks something like this
p =
-0.0149 -0.0149
Now, I want to store this value into another variable at the end of every for loop and increment its index.
So,What should be the dimension of that variable?
I have tried initializing ---> A=rand(2,101);
If you don't wish to pre-allocate the array A. Then you can keep appending the values in A at the each for loop iteration as follows:
A=[];
for loop
get p vector (every iteration it should be 2x1)
A=[A p];
end
Or you can directly write in the for loop:
A(:,i)=p; %but your p vector seems to be 1x2 and not 2x1. If it is 2x1, then you should initialize A as rand(101,2)