How to fprintf column headers in MATLAB? [duplicate] - matlab

This question already has answers here:
Display matrix with row and column labels
(6 answers)
Closed 7 years ago.
I have two matrices A and B as given below:
A = [1
2
3
4
5]
B = [10 11 12 13
15 16 17 18
17 12 15 13
20 21 22 17
40 41 32 33]
and I would like to output it to a text file in the form given below with column headers as shown:
Desired text output
A B B B B
1 10 11 12 13
2 15 16 17 18
3 17 12 15 13
4 20 21 22 17
5 40 41 32 33
Reproducible code
A = [1; 2; 3; 4; 5];
B = [10, 11, 12, 13;
15, 16, 17, 18;
17, 12, 15, 13;
20, 21, 22, 17;
40, 41, 32, 33;];
ALL = [A B];
ALL_cell = mat2cell(ALL, ones(size(ALL,1),1), size(ALL,2));
fID = fopen('output.dat','w');
f = #(x) fprintf(fID,'%s\n',sprintf('%f\t',x));
cellfun(f,ALL_cell);
fclose(fID);
How to insert the column headers as shown above with MATLAB? Sometimes, the columns in B could be over 100, as an example I have given only 4.

In my private collection of utility scripts, I have a function to 'pretty-print' matrices:
function pprint(fid, M, cols)
fprintf(fid, '%s\t', cols{:});
fprintf(fid, '\n');
for irow=1:size(M, 1)
fprintf(fid, '% .3f\t', M(irow,:));
fprintf(fid, '\n');
end
You could use it like this:
>> headers = [repmat({'A'}, 1, size(A, 2)), repmat({'B'}, 1, size(B, 2))]
headers =
'A' 'B' 'B' 'B' 'B'
>> fid = 1; % print to stdout
>> pprint(fid, [A, B], headers)
A B B B B
1.000 10.000 11.000 12.000 13.000
2.000 15.000 16.000 17.000 18.000
3.000 17.000 12.000 15.000 13.000
4.000 20.000 21.000 22.000 17.000
5.000 40.000 41.000 32.000 33.000
Note that the headers and the columns only line up nicely if the column labels are not too large, you might have to play with adding extra tabs, or use spaces instead of tabs (i.e. use '%10s' instead of '%s\t', and '%10.3f' instead of '% .3f\t')

Related

Create new matrix based on diagonal and antidiagonal of given matrix

I want to create matrix B from matrix A, with the following rules:
Non-diagonal elements A are like non-diagonal elements of B.
The main diagonal of A is the antidiagonal of B
The antidiagonal of A is the main diagonal of B.
For example:
A = [ 1 2 3 4;
7 8 9 10;
13 14 15 16;
19 20 21 22 ];
B = [ 4 2 3 1;
7 9 8 10;
13 15 14 16;
22 20 21 19 ];
How can I create B given A?
You can create all of the indices, then it's a single assignment.
% Get size of square matrix A
n = size(A,1);
% Indicies are 1:n^2 by default
idx = 1:n^2;
% Swap diagonal and antidiagonal indices
idx( [1:(n+1):n^2, n^2-n+1:1-n:n] ) = [n^2-n+1:1-n:n, 1:(n+1):n^2];
% Use the indexing array to create B from A, reshape to be n*n
B = reshape( A( idx ), n, n );
Output for your example A:
B =
4 2 3 1
7 9 8 10
13 15 14 16
22 20 21 19
There are so many ways to reach that results, it is just an indexing exercise. Here is one (of the many) way to reach that result for any square matrix of size n:
%% input
A=[ 1 2 3 4 ;
7 8 9 10 ;
13 14 15 16 ;
19 20 21 22 ];
%% Calculate linear indices for the diagonal and antidiagonal
n=size(A,1) ;
idxdiag = 1:(n+1):n^2 ; % => idxdiag = [1 6 11 16]
idxantidiag = n:(n-1):n^2-1 ; % => idxantidiag = [4 7 10 13]
%% Generate B
B = A ; % start with a simple copy (for the non-diagonal elements)
% Method 1: direct indice assignment
B(idxdiag) = diag(fliplr(A)) ; % Assign diagonal elements of B
B(idxantidiag) = flipud(diag(A)) ; % Assign antidiagonal elements of B
% Method 2: summation
B([idxdiag idxantidiag]) = 0 ;
B = B + diag(diag(fliplr(A))) + fliplr(diag(diag(A))) ;
B =
4 2 3 1
7 9 8 10
13 15 14 16
22 20 21 19
Both methods return exactly the same matrix B.
I suggest you familiarise yourself with the MATLAB function used to understand what is going on behind the scene:
fliplr
flipud
diag
and may be have a read at:
Matrix Indexing in MATLAB
I thought a little differently and came to a conclusion
A=[1 2 3 4;7 8 9 10;13 14 15 16; 19 20 21 22];;
n=size(A,1) ;
B=zeros(n,n) ;
for i=1:n
for j=1:n
if i==j
B(i,j)=A(i,n-i+1);
elseif j==n-i+1
B(i,j)=A(i,i);
else
B(i,j)=A(i,j);
end
end
end
B
Here's a variant using eye, find, and flip to generate linear indices:
ind1 = find(eye(size(A)));
ind2 = flip(find(flip(eye(size(A)))));
B = A;
B([ind1 ind2]) = B([ind2 ind1]);
B =
4 2 3 1
7 9 8 10
13 15 14 16
22 20 21 19
And here's a variant of the above that uses just eye and flip to generate logical indices:
ind1 = eye(size(A), 'logical');
ind2 = flip(ind1);
B = A;
B(ind1) = flip(A(ind2));
B(ind2) = flip(A(ind1));
B =
4 2 3 1
7 9 8 10
13 15 14 16
22 20 21 19

