Store vectors that result form for loop and then compute the average of all these vectors - arrays

I have a 4 by 4 matrix:
A=[rand(1) 2 -1 rand(1);
rand(1) 3 rand(1) 0;
rand(1) -5 -2 5;
9 0 0 rand(1)];
Now I would like to form a vector b to be the first column of the matrix A. So the vector b is
b=[rand(1)
rand(1)
rand(1)
9 ];
I would like to write a for loop that compute b many times say 100 then store these vectors in matrix C ( which now has size of 4*100) and then compute the mean of all columns of C. So far I wrote:
for j=1:100
A=[rand(1) 2 -1 rand(1);...
rand(1) 3 rand(1) 0;...
rand(1) -5 -2 5;...
9 0 0 rand(1)];
b=A(:,1)
end
Every time the loop executed, it produces a vector, say b_1 then b_2,....,b_100. How to store them in matrix C=[b_1 b_2 ... b_100] and then compute the mean of matrix C over all columns so that the mean will be a vector of size 4 by 1 the same size as b.

I don't have Matlab on this laptop but the little script should be like this:
for jj=1:100
C(:,jj)=[rand(1) ;...
rand(1) ;...
rand(1) ;...
9 ];
end
The matrix C will contain all the column-vectors b. To access to any of them just use b(:,x) where x is the index-number or column that you want to use.
For the average you can do something like this:
b_average=[mean(C(1,:)); mean(C(2,:)); mean(C(3,:));mean(C(4,:))];
Of course the last mean upon a vector with only 9 values hasn't meaning: I leave the code as it is just for completeness.
Remember as well that the average of a vector with random numbers will be really close to the value zero if N is big enough (where N is the number of the sample in the vector of course).
Anyway, the for loop is not the best way to do this. Try to use something like this:
C=[rand(1,100);rand(1,100);rand(1,100);9*ones(1,100)];
or better (as it was point out by Adriaan)
C=[rand(3,100);9*ones(1,100)];
This line does the same of the for loop. Again: try to don't use the variable j and iin Matlab because they are reserved.

Related

Extracting positions of elements from two Matlab vectors satisfying some criteria

Consider three row vectors in Matlab, A, B, C, each with size 1xJ. I want to construct a matrix D of size Kx3 listing every triplets (a,b,c) such that:
a is the position in A of A(a).
b is the position in B of B(b).
A(a)-B(b) is an element of C.
c is the position in C of A(a)-B(b).
A(a) and B(b) are different from Inf, -Inf.
For example,
A=[-3 3 0 Inf -Inf];
B=[-2 2 0 Inf -Inf];
C=[Inf -Inf -1 1 0];
D=[1 1 3; %-3-(-2)=-1
2 2 4; % 3-2=1
3 3 5]; % 0-0=0
I would like this code to be efficient, because in my real example I have to repeat it many times.
This question relates to my previous question here, but now I'm looking for the positions of the elements.
You can use combvec (or any number of alternatives) to get all pairings of indices a and b for the corresponding arrays A and B. Then it's simply a case of following your criteria
Find the differences
Check which differences are in C
Remove elements you don't care about
Like so:
% Generate all index pairings
D = combvec( 1:numel(A), 1:numel(B) ).';
% Calculate deltas
delta = A(D(:,1)) - B(D(:,2));
delta = delta(:); % make it a column
% Get delta index in C (0 if not present)
[~,D(:,3)] = ismember(delta,C);
% If A or B are inf then the delta is Inf or NaN, remove these
idxRemove = isinf(delta) | isnan(delta) | D(:,3) == 0;
D(idxRemove,:) = [];
For your example, this yields the expected results from the question.
You said that A and B are at most 7 elements long, so you have up to 49 pairings to check. This isn't too bad, but readers should be careful that the pairings can grow quickly for larger inputs.

How to plot a 2D plot in MATlab from Three Matrices and an array?

