concatenate columns of matrix into one vector - matlab

suppose that we have following two random matrix
x=rand(7,7);
x
x =
0.8147 0.5469 0.8003 0.0357 0.6555 0.8235 0.7655
0.9058 0.9575 0.1419 0.8491 0.1712 0.6948 0.7952
0.1270 0.9649 0.4218 0.9340 0.7060 0.3171 0.1869
0.9134 0.1576 0.9157 0.6787 0.0318 0.9502 0.4898
0.6324 0.9706 0.7922 0.7577 0.2769 0.0344 0.4456
0.0975 0.9572 0.9595 0.7431 0.0462 0.4387 0.6463
0.2785 0.4854 0.6557 0.3922 0.0971 0.3816 0.7094
and
y=rand(6,5)
y =
0.7547 0.4984 0.2551 0.1386 0.2435
0.2760 0.9597 0.5060 0.1493 0.9293
0.6797 0.3404 0.6991 0.2575 0.3500
0.6551 0.5853 0.8909 0.8407 0.1966
0.1626 0.2238 0.9593 0.2543 0.2511
0.1190 0.7513 0.5472 0.8143 0.6160
i want to concatenate first four columns of each matrix into single one dimensional vector c,i have tried
c=[x(:,4) y(:,4)]
Error using horzcat
Dimensions of matrices being concatenated are not consistent.
but get following error,please help me to solve this problem

[ reshape(x(:,1:4),[],1); reshape(y(:,1:4),[],1) ]
This stacks one column below the other: first those of x and then those of y. I guess that's the element order you want. (If you want to interleave one column of x, then one of y etc, see #RobertP's comment.)

Related

How to write output of MATLAB to a txt file?