Vectorising a Matlab code to pick specific indices of a matrix

I have a matrix A in Matlab of dimension Nx(N-1), e.g.
N=5;
A=[1 2 3 4;
5 6 7 8;
9 10 11 12;
13 14 15 16;
17 18 19 20];
I want to rearrange the elements of A in a certain way. Specifically I want to create a matrix B of dimension (N-1)xN such that:
for i=1,...,N,
B(:,i) collects
1) the first i-1 elements of the i-1th column of A and
2) the last N-i elements of the ith column of A.
Notice that for i=1 the i-1th column of A does not exist and therefore 1) is skipped; similarly, for i=N theith column of A does not exist and therefore 2) is skipped.
In the example above
B=[5 1 2 3 4
9 10 6 7 8
13 14 15 11 12
17 18 19 20 16];
This code does what I want. I am asking your help to vectorise it in an efficient way.
B=zeros(N-1,N);
for i=1:N
if i>1 && i<N
step1=A(1:i-1,i-1);
step2=A(i+1:N,i);
B(:,i)=[step1;step2];
elseif i==1
B(:,i)=A(i+1:N,i);
elseif i==N
B(:,i)=A(1:i-1,i-1);
end
end
Extract the lower and upper triangular matrices of A. Then reassemble them with a "diagonal shift":
u = triu(A);
l = tril(A,-1);
B = padarray(u(1:end-1,:),[0 1],'pre') + padarray(l(2:end,:),[0 1],'post');
Another valid approach using logical indexing combined with tril and triu:
B = zeros(size(A'));
B(tril(true(size(B)))) = A(tril(true(size(A)), -1));
B(triu(true(size(B)), 1)) = A(triu(true(size(A))));
Result:
>> B
B =
5 1 2 3 4
9 10 6 7 8
13 14 15 11 12
17 18 19 20 16

How to ge the average of two matrices on Matlab?

I have 2 matrices,
a= [1 2 3; 4 5 6; 7 8 9; 10 11 12];
and
b= [13 14 15; 16 17 18; 19 20 21; 22 23 24];
How can I make the average of these 2 matrices and store the values in another matrix "C" on Matlab?
The value of C will be,
c= [(1+13)/2 (2+14)/2 (3+15)/2; (4+16)/2 (5+17)/2 (6+18)/2;...]
Thanks.
You would do:
c = (a+b)/2
This will give you the desired result.
Another way would be to stack the matrices on top of each other in 3D, then find the average along the third dimension:
c = mean(cat(3, a, b), 3);

MATLAB: Failed to correctly write using csvwrite()

I am trying to write three different arrays into 3 columns in a csv file. This what I have tried :
str = 'This is the matrix: ' ;
a= [1 2 3 4 5 6 ]';
csvwrite('C:\Users\ganesh\Desktop\data.csv', a);
b= [11 12 13 14 15 16]';
csvwrite('C:\Users\ganesh\Desktop\data.csv', b, 1, 0);
c= [21 22 23 24 25 26]';
csvwrite('C:\Users\ganesh\Desktop\data.csv', c, 2, 0);
But it does not work. Only last data is coming that too in a row. I have tried to put offset for columns.
Did I made a mistake somewhere ? ALso is there a way I can write these data in a single function call , rather than calling three time as shown here.
You should put your data in a matrix:
m = [1 2 3 4 5 6
11 12 13 14 15 16
21 22 23 24 25 26];
csvwrite('data.csv', m);

How to cut a matrix in Matlab?

I would like to transform the matrix A into the matrix B without using cells (e.g. mat2cell) in Matlab, where
A=[1 2 3;
4 5 6;
7 8 9;
10 11 12;
13 14 15;
16 17 18;
19 20 21;
22 23 24;
25 26 27];
B=[1 2 3 10 11 12 19 20 21;
4 5 6 13 14 15 22 23 24;
7 8 9 16 17 18 25 26 27];
All you need is some reshape + permute magic -
N = 3; %// Cut after every N rows and this looks like the no. of columns in A
B = reshape(permute(reshape(A,N,size(A,1)/N,[]),[1 3 2]),N,[])
This builds a linear index to rearrange the entries of A and then reshapes into the desired matrix B:
m = 3; %// cut size in rows of A. Assumed to divide size(A,1)
n = size(A,2);
p = size(A,1);
ind = bsxfun(#plus, ...
bsxfun(#plus, (1:m).', (0:n-1)*p), permute((0:p/m-1)*m, [1 3 2]));
B = reshape(A(ind(:)), m, [])