In MATLAB, INF means infinity and NAN means Not a Number
Apparently both these seem similar but there must be some difference ,because of which MATLAB makes represents them separatley?
Why in some operations output is Inf while in others , output is NAN?
Mathematically they are two different concepts. While in real analysis, infinity is not a real number it does represent an unbounded limit and is part of the set that makes up extended real numbers. That makes infinity a symbol that can result from a mathematical operation, i.e. it is a valid answer.
A NaN, on the other hand, represents a result that is not numerical.
I like to initialize floating point arrays when allocated to NaN because it will make certain bugs (e.g. off by one errors) obvious.
Related
Can someone please explain why the following symmetric function cannot pass a certain limit of negative values?
D = 0.1; l = 4;
c = #(x,v) (v/D).*exp(-v*x/D)./(1-exp(-v*l/D));
v_vec = -25:0.01:25;
figure(2)
hold on
plot(v_vec,c(l,v_vec),'b')
plot(v_vec,c(0,v_vec),'r')
Notice at the figure where the blue line chops, this is where I get inf/nan values.
It seems that Matlab is trying to compute a result that is too large, outputs +inf, and then operates on that, which yields +/- inf and NaNs.
For instance, at v=-25, part of the function computes exp(-(-25)*4/0.1), which is exp(1000), and that outputs +inf. (larger than the largest representable double precision float).
You can potentially solve that problem by rewriting your function to avoid operating of such very large (or very small) numbers, say by reorganising the fraction containing exp() functions.
I did encounter the same hurdle using exp() with arguments triggering overflow. Sometimes it is difficult to trace back numeric imprecision or convergence errors. In principle the function definition using exp() only create intermediate issues as your purpose as a transition function. The intention I guess was to provide a continuous function.
My solution to this problem is to divide the argument into regions and provide in each region an approximation function. In your case zero for negative x and proportional to x for positive x. In between you can use the orginal function. Care should be taken to match the approximation at the borders of the regions and the number of continuous differentiations which is important for convergence in loops.
Basically I wanted to ask two things:
Why does this happen? (negative zero in Matlab)
When does this happen?
I came up with this. Octave has some similarities with Matlab, so the usefulness of this feature is clear, but one of the things they said, is that it does not appear in the default output. and I just tackled it right now. So, maybe a new insight on this?
For the second question, in the answered question I referred to, they just said it could happen in some calculations, and in the following calculation which I just did, it doesn't seem really necessary to use (or get) that negative zero.
The code where I encountered this is:
xcorr([1 0 1 1], [0 1 1 0 0])
where it's output is:
-0.0000 -0.0000 1.0000 1.0000 1.0000 2.0000 1.0000 0.0000 0.0000
The xcorr is actually a cross corelation function, which does only some simple operations like summing and multiplications, where it's exact function details can be found here. Anyway, nothing like "complex branch cuts and transformations of the complex plane"
Thanks
These values do not represent zeros. Instead, they are negative values which are very close to zero.
The reason for getting these values and not simply zeros is due to approximations which are performed in the function implementation. According to Matlab documentation: "xcorr estimates the cross-correlation sequence of a random process".
In other words - the values which are displayed on the screen are just approximations for negative values.
In order to test this, you can change the display format of Matlab.
code:
format shortE;
xcorr([1 0 1 1], [0 1 1 0 0])
Result:
ans =
Columns 1 through 5
-6.2450e-017 -5.5511e-017 1.0000e+000 1.0000e+000 1.0000e+000
Columns 6 through 9
2.0000e+000 1.0000e+000 1.1102e-016 1.1796e-016
As you can see, the values in coordinates 1,2,8 and 9 are actually negative.
In the specific sample case, the -0.0000 turned out to actually be tiny non-zero negative numbers. However, in an effort to make printout human readable, Matlab and Octave tries to avoid using scientific notation in printing. As a result, when mixed with big numbers, small number are reduced to 0.0000 or -0.000. This can be changed by setting the default preferences in Matlab or Octave.
But this is NOT the only answer to the asked questions:
Why does this happen? (negative zero in Matlab),
When does this happen?
In fact, in Matlab and Octave, and any computing environment that works with floating points, -0. really a thing. This is not a bug in the computing environment, but rather an allowance in the IEEE-754 standard for binary representation of a floating point number, and it is a product of the floating point processor in the CPU (not the programming language).
Whereas binary representation of integer does not have a special sign bit, IEEE-754 reserves a bit for the sign, separate from the number. So while the number part might mean 0, the sign bit is left to mean negative.
It happens wherever your CPU (Intel or AMD) does a product with 0. and any negative number (including -0.). I don't know if it is required by IEEE-754 for that to happen or if it simply the result of CPU design optimization (maximize speed, minimize size).
In either case, this -0. is a non-issue in that IEEE-754 requires it to be comparatively and arithmetically exactly the same as 0.. That is:
-0. < 0 --> FALSE
-0. == 0 --> TRUE
1+ -0. == 1 --> TRUE
etc...
In real probability, there is a 0% chance that a random number p, selected from all of the real numbers in the interval (0,1), will be 0.5. However, what are the odds that
rand == 0.5
in MATLAB? I suppose this is like asking how many double-precision numbers are between zero and one, or maybe there are other factors at play.
No particular info on MATLAB's generator...
In general even simple pseudo-random generators have long enough cycles which would cover all values representable by double.
If MATLAB uses some other form of generating random numbers it would be even better - so assuming it uniformly covers whole range of double values.
I believe probability would be: distance between representable numbers around values you are interested divided by length of the interval. See What is the minimal step in double data type? (.NET) for discussion on the distance.
Looking at this question, we see that there are 262 - 252
doubles in the interval (0 1). Therefore, the probability of picking any single one (like 0.5) would be roughly equal to one divided by this number, or
>> p = 1/(2^62-2^52)
ans =
2.170523997312134e-019
However, as horchler already indicates, it also depends on the type of random number generator you use, as well as MATLAB's implementation thereof. Sadly, I have only basic knowledge on the implementaion details for each, but you can look here for a list of available random number generators in MATLAB and google a bit further for more precise numbers.
I am not sure whether Alexei was trying to say this, but inspired by him I think the probability will indeed be approximately the distance between numbers around 0.5.
Therefore I expect the probability to be approximately:
eps(0.5)
Which evaluates to 1.1102e-16
Given the monotonic nature of the difference between double numbers I would actually think this holds:
eps(0.5-eps(0.5)) <= yourprobability <= eps(0.5)
Implying a range of 5.5511e-17 to 1.1102e-16
Is it possible that the determinant of a positive semi definite matrix is equal to 0. It is coming to be zero in my case. I have a diagonal matrix with diagonal elements non zero. When I try to calculate the determinant of this matrix it is coming out to be 0. Why is it so?
This is the reason why computing the determinant is never a good idea. Yeah, I know. Your book, your teacher, or your boss told you to do so. They were probably wrong. Why? Determinants are poorly scaled beasts. Even if you compute the determinant efficiently (many algorithms fail to do even that) you don't really want a determinant most of the time.
Consider this simple positive definite matrix.
A = eye(1000);
What is the determinant? I need not even bother. It is 1. But, if you insist...
det(A)
ans =
1
OK, so that works. How about if we simply multiply that entire matrix by a small constant, 0.1 for example. What is the determinant? You might say there is no reason to bother, as we already know the determinant. It must be just det(A)*0.1^1000, so 1e-1000.
det(A*0.1)
ans =
0
What did we do wrong here? Where this failed is we forgot to remember we were working in floating point arithmetic. Since the dynamic range of a double in MATLAB goes down only to essentially
realmin
ans =
2.2250738585072e-308
then smaller numbers turn into zero - they underflow. Anyway, most of the time when we compute a determinant, we are doing so for the wrong reasons anyway. If they want you to test to see if a matrix is singular, then use rank or cond, not det.
by definition, a positive semi definite matrix may have eigenvalues equal to zero, so its determinant can therefore be zero
Now, I can't see what you mean with the sentence,
I have a diagonal matrix with diagonal elements non zero. When I try to calculate the ...
If the matrix is diagonal, and all elements in the diagonal are non-zero, the determinant should be non-zero. If you are calculating it in your computer, beware underflows.
You may consider the sum of logarithms instead of the product of the diagonal elements
eps returns the distance from 1.0 to the next largest double-precision number, so I can use it to interpret the numbers value on negative weight position. But for very large number with value on high positive weight position, what can I use to interpret?
I mean that I need to have some reference to count out computation noise on numbers obtained on Matlab.
Have you read "What Every Computer Scientist Should Know About Floating-Point Arithmetic"?
It discusses rounding error (what you're calling "computation noise"), the IEEE 754 standard for representation of floating-point numbers, and implementations of floating-point math on computers.
I believe that reading this paper would answer your question, or at least give you more insight into exactly how floating point math works.
Some clarifications to aid your understanding - too big to fit in the comments of #Richante's post:
Firstly, the difference between realmin and eps:
realmin is the smallest normalised floating point number. You can represent smaller numbers in denormalised form.
eps is the smallest increment between distinct numbers. realmin = eps(realmin) * 2^52.
"Normalised" and "denormalised" floating point numbers are explained in the paper linked above.
Secondly, rounding error is no indicator of how much you can "trust" the nth digit of a number.
Take, for example, this:
>> ((0.1+0.1+0.1)^512)/(0.3^512)
ans =
1.0000
We're dividing 0.3^512 by itself, so the answer should be exactly one, right? We should be able to trust every digit up to eps(1).
The error in this calculation is actually 400 * eps:
>> ((0.1+0.1+0.1)^512)/(0.3^512) - 1
ans =
9.4591e-014
>> ans / eps(1)
ans =
426
The calculation error, i.e. the extent to which the nth digit is untrustworthy, is far greater than eps, the floating-point roundoff error in the representation of the answer. Note that we only did six floating-point operations here! You can easily rack up millions of FLOPs to produce one result.
I'll say it one more time: eps() is not an indicator of the error in your calculation. Do not attempt to display : "My result is 1234.567 +/- eps(1234.567)". That is meaningless and deceptive, because it implies your numbers are more precise than they actually are.
eps, the rounding error in the representation of your answer, is only 1 part per billion trillion or so. Your real enemy is the error that accumulates every time you do a floating point operation, and that is what you need to track for a meaningful estimate of the error.
Easier to digest than the paper Li-aung Yip recommends would be the Wikipedia article on machine epsilon. Then read What Every Computer Scientist ...
Your question isn't very well worded, but I think you want something that gives the distance from a number to the next smallest double-precision number? If this is the case, then you can just use:
x = 100;
x + eps(x) %Next largest double-precision number
x - eps(-x) %Next smallest double-precision number
Double-precision numbers have a single sign bit, so counting up from a negative number is the same as counting down from a positive.
Edit:
According to help eps, "For all X, EPS(X) is equal to EPS(ABS(X))." which really confuses me; I can't see how that can be consistent with double having a single sign bit, and values not being equally spaced.