Matlab output - Space padding? - matlab

I'm trying to output a Matrix:
M = [1 20 3; 22 3 24; 100 150 2];
Using:
for i=1:3
fprintf('%f\t%f\t%f\n', M(i), M(i+length(M)), M(i+length(M)*2));
end
And the output is turning out something like:
1 20 3
22 3 24
100 150 2
Which is obviously not great. How can I get it so the front of integers are padded with spaces? Like so:
1 20 3
22 3 24
100 150 2
Any ideas?
Thanks!

You can use string formatting to allocate specific number of characters per displayed number.
For example
fprintf('% 5d\n', 12)
prints 12 in 5 characters, padding the un-used 3 leading characters with spaces.

You can use num2str (optionally with format string %f) and apply it to the whole matrix instead of each row so that you get the right padding:
disp(num2str(M));
returns
1 20 3
22 3 24
100 150 2

Related

How to load a text file in Matlab when the number of values in every line are different

I have a none rectangular text file like A which has 10 values in first line, 14 values in 2nd line, 16 values in 3rd line and so on. Here is an example of 4 lines of my text file:
line1:
1.68595314026 -1.48498177528 2.39820933342 27 20 15 2 4 62 -487.471069336 -517.781921387 5 96 -524.886108398 -485.697143555
Line2:
1.24980998039 -0.988095104694 1.89048337936 212 209 191 2 1 989 -641.149658203 -249.001220703 3 1036 -608.681762695 -300.815673828
Line3:
8.10434532166 -4.81520080566 4.90576314926 118 115 96 3 0 1703 749.967773438 -754.015136719 1 1359 1276.73632813 -941.855895996 2 1497 1338.98852539 -837.659179688
Line 4:
0.795098006725 -0.98456710577 1.89322447777 213 200 68 5 0 1438 -1386.39111328 -747.421386719 1 1565 -1153.50915527 -342.951965332 2 1481 -1341.57043457 -519.307800293 3 1920 -1058.8828125 -371.696960449 4 1303 -1466.5802002 -308.764587402
Now, I want to load this text file in to a matrix M in Matlab. I tired to use importdata function for loading it
M = importdata('A.txt');
but it loads the file in a rectangular matrix (all rows have same number of columns!!!) which is not right. The expected created matrix size should be like this:
size(M(1,:))= 1 10
size(M(2,:))= 1 14
size(M(3,:))= 1 16
How can I load this text file in a correct way into Matlab?
As #Jens suggested, you should use a cell array. Assuming your file contains only numeric values separated by whitespaces, for instance:
1 3 6
7 8 9 12 15
1 2
0 3 7
You can parse it into cell array like this:
% Read full file
str = fileread('A.txt');
% Convert text in a cell array of strings
c = textscan(str, '%s', 'Delimiter', '\n');
c = c{1};
% Convert 'string' elements to 'double'
n = cellfun(#str2num, c, 'UniformOutput', false)
You can then access individual lines like this:
>> n{1}
ans =
1 3 6
>> n{2}
ans =
7 8 9 12 15

How to set an indexed value in a matrix based on another matrix's values

Say I have a matrix A
A =
0 1 2
2 1 1
3 1 2
and another matrix B
B =
0 42
1 24
2 32
3 12
I want to replace each value in A by the one associated to it in B.
I would obtain
A =
42 24 32
32 24 24
12 24 32
How can I do that without loops?
There are several ways to accomplish this, but here is an short one:
[~,ind]=ismember(A,B(:,1));
Anew = reshape(B(ind,2),size(A))
If you can assume that the first column of B is always 0:size(B,1)-1, then it is easier, becoming just reshape(B(A+1,2),size(A)).
arrayfun(#(x)(B(find((x)==B(:,1)),2)),A)

Converting Single dimensional matrix to two dimension in Matlab

Well I do not know if I used the exact term. I tried to find an answer on the net.
Here is what i need:
I have a matix
a = 1 4 7
2 5 8
3 6 9
If I do a(4) the value is 4. So it is reading first column top to buttom then continuing to next .... I don't know why. However,
What I need is to call it using two indices. As row and column:
a(1,2)= 4
or even better if i can call it in the following way:
a{1}(2)=4
What is this process really called (want to learn) and how to perform in matlab.
I thought of a loop. Is there a built in function
Thanks a lot
Check this:
a =
18 18 16 18 18 18 16 0 0 0
16 16 18 0 18 16 0 18 18 16
18 0 18 18 0 16 0 0 0 18
18 0 18 18 16 0 16 0 18 18
>> a(4)
ans =
18
>> a(5)
ans =
18
>> a(10)
ans =
18
I tried reshape. it is reshaping not converting into 2 indeces
If you've already got a matrix, you already can access it with two indices:
if you've got
a = 1 4 7
2 5 8
3 6 9
you can access it as
a(3,2) = 6
However, the indexing goes from the top left, row first then column. If you want to get at the "4" in the matrix then do:
a(1,2)
To reshape a vector/matrix/array, use reshape().
Or you could leave it as a one dimensional array and just use
((Column - 1) * 3) + Row - 1) as the index. 3 because there are three columns.
NB a(4) = 4 because of the way you've arranged columns and rows in the one dimensional array, yours is "loaded" as
R1C1,R2C1,R3C1, R1C2 etc wher R is row and C is column
If that's inconvenient then you just need to get whatever fills the array row then column so the above mapping would be
((Row - 1) * 3) + Column - 1)
Don't do Matlab so above code assumes array starts at 0, if not just add 1 to it.

