Matlab precision [duplicate] - matlab

This question already has answers here:
Why is 24.0000 not equal to 24.0000 in MATLAB?
(6 answers)
Closed 7 years ago.
I have a question about the precision in Matlab. I searched the questions here and they mention that there are precision problems when using very large or very small numbers and other posts looking at the comparison of numbers. My case is a bit different
I do not have that, my numbers have only 4 decimal places and I want them to add up to one.
Example:
Initial data:
aeb =
0.231215677537590 0.470472652172102 0.203009018534716
0.087759104877338 0.007588684370711
Then I rounded it to get 4 decimals:
aeb = round(aeb*10000)/10000
0.231200000000000 0.470500000000000 0.203000000000000
0.087800000000000 0.007600000000000
Then I identify the largest number and replace it by the difference with one
[~, idx]=max(aeb);
aeb(idx)=0;
aeb(idx)= 1 - sum(aeb);
But when I then do:
1 - sum(aeb)
1.110223024625157e-16
Does anyone know how I can make them add to one ? I just want 3-5 decimal places.

Their sum is within machine epsilon of the number one. The short answer is that any difference that small is indistinguishable from zero.
A practical point to be aware of....
In a lot of computing contexts, you don't want to test for equality, you want to test if the difference is within a certain tolerance. Eg.
abs(x - y) < tol

Related

MATLAB bug with absolute value and conditional statement [duplicate]

This question already has answers here:
Why is 24.0000 not equal to 24.0000 in MATLAB?
(6 answers)
Is floating point math broken?
(31 answers)
Closed 7 months ago.
While learning MATLAB, I came across a strange problem with my code. I am trying to receive a number as user input and determine whether the inputted number is in the desired range of 5.4±0.1. As you can see below, I took absolute value of the difference between input and 5.4 and checked if it is less than or equal to 0.1. By the code, any number between 5.3 and 5.5 should output "Part is good," but strangely, it doesn't work for the lower bound, 5.3. Every number between 5.3 and 5.5 works except for 5.3, and even 5.5 (the upper bound) works well. I am wondering if there is something with MATLAB that I am not aware of yet. Thank you!
part = input("Enter the length of a part"); %user input (height)
if (part<0) %if input is a negative number
error("Illegal input"); %error message
elseif (abs(part-5.4) <= 0.1) %if input is 5.4+-0.1
disp("Part is good"); %display 'part is good'
else % if not
disp("Part is not good"); %display 'part is bad'
end
First, none of the numbers you are dealing with except 5.5 can be represented exactly in IEEE double precision floating point binary. So you cannot rely on these edge cases to work out exactly as if they were represented exactly in floating point decimal because they aren't. To see this, here are the exact conversions of the underlying floating point binary bit patterns to decimal which show why one edge calculation works and the other doesn't. Bottom line is you need to use tolerances (e.g., something slightly bigger than 0.1) or do your calculations differently if you want your edge cases to work as expected in decimal. This isn't a MATLAB bug ... it is simply how floating point binary calculations work. Any language that uses IEEE floating point in the background will have the same issues that must be accounted for by the programmer when writing code.
A more detailed discussion can be found here: Why is 24.0000 not equal to 24.0000 in MATLAB?

Floating Point Number Overflow [duplicate]

This question already has an answer here:
How to deal with overflow and underflow?
(1 answer)
Closed 7 years ago.
I have to create a function where I need to square values. I am told that even if the initial value is not too big or is not too small, the value squared might still overflow (returns inf) or underflow (returns 0), and I need to figure out how to prevent that.
My problem is I do not even understand what numbers can cause an overflow when squared when the number itself is not too large.
I thought it might be for the not too small numbers, e.g. 1/3 with repeating decimal numbers, but MATLAB just turns that into 0.3333.
Can someone give me an example of such a number or explain what kind of numbers would cause this?
For underflow, let's consider Planck's constant: 6.626070040e-34
sqrt(6.626070040e-34)
ans =
2.5741e-17
Well, that's apparently not small enough, let's go smaller:
sqrt(6.626070040e-340)
ans =
0
There's your underflow.
Overflow can be seen the same way, just use big numbers:
sqrt(6.626070040e34)
ans =
2.5741e+17
sqrt(6.626070040e340)
ans =
Inf
Underflow means the numbers are too small for MATLAB to handle, overflow means they are too big for MATLAB to handle.
Thanks to #obchardon here are the numbers on my MATLAB R2012a 64bits system:
realmax('double') %//largest allowed double
ans =
1.7977e+308
realmin('double') %//smallest allowed double
ans =
2.2251e-308
Now that we know what the largest possible value is that MATLAB can handle, let's try going below that and square it:
(realmax('double')-10).^2
ans =
Inf
so the number we tried to square here (realmax('double')-10) is allowable by MATLAB, but not squarable.

MATLAB: how can I generate 2 random numbers which sum is less than 1? [duplicate]

This question already has answers here:
Random numbers that add to 100: Matlab
(4 answers)
Closed 9 years ago.
Does anybody know how to generate two random numbers which sum is less than one?
I found only topics describing how to generate 2 random numbers which add up to 1 (trough normalization)
Generate the first random number, r1.
Generate a random number less than 1 to be the random sum.
Define r2 as (sum - r1).
Assuming you don't care too much about the distribution:
x = rand(2,1);
if sum(x)>1
x=x/2;
end
Modifying normKrumpe's answer, I'd suggest
Generate the sum as a random number.
Generate a random number r1 less than (or <=?) the sum.
r2 = sum-r1.

Why is the 100*0.07 equal to 6.9999....? [duplicate]

This question already has answers here:
Why is 24.0000 not equal to 24.0000 in MATLAB?
(6 answers)
Closed 5 years ago.
One of my friends wrote the following in Matlab and the outputs are little weird:
for p=0.01:0.01:0.1
100*p
end
The following was the output:
1
2
3
4
5
6.000000000000001
6.999999999999999
8
9
10
I'd like to know why there is a slight error? Does this mean that, the accuracy in the general case is also as poor as it is in this case?
EDIT:
We compared the numbers -- 7==6.999999999999999 and the output was 0. So, Matlab contradicts itself!
The problem is that 0.01 cannot be exactly represented in binary floating-point. Neither can 0.07.
Looks like a floating point precision "issue": http://www.lahey.com/float.htm
Try
x = ((0.07+1)*100) - 100
;-)

Using rand in matlab to produce numbers between limits [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is there a way in Matlab using the pseudo number generator to generate numbers within a specific range?
I want to get 20 random integer numbers between -10 and 10 and I thought of using the rand function in matlab.
I thought of myltiplying by ten and then finding a way to get only the ones between -10 and 10 and use an iteration for each of the other numbers that is outside the limits [-10,10] to get a new number inside the limits.
Is there a better, faster way?
Use
randomIntegers = randi([-10,10],[20,1])
to generate a vector of random integers between -10 and 10.
Although Jonas' solution is really nice, randi isn't in some of the early versions of MATLAB. I believe all versions have rand. A solution using rand would be:
randomIntergers = floor(a + (b-a+1) .* rand(20,1));
where [a,b] is the range of values you want a distribution over.
If you are use round(a + (b-a)) you will have a nonuniform effect on the values of 'a' and 'b'. This can be confirmed using the hist() function. This is because the domain that maps into 'a' and 'b' is half the size for all other members of the range.