I am trying to plot a figure using three matrices but somehow I couldn't understand. I have three matrices and an array. Suppose,
A =
1 2 3
4 5 4
7 8 9
B =
2 3 13
5 11 10
9 7 6
C =
1 2 3
2 3 13
5 11 10
and an array
Y= [0.001 0.0002 0.0004].
Now I want to plot it in such a way that array values should be on y axis while against 0.001, 0.002 and 0.0004 the matrices value should be arranged.
for examples, the y=0.001, A(1,1)=1, y=0.0002, B(1,1)=2 y=0.0004, C(1,1)=1 for a single line.
and similarly process goes for A(i,j),B(i,j) and c(i,j) points using loop to plot all lines on a single figure.
Thanks
So, the first plot is plot([1,2,1],Y), the next one is plot([2,3,2],Y) and so on?
If so, you could do it like that
X = cat(3,cat(3,A,B),C);
X = reshape(permute(X,[3,1,2]),3,9);
plot(X,Y,'--x');
which gives a plot like this:
Is this what you were looking for? If not, I didn't understand your question well and I'd like to ask you to rephrase it.
You can create a 3D array (tensor) and access it in a loop.
T(:,:,1) = A;
T(:,:,2) = B;
T(:,:,3) = C;
figure;
for idi = 1:size(A,1)
for idj = 1:size(A,2)
plot(squeeze(T(idi,idj,:)).',Y); hold on;
end
end
Accessing the third dimension is not fastest operation (as they are not store sequential in memory) and if the matrices are larger you might consider reshape.
I did not understand you wanted the vector Y to be on the x-axis or y-axis (and neither of those plots make sense to me) but I am sure you can modify the code from here for your needs.

Inserting selected number of zeros between fixed number of non-zero elements in a vector in MATLAB

I have a vector like
A=[1,2,3,4,5,6,7,8,9,10];
I would like to insert 2 zero every 5 number.
The result would be A=[1,2,3,4,5,0,0,6,7,8,9,10,0,0].
I know I could preallocate the space and then use a for cycle to assign the variable, but I was wandering if there was some more elegant way.
This works even if A doesn't contain an integer number of blocks:
A = [1,2,3,4,5,6,7,8,9,10,11,12]; % input vector
m = 5; % block size
n = 2; % number of zeros to be added after each block
B = zeros(1, numel(A)+floor(numel(A)/m)*n); % preallocate to appropriate size
B(mod(0:end-1, m+n)<m) = A; % logical index. Fill values of A at desired positions of B
The result in this example is
B =
1 2 3 4 5 0 0 6 7 8 9 10 0 0 11 12
With A having number of elements a multiple of 5, you could use some reshaping and concatenation with zeros, like so -
reshape([reshape(A,5,[]) ; zeros(2,numel(A)/5)],1,[])

How to do a matrix manipulation on Matlab?

I have a matrix A of size m x n and another matrix b of size 1 x n (in Matlab).
The matrix b is such that it consists of sequences of 1s, then sequences of 2s, then sequences of 3s, etc. up to some value k.
(For example b = [1 1 1 2 2 2 3 4 4], n = 9)
I want to take A, and for each row in A, choose the max in each segment, zeroing everything else in that subsequence.
So, for example, for a row A = [0 -1 2 3 4 1 3 4 5]) I would get
[0 0 2 0 4 0 3 0 5]
If there are multiple rows in A (m > 1), this should happen for each row.
I can do it easily using for loops, but it works very slowly, because I loop both over m and n.
Is there a "oneliner" to do it in Matlab, or something simple that works fast?
If A is a single row, accumarray can do the job using an ad hoc function:
result = accumarray(b(:), A(:) ,[] , #(x) {x==max(x)});
result = vertcat(result{:}).' .* A;
Not sure how fast this will be, since it uses cells.
If A has several rows, you can use a loop over the rows.

Look at each row separately in a matrix (Matlab)

I have a matrix in Matlab(2012) with 3 columns and X number of rows, X is defined by the user, so varies each time. For this example though I will use a fixed 5x3 matrix.
So I would like to perform an iterative function on each row within the matrix, while the value in the third column is below a certain value. Then store the new values within the same matrix, so overwrite the original values.
The code below is a simplified version of the problem.
M=[-2 -5 -3 -2 -4]; %Vector containing random values
Vf_X=M+1; %Defining the first column of the matrix
Vf_Y=M+2; %Defining the secound column of the matrix
Vf_Z=M; %Defining the third column of the matrix
Vf=[Vf_X',Vf_Y',Vf_Z']; %Creating the matrix
while Vf(:,3)<0
Vf=Vf+1;
end
disp(Vf)
The result I get is
1 2 0
-2 -1 -3
0 1 -1
1 2 0
-1 0 -2
Ideally I would like to get this result instead
1 2 0
1 2 0
1 2 0
1 2 0
1 2 0
The while will not start if any value is above zero to begin with and stops as soon as one value goes above zero.
I hope this makes sense and I have supplied enough information
Thank you for your time and help.
Your current problem is that you stop iterating the very moment any of the values in the third row break the condition. Correct me if I'm wrong, but what I think you want is to continue doing iterations on the remaining rows, until the conditions are broken by all third columns.
You could do that like this:
inds = true(size(Vf,1),1);
while any(inds)
Vf(inds,:) = Vf(inds,:)+1;
inds = Vf(:,3) < 0;
end
Of course, for the simple addition you provide, there is a better and faster way:
inds = Vf(:,3)<0;
Vf(inds,:) = bsxfun(#minus, Vf(inds,:), Vf(inds,3));
But for general functions, the while above will do the trick.

Resources