I want to calculate the percentage of accuracy. I have the code below. But it give unexpected output like this "The accuracy is 2.843137e+01x37".
While expected result is "The accuracy is 28.43%"
y %Amount of correct data
j %Amount of all data
a = 'The accuracy is %dx%d.';
percent = '%.0f%%';
format short
acc = 100 * double(y/j);
sprintf (a,acc)
How to fix it?
Any help would be so much appreciated.
Thank you.
You almost have what you expected, just put it together the right way.
The correct format specifier for 28.43% is %.2f%%. This gives you two digits after the decimal point and adds the %-sign at the end. You have that defined in the variable percent, except that .0 should be .2 for two digits as you have written in the expected result. If you look closely, you'll realize that percent is never used.
Let's come to the conclusion. Change the format specifier to the following:
a = 'The accuracy is %.2f%%';
That's all you need to do. The line defining percent can be omitted as well as format short unless you need this for something later on.
Something important regarding the cast to double: What you currently have just casts the result. If necessary, do the cast individually to y and/or j before the division. Probably you don't need any casting in your case.
The whole code with an assumption for y and j is:
y = 28.43137; %// Amount of correct data
j = 100; %// Amount of all data
a = 'The accuracy is %.2f%%';
acc = 100 * (y/j); %// no cast
% acc = 100 * (double(y)/double(j)); %// with cast
sprintf(a,acc);
Output:
ans =
The accuracy is 28.43%
Try,
a = 'The accuracy is %f.';
acc = 100 * double(y/j);
sprintf (a,acc)
Related
I have made this scripts that calculates the frequency of a given dataset, but matlab is not precise enough, is it possible to make matlab read in more accurat numbers and not cut off the numbers? I want it to use 8 digits (0.12345678) instead of 4 (0.1234) that is does now
fid = fopen('forceCoeffs.dat','rt');
A = textscan(fid, '%f%f%f%f%f%f', 'HeaderLines',9,'Collect', 9);
A = A{1};
fclose(fid);
t = A(:,1);
Fs = 1/(A(1,1));
x = A(:,2)
x = detrend(x,0);
xdft = fft(x);
freq = 0:Fs/length(x):Fs/2;
xdft = xdft(1:length(x)/2+1);
plot(freq,abs(xdft));
[~,I] = max(abs(xdft));
fprintf('Maximum occurs at %d Hz.\n',freq(I));
File: https://drive.google.com/file/d/0B9CEsYCSSZUSb1JmcHRkbFdWYUU/view?usp=sharing
Thank you for including the forceCoeffs.dat file as it allowed me to run your code. Here is an explanation of what you are seeing.
First I want to point out that MATLAB is not rounding anything. You can check the data type of A to ensure you have enough precision.
>> class(A)
ans =
double
And since you are reading in the file using %f for each column, MATLAB will use all the bits provided by the double type. Ok, now take a look at the contents of your file. The first column has only 2 decimals of precision at most.
0.05 -7.013874e-09 1.410717e+02 -6.688450e-02 -3.344226e-02 -3.344224e-02
...
349.95 -1.189524e-03 1.381022e+00 -2.523909e-01 -1.273850e-01 -1.250059e-01
350 -1.423947e-03 1.380908e+00 -2.471767e-01 -1.250123e-01 -1.221644e-01
Since no more is needed MATLAB only prints four decimal places when you look at the variable in the variable explorer. Try looking at one of the other columns to see what I am talking about. I commented out the A = A{1} part of your code and looked at the second column. When clicking on the number you see the full precision.
You can use a long type to display 16 digits
To get more than 4 digits precision, you can use
format long
However, to get exactly 8 digits, you need to round it. If your number is a then let use:
format long
round(1e8*a)*1e-8
e.g. x = 12.354
I want to get 354 from x. For this I tried this equation,
y = x - floor(x)
But this generates 0.354 which is not my requirement.
So, how can I do it?
The generic idea as pointed out by #JoachimPileborg looks like this in MATLAB:
x = 12.354;
str = num2str(x);
idx = find(str=='.');
substr = str(idx+1:end);
y = str2num(substr);
A generic solution that should work with all programming languages, is to convert the number to a string, then take the sub-string from after the decimal point (or comma) and convert it to an integer.
An alternative (possibly faster) to m.s. 's answer. Notice the 'shift' due to this approach effectively removing the zeroes to the right of the decimal point.
yfoo = 34.00267400;
yfoo = yfoo- floor(yfoo); % .00267400;
% internal rep of number ignores trailing zeros.
yrab = str2num(strrep(num2str(yfoo),'.','')); %2674
I have a program in which
e=0.01;
test3=Ask(1,2)-Bid(1,2);
(Bid and Ask are both matrices generated by a for loop).
I know that sometimes test3 could equal to e, but matlab gave me this:
>>test3
e
test3==e
test3>e
test3 =
0.0100
e =
0.0100
ans =
0
ans =
1
What's wrong with it? Thank you!
EDIT: I tried format long and then I got
Ask(1,2) =
8.620000000000001
Bid(1,2) =
8.609999999999999
test3 =
0.010000000000002
no wonder I got it wrong. But actually I've already use price=roundn(r*v,-2) and both Ask(1,2) and Bid(1,2) equal to some price so they should have two decimal places only. What can I do now if I want to round them to exactly two decimal places? Thanks again!
In general, roundoff error makes it difficult to ever compare numbers in floating point.
0.1 is a nice decimal number 1/10, but stored on a computer in binary it is a repeating fraction and not stored exactly.
So just for example:
x = 0.2;
y = 0.1 + 0.1;
x == y
will not be true.
[Well, unfortunately, as rwong points out below, this actually isn't true. I should have tried it! Octave is being a bit too smart for me at this hour. Still, in general, there will be roundoff!]
Sometimes the error will be big enough to see in the 16th digit, which is why you got the comment to try format long. But sometimes it might not be visible. The bottom line is:
NEVER USE == for two decimal numbers. It is almost always false, and usually that's meaningless.
what you want is to test if two numbers are very close to each other, which is:
abs(x-y) < 0.00001
for some small limit.
If test3 = 0.01000000000000001 or some such and e = 0.01 then you are likely to get this sort of result what happens when you print test3-e will give you a clue - this is why in the safety critical field float == float is always something that raises an alarm bell with auditors.
I want to compare two double values. I know the value of MinimumValue, which is 3.5261e+04. This MinimumValue I got from an array e. My code has to print first statement 'recognized face' because both value are same. But my code is displaying second statement 'unrecognized face'.
What is the mistake in my code?
MinimumValue = min(e)
theta = 3.5261e+04;
if (MinimumValue <= theta)
fprintf('recognized face\n');
else
fprintf('unrecognized face\n');
end
There are two approaches:
Replace if MinimumValue<=theta with if MinimumValue == theta. This is the easier but probably poorer approach for your problem.
Chances are, MinimumValue is different from theta by a very small amount. If you are doing some calculations by hand to determine that theta = 3.5261e+04, and believe there are more decimal places, you should use format long to determine the actual value of theta to 15 significant figures. After that, you can use if abs(MinimumValue - theta) <= eps (edit: As patrick has noted in the comment below, you should compare to some user-defined tolerance or eps instead of realmin('double').
I have a homework problem, I think I did it correctly but need to make sure 100%. Can anyone check for me, before I hand it in?
Thank you.
Question:
Plot the function given by f (x) = 2 sin(2x) − 3 cos(x/2) over the in-
terval [0, 2π] using steps of length .001 (How?). Use the commands max and min to estimate the maximum and minimum points. Include the maximum and minimum points as tick marks on the x-axis and the maximum and minimum values as tick marks on the y-axis.
My code:
x=linspace(0,2*pi,6280);
f=#(x)...
2.*sin(2.*x)-3.*cos(x./2);
%f = #(x)2.*sin(2.*x)-3.*cos(x./2)
g=#(x)...
-1*(2.*sin(2.*x)-3.*cos(x./2));
%g = #(x)-1*(2.*sin(2.*x)-3.*cos(x./2))
[x3,y5]=fminbnd(g,0,2*pi);
%x3 = 4.0968
%y3 = -3.2647
[x2,y4]=fminbnd(f,0,2*pi);
%x2 =2.1864
%y2 = -3.2647
y2=max(f(x));
y3=min(f(x));
plot(x,f(x));
set(gca,'XTick',[x2 x3]);
set(gca,'YTick',[y2 y3]);
(*after I paste this code here, it appeared not as nice as I had it in my program, don't know why)
To create a vector with certain step do
x=0:0.001:2*pi;
Why do you have g(x) function and why are you using fminbind? Use MIN and MAX, return index of those values and find related x values.
[ymin, minindex] = min(f(x));
xmin = x(minindex);
For general case if you have multiple min/max values, index will contain only the first occurrence. Instead you can do:
minindex = find(y==ymin);
Or for real values to avoid precision error:
minindex = find(abs(y-ymin)<=eps);
Also your last statement returns error Values must be monotonically increasing. To avoid it sort your tick values.
set(gca,'XTick',sort([xmin xmax]));
set(gca,'YTick',sort([ymin ymax]));