The value is absolute integer, not a floating point to be doubted, also, it is not about an overflow since a double value can hold until 2^1024.
fprintf('%f',realmax)
179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
The problem I am facing in nchoosek function that it doesn't produce exact values
fprintf('%f\n',nchoosek(55,24));
2488589544741302.000000
While it is a percentage error of 2 regarding that binomian(n,m)=binomial(n-1,m)+binomial(n-1,m-1) as follows
fprintf('%f',nchoosek(55-1,24)+nchoosek(55-1,24-1))
2488589544741301.000000
Ps: The exact value is 2488589544741300
this demo shows
What is wrong with MATLAB?
Your understanding of the realmax function is wrong. It's the maximum value which can be stored, but with such large numbers you have a floating point precision error far above 1. The first integer which can not be stored in a double value is 2^53+1, try 2^53==2^53+1 for a simple example.
If the symbolic toolbox is available, the easiest to implement solution is using it:
>> nchoosek(sym(55),sym(24))
ans =
2488589544741300
There is a difference between something that looks like an integer (55) and something that's actually an integer (in terms of variable type).
The way you're calculating it, your values are stored as floating point (which is what realmax is pointing you to - the largest positive floating point number - check intmax('int64') for the largest possible integer value), so you can get floating point errors. An absolute difference of 2 in a large value is not that unexpected - the actual percentage error is tiny.
Plus, you're using %f in your format string - e.g. asking it to display as floating point.
For nchoosek specifically, from the docs, the output is returned as a nonnegative scalar value, of the same type as inputs n and k, or, if they are different types, of the non-double type (you can only have different input types if one is a double).
In Matlab, when you type a number directly into a function input, it generally defaults to a float. You have to force it to be an integer.
Try instead:
fprintf('%d\n',nchoosek(int64(55),int64(24)));
Note: %d not %f, converting both inputs to specifically integer. The output of nchoosek here should be of type int64.
I don't have access to MATLAB, but since you're obviously okay working with Octave I'll post my observations based on that.
If you look at the Octave source code using edit nchoosek or here you'll see that the equation for calculating the binomial coefficient is quite simple:
A = round (prod ((v-k+1:v)./(1:k)));
As you can see, there are k divisions, each with the possibility of introducing some small error. The next line attempts to be helpful and warn you of the possibility of loss of precision:
if (A*2*k*eps >= 0.5)
warning ("nchoosek", "nchoosek: possible loss of precision");
So, if I may slightly modify your final question, what is wrong with Octave? I would say nothing is wrong. The authors obviously knew of the possibility of imprecision and included a check to warn users when that possibility arises. So the function is working as intended. If you require greater precision for your application than the built-in function provides, it looks as though you'll need to code (or find) something that calculates the intermediate results with greater precision.
Related
I have training data, that are train_input (194x11 matrix) and train_output (194x1 ordinal).
class(train_input) gives the result double and class(train_output) gives the result ordinal. I run them using mnrfit in Matlab. The command is basically
[B,dev,stats] = mnrfit(train_output, train_input)
I get the error message:
Inputs must be floats, namely single or double.
I converted the ordinal output into double and this time the error is
If Y is a column vector, it must contain positive integer category numbers
I tried to make them categorical, bu this time I get
Creating an instance of the Abstract class 'categorical' is not allowed
The Matlab tutorial says that I keep them ordinal or categorical in order to apply mnrfit.
I also tried to run the examples myself, I get the last "categorical" error.
What might the problem be?
The problem is that you are not inputting floats. That's exactly what the error says. An ordinal is not a double or single, therefore it does not work.
This page on the documentation shows examples and as far as I can see you need doubles for both X and Y. Try running the examples yourself and check the classes of their inputs.
I'm working with an algorithm, which uses hyperbolic functions and in order to get more accurate results from it I need to increase the precision, so I would like to do it by vpa function means, but I'm not quite sure how to implement it. Here some code to clarify the situation further:
x=18; %the hyperbolic relation is valid until x=18
cosh(x)^2-sinh(x)^2
ans = 1
x=19; %the hyperbolic relation is no longer valid
cosh(x)^2-sinh(x)^2
ans = 0
working with the VPA function:
a=vpa('cosh(40)',30); %the hyperbolic relation is valid beyond x=19
b=vpa('sinh(40)',30);
a^2-b^2
ans = 1.00008392333984375
the problem now is that I don't know how to get the value from VPA with a variable of control 'x'
I tried this but it didn't work:
x=40;
a=vpa('cosh(x)',x,30);
b=vpa('sinh(x)',30);
a^2-b^2
When doing symbolic math or variable precision arithmetic one must be careful with with converting between floating-point. In this case, you need to convert your input, x, to variable precision before passing it in to cosh or sinh (otherwise only the output of these will be converted to variable precision). For your example:
x = vpa(40,30);
a = cosh(x);
b = sinh(x);
a^2-b^2
which returns the expected 1.0. I'm not sure where you found the the use of vpa with string inputs, but that form is no longer used (using strings may even result in different results due to different functions being called). Note also that the default setting for digits in current versions of Matlab is 32.
I am trying to solve a non-linear system of equations using the Newton-Raphson iterative method, and in order to explore the parameter space of my variables, it is useful to store the previous solutions and use them as my first initial guess so that I stay in the basin of attraction.
I currently save my solutions in a structure array that I store in a .mat file, in about this way:
load('solutions.mat','sol');
str = struct('a',Param1,'b',Param2,'solution',SolutionVector);
sol=[sol;str];
save('solutions.mat','sol');
Now, I do another run, in which I need the above solution for different parameters NewParam1 and NewParam2. If Param1 = NewParam1-deltaParam1, and Param2 = NewParam2 - deltaParam2, then
load('solutions.mat','sol');
index = [sol.a]== NewParam1 - deltaParam1 & [sol.b]== NewParam2 - deltaParam2;
% logical index to find solution from first block
SolutionVector = sol(index).solution;
I sometimes get an error message saying that no such solution exists. The problem lies in the double precisions of my parameters, since 2-1 ~= 1 can happen in Matlab, but I can't seem to find an alternative way to achieve the same result. I have tried changing the numerical parameters to strings in the saving process, but then I ran into problems with logical indexing with strings.
Ideally, I would like to avoid multiplying my parameters by a power of 10 to make them integers as this will make the code quite messy to understand due to the number of parameters. Other than that, any help will be greatly appreciated. Thanks!
You should never use == when comparing double precision numbers in MATLAB. The reason is, as you state in the the question, that some numbers can't be represented precisely using binary numbers the same way 1/3 can't be written precisely using decimal numbers.
What you should do is something like this:
index = abs([sol.a] - (NewParam1 - deltaParam1)) < 1e-10 & ...
abs([sol.b] - (NewParam2 - deltaParam2)) < 1e-10;
I actually recommend not using eps, as it's so small that it might actually fail in some situations. You can however use a smaller number than 1e-10 if you need a very high level of accuracy (but how often do we work with numbers less than 1e-10)?
I'm having the following issue with my code. I've been trying to use some other posts that I found on line, like this one. But they didn't what I'm looking for.
My code uses a MATLAB Exchange function which optimize a numerical value that is important to be with 32 digits after the dot such as
0.59329669191989231613604260928696
The optimization function can be found here and it is called fminsearchbnd
The optimization function calculate this and store the value in a variable that I use all over my code. In order not to perform the optimization everytime I want to store the variable (I tried either on a *.mat and on a label in the string form.
But when I retrieve it, MATLAB transforms it in a double precision variable 'cutting' all the numbers after the 14th. However I need all of them because they are important!
Is it possible to read a number like that w/o using vpa() because with a symbolic value I can't do anything.
Any help is really appreciated.
Thanks
EDIT:
fminsearchbnd gives me this class(bb) -> double and when I want to see it on the workspace it is 0.586675392365899. But when I set formatSpec = '%.32f\n'; because I want to see all the numbers that the optimization gives me, typing set(editLabel,'String',num2str(bb,formatSpec))
You're trying to store/use a number that cannot be represented exactly in an IEEE754 64-bit double-precision floating point number.
I'm not sure how you got that number without using vpa() in the first place, since 64-bit double is Matlab's maximum of precision...
You could use the multiple precision toolbox by Ben Barrowes, or HPF by John d'Errico, also from the FEX. You'll have to convert/construct to/from string if you want to store/load it to/from file.
But I have to agree with John's comment there:
The fact is, most of the time, if you can't do it with a double, you
are doing something wrong
so...why exactly are those 32-or-more digits important?
%function [flag] =verify(area)
[FileName,PathName,FilterIndex]= uigetfile('*.tif','Select the signature file');
display(PathName)
m=[PathName,FileName];
area=nor_area(m);
%display(area)
%area=0.8707;
class(area)
flag=0;
extract=xlsread('D:\Project\Image_processing\important\best.xlsx', 'CW4:CW17');
c=numel(extract);
display(c)
l=extract(1);
class(l)
display(l)
for k = 1:c
%x=extract(k);
if (l==area && flag==0)
% display(extract(k));
flag=1;
display(flag)
end
end
display(flag)
The above is my code for verification, i am not able to compare "l==area", even if the values are same am not able to enter inside the loop. If i try passing the value assume l=0.9999 and the area that i obtain to be the same , if i sent l value explicitly it works..!! but if i try using some function and pass the same value it wont work. I have tried checking the type by using class, both returns double.
Can anyone please help me out with this and if this approach is not good, suggest any alternative that may be used.
It is not generally a good idea to compare floats like you are doing (with the == operator) since floats, unlike integer values are subject to round off. See here and here for a discussion on comparing floats in MATLAB.
Essentially you have to check that two floats are 'close enough' rather than exactly equal, which is what == checks for. MATLAB has a built in function eps for determining the floating point precision on your machine, so use that function when comparing floats. See its documentation for more information.
In most cases it is not wise to compare floating point numbers by a == b. Use abs(a-b)<epsilon where epsilonis some small tolerance like 1e-10 instead.