Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
424 views
in Technique[技术] by (71.8m points)

numerical methods - How to calculate machine epsilon in MATLAB?

I need to find the machine epsilon and I am doing the following:

eps = 1;

while 1.0 + eps > 1.0 do
    eps = eps /2;
end

However, it shows me this:

Undefined function or variable 'do'. 
Error in epsilon (line 3) 
while 1.0 + eps > 1.0 do

What should I do?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

First and foremost, there is no such thing as a do keyword in MATLAB, so eliminate that from your code. Also, don't use eps as an actual variable. This is a pre-defined function in MATLAB that calculates machine epsilon, which is also what you are trying to calculate. By creating a variable called eps, you would shadow over the actual function, and so any other functions in MATLAB that require its use will behave unexpectedly, and that's not what you want.

Use something else instead, like macheps. Also, your algorithm is slightly incorrect. You need to check for 1.0 + (macheps/2) in your while loop, not 1.0 + macheps.

In other words, do this:

macheps = 1;

while 1.0 + (macheps/2) > 1.0
    macheps = macheps / 2;
end

This should give you 2.22 x 10^{-16}, which agrees with MATLAB if you type in eps in the command prompt. To double-check:

>> format long
>> macheps

macheps =

     2.220446049250313e-16

>> eps

ans =

     2.220446049250313e-16

Bonus

In case you didn't know, machine epsilon is the upper bound on the relative error due to floating point arithmetic. In other words, this would be the maximum difference expected between a true floating point number and one that is calculated on a computer due to the finite number of bits used to store a floating point number.

If you recall, floating numbers inevitably are represented as binary bits on your computer (or pretty much anything digital). In terms of the IEEE 754 floating point standard, MATLAB assumes that all numerical values are of type double, which represents floating point numbers as 64-bits. You can obviously override this behaviour by explicitly casting to another type. With the IEEE 754 floating point standard, for double precision type numbers, there are 52 bits that represent the fractional part of the number.

Here's a nice diagram of what I am talking about:

Source: Wikipedia

You see that there is one bit reserved for the sign of the number, 11 bits that are reserved for exponent base and finally, 52 bits are reserved for the fractional part. This in total adds up to 64 bits. The fractional part is a collection or summation of numbers of base 2, with negative exponents starting from -1 down to -52. The MSB of the floating point number starts with2^{-1}, all the way down to 2^{-52} as the LSB. Essentially, machine epsilon calculates the maximum resolution difference for an increase of 1 bit in binary between two numbers, given that they have the same sign and the same exponent base. Technically speaking, machine epsilon actually equals to 2^{-52} as this is the maximum resolution of a single bit in floating point, given those conditions that I talked about earlier.

If you actually look at the code above closely, the division by 2 is bit-shifting your number to the right by one position at each iteration, starting at the whole value of 1, or 2^{0}, and we take this number and add this to 1. We keep bit-shifting, and seeing what the value is equal to by adding this bit-shifted value by 1, and we go up until the point where when we bit shift to the right, a change is no longer registered. If you bit-shift any more to the right, the value will become 0 due to underflow, and so 1.0 + 0.0 = 1.0, and this is no longer > 1.0, which is what the while loop is checking.

Once the while loop quits, it is this threshold that defines machine epsilon. If you're curious, if you punch in 2^{-52} in the command prompt, you will get what eps is equal to:

>> 2^-52

ans =

     2.220446049250313e-16

This makes sense as you are shifting one bit to the right 52 times, and the point before the loop stops would be at its LSB, which is 2^{-52}. For the sake of being complete, if you were to place a counter inside your while loop, and count up how many times the while loop executes, it will execute exactly 52 times, representing 52 bit shifts to the right:

macheps = 1;
count = 0;
while 1.0 + (macheps/2) > 1.0
    macheps = macheps / 2;
    count = count + 1;
end

>> count

count =

  52

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...