Dividing selected elements of array on Matlab

I have the following array
a = [ 1 10 3 4 68 2 34 8 10 ]
And I need to divide each number (/2) if this number is higher than 9.
This means that 1 has not to be divided, and 10 has to be divided (/2)
The resulting array should be:
a = [ 1 5 3 4 34 2 17 8 5 ]
I have to do it without using a FOR function. So I tried with this:
a = a./2;
This divides every number of the array, and I as told you before, I want to divide only the ones higher than 9.
Can anyone tell me how can I do it? Add a 'if whatever>5' in that statement or something?
Thanks in advance
Use logical indexing for both dividing only the numbers that meets your criterion and for assigning the result to those specific indices.
a = [ 1 10 3 4 68 2 34 8 10 ];
a(a>9) = a(a>9) ./ 2

How to extract new matrix from existing one

I have a large number of entries arranged in three columns. Sample of the data is:
A=[1 3 2 3 5 4 1 5 ;
22 25 27 20 22 21 23 27;
17 15 15 17 12 19 11 18]'
I want the first column (hours) to control the entire matrix to create new matrix as follows:
Anew=[1 2 3 4 5 ; 22.5 27 22.5 21 24.5; 14 15 16 19 15]'
Where the 2nd column of Anew is the average value of each corresponding hour for example:
from matrix A:
at hour 1, we have 2 values in 2nd column correspond to hour 1
which are 22 and 23 so the average is 22.5
Also the 3rd column: at hour 1 we have 17 and 11 and the
average is 14 and this continues to the hour 5 I am using Matlab
You can use ACCUMARRAY for this:
Anew = [unique(A(:,1)),...
cell2mat(accumarray(A(:,1),1:size(A,1),[],#(x){mean(A(x,2:3),2)}))]
This uses the first column A(:,1) as indices (x) to pick the values in columns 2 and 3 for averaging (mean(A(x,2:3),1)). The curly brackets and the call to cell2mat allow you to work on both columns at once. Otherwise, you could do each column individually, like this
Anew = [unique(A(:,1)), ...
accumarray(A(:,1),A(:,2),[],#mean), ...
accumarray(A(:,1),A(:,3),[],#mean)]
which may actually be a bit more readable.
EDIT
The above assumes that there's no missing entry for any of the hours. It will result in an error otherwise. Thus, a more robust way to calculate Anew is to allow for missing values. For easy identification of the missing values, we use the fillval input argument to accumarray and set it to NaN.
Anew = [(1:max(A(:,1)))', ...
accumarray(A(:,1),A(:,2),[],#mean,NaN), ...
accumarray(A(:,1),A(:,3),[],#mean,NaN)]
You can use consolidator to do the work for you.
[Afinal(:,1),Afinal(:,2:3)] = consolidator(A(:,1),A(:,2:3),#mean);
Afinal
Afinal =
1 22.5 14
2 27 15
3 22.5 16
4 21 19
5 24.5 15