how to remove decimal trailing zeros in matrix (C) in matlab.
65.7500 4.7500 4.7500 64.0000 60.0000
118.9000 105.6000 92.5500 147.6000 178.2000
73.6600 84.0100 95.6900 190.0000 164.0000
147.9000 132.0000 140.0000 147.0000 116.5000
ans=
65.75 4.75 4.75 64 60
118.9 105.6 92.55 147.6 178.2
73.66 84.01 95.69 190 164
147.9 132 140 147 116.5
>> format short g
>> C
C =
65.75 4.75 4.75 64 60
118.9 105.6 92.55 147.6 178.2
73.66 84.01 95.69 190 164
147.9 132 140 147 116.5
Related
Ive been looking at implementing GLCM within MATLAB using graycomatrix. There are two arguments that I have discovered (NumLevels and GrayLimits) but in in my research and implementation they seem to achieve the same result.
GrayLimits specified bins between a range set [low high], causing a restricted set of gray levels.
NumLevels declares the number of gray levels in an image.
Could someone please explain the difference between these two arguments, as I don't understand why there would be two arguments that achieve the same result.
From the documentation:
'GrayLimits': Range used scaling input image into gray levels, specified as a two-element vector [low high]. If N is the number of gray levels (see parameter 'NumLevels') to use for scaling, the range [low high] is divided into N equal width bins and values in a bin get mapped to a single gray level.
'NumLevels': Number of gray levels, specified as an integer.
Thus the first parameter sets the input gray level range to be used (defaults to the min and max values in the image), and the second parameter sets the number of unique gray levels considered (and thus the size of the output matrix, defaults to 8, or 2 for binary images).
For example:
>> graycomatrix(img,'NumLevels',8,'GrayLimits',[0,255])
ans =
17687 1587 81 31 7 0 0 0
1498 7347 1566 399 105 8 0 0
62 1690 3891 1546 298 38 1 0
12 335 1645 4388 1320 145 4 0
2 76 305 1349 4894 959 18 0
0 16 40 135 965 7567 415 0
0 0 0 2 15 421 2410 0
0 0 0 0 0 0 0 0
>> graycomatrix(img,'NumLevels',8,'GrayLimits',[0,127])
ans =
1 9 0 0 0 0 0 0
7 17670 1431 156 50 31 23 15
1 1369 3765 970 350 142 84 92
0 128 1037 1575 750 324 169 167
0 46 361 836 1218 747 335 260
0 16 163 330 772 1154 741 547
0 10 74 150 370 787 1353 1208
0 4 67 136 294 539 1247 21199
>> graycomatrix(img,'NumLevels',4,'GrayLimits',[0,255])
ans =
28119 2077 120 0
2099 11470 1801 5
94 1829 14385 433
0 2 436 2410
As you can see, these parameters modify the output in different ways:
In the first case above, the range [0,255] was mapped to columns/rows 1-8, putting 32 different input grey values into each.
In the second case, the smaller range [0,127] was mapped to 8 indices, putting 16 different input grey values into each, and putting the remaining grey values 128-255 into the 8th index.
In the third case, the range [0,255] was mapped to 4 indices, putting 64 different input grey values into each.
I have a file named Myfile.txt with a header and three rows of data:
Header Row1 Row2 Row3
5.10 10 15
5.20 20 25
5.30 30 35
5.40 40 45
5.50 50 55
5.60 60 65
5.70 70 75
5.80 80 85
5.90 90 95
5.95 10 20
6.00 25 30
6.05 35 40
I want to read in every 3 lines that increment the first column by .1 and then all lines after the increment to .05, so my output looks like:
5.30 30 35
5.60 60 65
5.90 90 95
5.95 10 20
6.00 25 30
6.05 35 40
I have the following code but I don't know how to implement the condition, can I get some help doing this?
per_line = 3;
every_nth_line = 3;
fmt = [repmat('%*f',1,per_line*(every_nth_line-1)), repmat('%f',1,per_line)];
fid = fopen('Myfile.txt','rt');
datacell = textscan(fid,fmt,'delimiter','\n','HeaderLines',1,'CollectOutput',1);
fclose(fid);
C=datacell{1};
You can use the following code:
fileID = fopen('Myfile.txt');
mydata = textscan(fileID,'%f%f%f','HeaderLines',2);
findx = (find(abs(diff([mydata{1}(1)-0.1;mydata{1}])-0.1000)<0.0001));
sindx = (find(abs(diff(mydata{1})-0.05)<0.0001))+1;
alldata = [mydata{:}];
C= [alldata(findx(3:3:end),:);alldata(sindx,:)];
fclose(fileID);
diff is used to determine the difference between entries in the first column. abs is used to determine equality between floating point numbers within a small difference, and find is used to return their indexes.
C contains:
5.3000 30.0000 35.0000
5.6000 60.0000 65.0000
5.9000 90.0000 95.0000
5.9500 10.0000 20.0000
6.0000 25.0000 30.0000
6.0500 35.0000 40.0000
I'm plotting a scatter plot and would like to have the a-axis as entry named than index. My data is from MASS in R and looks like this
animals={'Mountain beaver';'Cow';'Grey wolf';'Goat';'Guinea pig';'Dipliodocus';'Asian elephant';'Donkey';'Horse';'Potar monkey';'Cat';'Giraffe';'Gorilla';'Human';'African elephant';'Triceratops';'Rhesus monkey';'Kangaroo';'Golden hamster';'Mouse';'Rabbit';'Sheep';'Jaguar';'Chimpanzee';'Rat';'Brachiosaurus';'Mole';'Pig'};
body=[1.35 465 36.33 27.66 1.04 11700 2547 187.1 521 10 3.3 529 207 62 6654 9400 6.8 35 0.12 0.023 2.5 55.5 100 52.16 0.28 87000 0.122 192];
brain=[8.1 423 119.5 115 5.5 50 4603 419 655 115 25.6 680 406 1320 5712 70 179 56 1 0.4 12.1 175 157 440 1.9 154.5 3 180];
% Plot
x=1:length(body);
scatter(x,body,'filled','d')
hold
scatter(x,brain,'filled')
legend('body', 'brain','location','east');
How could I amend the program so my scatterplot display animals in xticks with 45 degrees?
I think this is what you want:
% add these lines at the end of your code
set(gca,'XTickLabel',animals)
set(gca,'XTick',1:numel(animals));
xlim([0 numel(animals)+1]);
set(gca, 'XTickLabelRotation', 45);
which gives this:
Let's we are given a number that we would like to compare it with the whole numbers which are in a column of matrix. For example:
value = 210;
A = [
0.0010 68
0.0011 277
0.0011 129
0.0012 87
0.0015 78
0.0016 248
0.0019 270
0.0019 133
0.0022 258
0.0025 264
0.0029 255
0.0030 81
0.0032 242
0.0033 27
0.0036 124];
Now, we want to compare value with all the numbers in column two under a condition and if it satisfies for all the numbers in the second column then do some computations otherwise do some other computations. If it does not hold for one then exit and continue code.
In the example:
if abs(value - A(:,2)) > 50 % should be true for all A(:,2)
do something
else
do something
How could one write it in code?
I have a p-by-p-by-n tensor. I want to extract diagonal element for each p-by-p slice. Are there anyone know how to do this without looping?
Thank you.
Behold the ever mighty and ever powerful bsxfun for vectorizing MATLAB problems to do this task very efficiently using MATLAB's linear indexing -
diags = A(bsxfun(#plus,[1:p+1:p*p]',[0:n-1]*p*p))
Sample run with 4 x 4 x 3 sized input array -
A(:,:,1) =
0.7094 0.6551 0.9597 0.7513
0.7547 0.1626 0.3404 0.2551
0.2760 0.1190 0.5853 0.5060
0.6797 0.4984 0.2238 0.6991
A(:,:,2) =
0.8909 0.1493 0.8143 0.1966
0.9593 0.2575 0.2435 0.2511
0.5472 0.8407 0.9293 0.6160
0.1386 0.2543 0.3500 0.4733
A(:,:,3) =
0.3517 0.9172 0.3804 0.5308
0.8308 0.2858 0.5678 0.7792
0.5853 0.7572 0.0759 0.9340
0.5497 0.7537 0.0540 0.1299
diags =
0.7094 0.8909 0.3517
0.1626 0.2575 0.2858
0.5853 0.9293 0.0759
0.6991 0.4733 0.1299
Benchmarking
Here's few runtime tests comparing this bsxfun based approach against repmat + eye based approach for big datasizes -
***** Datasize: 500 x 500 x 500 *****
----------------------- With BSXFUN
Elapsed time is 0.008383 seconds.
----------------------- With REPMAT + EYE
Elapsed time is 0.163341 seconds.
***** Datasize: 800 x 800 x 500 *****
----------------------- With BSXFUN
Elapsed time is 0.012977 seconds.
----------------------- With REPMAT + EYE
Elapsed time is 0.402111 seconds.
***** Datasize: 1000 x 1000 x 500 *****
----------------------- With BSXFUN
Elapsed time is 0.017058 seconds.
----------------------- With REPMAT + EYE
Elapsed time is 0.690199 seconds.
One suggestion I have is to create a p x p logical identity matrix, replicate this n times in the third dimension, and then use this matrix to access your tensor. Something like this, supposing that your tensor was stored in A:
ind = repmat(logical(eye(p)), [1 1 n]);
out = A(ind);
Example use:
>> p = 5; n = 3;
>> A = reshape(1:75, p, p, n)
A(:,:,1) =
1 6 11 16 21
2 7 12 17 22
3 8 13 18 23
4 9 14 19 24
5 10 15 20 25
A(:,:,2) =
26 31 36 41 46
27 32 37 42 47
28 33 38 43 48
29 34 39 44 49
30 35 40 45 50
A(:,:,3) =
51 56 61 66 71
52 57 62 67 72
53 58 63 68 73
54 59 64 69 74
55 60 65 70 75
>> ind = repmat(logical(eye(p)), [1 1 n]);
>> out = A(ind)
out =
1
7
13
19
25
26
32
38
44
50
51
57
63
69
75
You'll notice that we grab the diagonals of the first slice, followed by the diagonals of the second slice, etc. up until the last slice. These values are all concatenated into a single vector.
Just reading Divakar's answer and trying to understand why he again is roughly 10 times faster than my idea I put together code mixing both, and ended up with code which is faster:
A=reshape(A,[],n);
diags2 = A(1:p+1:p*p,:);
For a 500x500x500 tensor I get 0.008s for Divakar's solution and 0.005s for my solution using Matlab 2013a. Probably plain indexing is the only way to beat bsxfun.