I would like to write output of Matlab code's result into a .txt file.
My code is :
for i=1:1000;
M{i}=rand(1,4)';
end
So I try :
fid=fopen('M.txt','wt');
fprintf(fid,'%.8f\n',M{i});
fclose(fid)
The result is 1*1000 cell and every cell has 4*1 matrice. But the output file has 1*4000 matrices with this. How can I write column by column to a .txt file.
Thanks in advance.
screenshot from matlab
I want to write down all values of matrix like below side by side for 1000 matrices.
0.9572 0.9572 0.9572 0.9572 0.9572 0.9572 0.9572 0.9572 0.9572 0.9572
0.4854 0.4854 0.4854 0.4854 0.4854 0.4854 0.4854 0.4854 0.4854 0.4854
0.8003 0.8003 0.8003 0.8003 0.8003 0.8003 0.8003 0.8003 0.8003 0.8003
0.1419 0.1419 0.1419 0.1419 0.1419 0.1419 0.1419 0.1419 0.1419 0.1419
As you mentioned your MATLAB version is R2019a, you can use writematrix directly:
>> n = 4;
>> m = rand(1,n);
>> M = repmat(m.',1,1000);
>> writematrix(M,'M.txt','Delimiter','space')
Your format specifier *.8f\n says print each value on a new line. If you want to print the four values as four columns, use a format specifier like this:
fprintf(fid,'%.8f %.8f %.8f %.8f\n',M{i});
If you want to write just one column of the data at a time, specify which column like this:
fprintf(fid,'%.8f\n',M{i}(1));
Then you'll have to repeat or loop to do the other 3 columns.

fillmissing with only last 5 observations instead of all

I am using Matlab's fillmissing function to fill missing values.
If you have a matrix that looks as follows:
A = rand(10,2);
A(end-5:end,1) = NaN;
% this gives:
A =
0.8147 0.1576
0.9058 0.9706
0.1270 0.9572
0.9134 0.4854
NaN 0.8003
NaN 0.1419
NaN 0.4218
NaN 0.9157
NaN 0.7922
NaN 0.9595
And you apply the function fillmissing as follows:
Afilled = fillmissing(A, 'previous')
then the corresponding matrix will look as follows:
Afilled =
0.8147 0.1576
0.9058 0.9706
0.1270 0.9572
0.9134 0.4854
0.9134 0.8003
0.9134 0.1419
0.9134 0.4218
0.9134 0.9157
0.9134 0.7922
0.9134 0.9595
Now however, the function does not take into account how many observations were actually missing (in this case 6).
I am looking for a way to take the number of observations into account before taking the last value. For example, only fill the missing observations based on the last 5 observations:
Afilled2 =
i=1 0.8147 0.1576
i=2 0.9058 0.9706
i=3 0.1270 0.9572
i=4 0.9134 0.4854
i=5 % missing 1 0.9134 0.8003
i=6 % missing 2 0.9134 0.1419
i=7 % missing 3 0.9134 0.4218
i=8 % missing 4 0.9134 0.9157
i=9 % missing 5 0.9134 0.7922
i=10 NaN 0.9595
MATLAB's fillmissing function doesn't have this functionality. Here is some simple code to do what you would like to do (fill along dimension 1 using the 'previous' method):
% parameter: maximum number of observations to fill with a given value
max_fill_obs = 5;
% loop over columns
for col = 1 : size(A, 2)
% initialize a counter (the number of previously filled values) to 0
counter = 0;
% loop over rows within column col, starting from the second row
for row = 2 : size(A, 1)
% if the current element is known, reset the counter to 0
if ~isnan(A(row, col))
counter = 0;
% otherwise, if we haven't already filled in max_fill_obs values,
% fill in the value and increment the counter
elseif counter < max_fill_obs
A(row, col) = A(row - 1, col);
counter = counter + 1;
end
end
end
This works if there are multiple blocks of NaN values, filling in only the first max_fill_obs values within each block. For example, try running it on the matrix defined by
A = rand(20,2);
A(5:10,1) = NaN;
A(13:19,1) = NaN;
This is a vectorized version of the above code:
Afilled = fillmissing(A, 'previous');
Afilled(movsum(isnan(A), [max_fill_obs, 0]) > max_fill_obs) = NaN;

How can i delete rows with zeros from a matrix and rebuild the matrix? [duplicate]

This question already has answers here:
in matlab delete an entire row if the elements in certain columns equal zero
(3 answers)
Closed 5 years ago.
I have a large nxm matrix. Here is some code to set up an example matrix E for illustration:
E = [(0:9).',[rand(9,3); zeros(1,3)]]
>> E =
0 0.8147 0.9649 0.7922
1 0.9058 0.1576 0.9595
2 0.1270 0.9706 0.6557
3 0.9134 0.9572 0.0357
4 0.6324 0.4854 0.8491
5 0.0975 0.8003 0.9340
6 0.2785 0.1419 0.6787
7 0.5469 0.4218 0.7577
8 0.9575 0.9157 0.7431
9 0 0 0
My question is how can transform matrix E into
>> E =
0 0.8147 0.9649 0.7922
1 0.9058 0.1576 0.9595
2 0.1270 0.9706 0.6557
3 0.9134 0.9572 0.0357
4 0.6324 0.4854 0.8491
5 0.0975 0.8003 0.9340
6 0.2785 0.1419 0.6787
7 0.5469 0.4218 0.7577
8 0.9575 0.9157 0.7431
In order to write it to a txt file without the zeros.
Since the size of this matrix is not fixed, it could have multiple rows like 9 in the above example, or look like
>> E =
0 0.8147 0.9649 0.7922
1 0.9058 0.1576 0.9595
2 0.1270 0.9706 0.6557
3 0.9134 0.9572 0.0357
4 0.6324 0.4854 0.8491
5 0.0975 0.8003 0.9340
6 0.2785 0.1419 0.6787
7 0.5469 0.4218 0.7577
8 0.9575 0.9157 0.7431
0 0 0 0
0 0 0 0
Thank you.
Does this cover all cases? If an element in column 2 == 0, delete it.
E = E(E(:,2) ~= 0,:);
Or if all columns but the first one have to be zero:
E = E(all(E(:,2:end) ~= 0,2),:);

Performing concatenation within a matrix MATLAB [duplicate]

This question already has answers here:
How do you concatenate the rows of a matrix into a vector?
(2 answers)
Closed 7 years ago.
I have an m x n matrix, how do I convert it to a column matrix of dimension (m x n) x 1?
Is there any library function in MATLAB? If not, how can I write one to do this?
Thanks in advance!
You can simply use the colon operator to flatten a matrix into a column vector. You will want to first take the transpose because by default, flattening is column-major and your post is row-major.
M = rand(4,3);
M =
0.8147 0.6324 0.9575
0.9058 0.0975 0.9649
0.1270 0.2785 0.1576
0.9134 0.5469 0.9706
M = M.';
M =
0.8147 0.9058 0.1270 0.9134
0.6324 0.0975 0.2785 0.5469
0.9575 0.9649 0.1576 0.9706
M = M(:);
M =
0.8147
0.6324
0.9575
0.9058
0.0975
0.9649
0.1270
0.2785
0.1576
0.9134
0.5469
0.9706

Use vertcat to concatenate columns of a matrix using array of indices

Let's say we have the following random matrix
a=rand(6,5)
a =
0.8147 0.2785 0.9572 0.7922 0.6787
0.9058 0.5469 0.4854 0.9595 0.7577
0.1270 0.9575 0.8003 0.6557 0.7431
0.9134 0.9649 0.1419 0.0357 0.3922
0.6324 0.1576 0.4218 0.8491 0.6555
0.0975 0.9706 0.9157 0.9340 0.1712
and we have done an SVD decomposition of this matrix.
[U E V]=svd(a);
If we want to concatenate the first, third and fifth columns, we can do that like this
z=vertcat(U(:,1),U(:,3),U(:,5));
The dimensions of z are
[m,n]=size(z)
m =
18
n =
1
But suppose that I want the following thing: I will declare an array with elements of these indices or
b=[1 3 5]
b =
1 3 5
and then
z1=vertcat(U(:,b));
but the dimensions are
[m1 n1]=size(z1)
m1 =
6
n1 =
3
Is it possible that in z1=vertcat(U(:,b)); I change something so that it directly gives me result I want?
When you look at:
a(:,1) = 0.8147
0.9058
0.1270
0.9134
0.6324
0.0975
You get a vertical vector. By doing vertcat you add the other vertical vectors vertically resulting in a 18x1vector.
You could use horzcat if you want the other columns added as columns. By using b which is a horizontal vector MATLAB is changing the output accordingly.
Because svd returns a matrix of the same dimension as the input, same goes for U.
EDIT
For getting a 18x1 vector as result use either:
z1=reshape(z1,18,1);
or use
z1=z1(:);
This should do the trick
z1 = U(:,b);
z1 = z1(:);
what you done is proper, but you have to use reshape function at the last step, like that:
z1 = reshape(Z1,1,18);