increment float32 by smallest possible amount (using numpy currently) - python

Trying to increment a single-precision floating point number by the smallest possible amount. I see there is a nextafter function, but I can't get that to work for single precision numbers. Any suggestions?

Seems to work fine:
>>> x = np.float32(1.)
>>> y = np.nextafter(x, np.float32(2.))
>>> y
1.0000001
>>> type(y)
numpy.float32

Related

Should I use float literals to represent integer numbers as floats in Python?

Consider a function that is to return a half of a float argument. Should it better be the first or the second?
def half_a(x: float) -> float:
return x / 2
def half_b(x: float) -> float:
return x / 2.0
Is there any performance difference or is there a style convention that would say one of these is better than the other?
Clearly half_a looks better and a more complex piece of code may get more readable written this way but in some other languages it is either necessary or preferable to use the half_b version to avoid run-time type conversion.
It's hard to know if there's a performance difference (and if there is, it's definitely negligible). Regarding style, there is also no common convention. However, I would choose the first one, if you are on python 3+. Python 3 has a different operator for integer division. See below
x = 2
print(type(x)) # int
print(type(x / 2)) # float
print(type(x // 2)) # int
On the other hand, if you are on python 2, you should probably choose the second one, because if your argument happens to be an int
print(2/5) # 0
float divided by float is slightly faster than float divided by int:
>>> timeit.timeit('n/2', 'n=123456.789')
0.04134701284306175
>>> timeit.timeit('n/2.0', 'n=123456.789')
0.03455621766488548
>>> timeit.timeit('[n/2 for n in r]', 'r = [n*5/1.1 for n in range(1, 10001)]', number=10000)
5.177127423787169
>>> timeit.timeit('[n/2.0 for n in r]', 'r = [n*5/1.1 for n in range(1, 10001)]', number=10000)
4.067747102254316

Measuring the accuracy of floating point results to N decimal places

I'm testing some implementations of Pi in python (64-bit OS) and am interested in measuring how accurate the answer is (how many decimal places were correct?) for increasing iterations. I don't wish to compare more than 15 decimal places because beyond that the floating point representation itself is inaccurate.
E.g. for a low iteration count, the answer I got is
>>> x
3.140638056205993
I wish to compare to math.pi
>>> math.pi
3.141592653589793
For the above I wish my answer to be 3 (3rd decimal is wrong)
The way I've done it is:
>>> p = str('%.51f' % math.pi)
>>> q = str('%.51f' % x)
>>> for i,(a,b) in enumerate(zip(p,q)):
... if a != b:
... break
The above looks clumsy to me, i.e. converting floats to strings and then comparing character by character, is there a better way of doing this, say more Pythonic or that uses the raw float values themselves?
Btw I found math.frexp, can this be used to do this?
>>> math.frexp(x)
(0.7851595140514982, 2)
You can compute the logarithm of the difference between the two
>>> val = 3.140638056205993
>>> epsilon = abs(val - math.pi)
>>> abs(int(math.log(epsilon, 10))) + 1
3
Essentially, you're finding out which power of 10 does it take to equal the difference between the two numbers. This only works if the difference between the two numbers is less than 1.

Error with Python modulo on scientific notation

I hope someone can help me with an explanation for this strange result on large divisor, or suggest me with some keywords so can I get a better search.
>>> m = 1e9+9
>>> n = 1000000009
>>> m == n
True
>>> 2549015908609065 % m
885667930.0
>>> 2549015908609065 % n
885667930
>>> 2549015908609065L % n
885667930L
>>> 2549015908609065L % m
885667930.0
>>> 254901590860906524041412370460835L % m
98506080.0
>>> 254901590860906524041412370460835L % n
327998297L
>>> 254901590860906524041412370460835L % int(m)
327998297L
The reason you are seeing strange results is because you are performing modulo on floating point numbers, which have an inexact representation. The documentation on the decimal module highlights this quite well.
To perform exact operations on very large number, you can use the decimal class as follows:
from decimal import *
print Decimal(2549015908609065) % Decimal(1e9) # Gives the answer you expect
m = 1e9+9 stores the number as a float; however n = 1000000009 stores the numbers as an integer.
When you divide an integer number by a float, python implicitly outputs a float as a result; However, when you divide an integer by another integer, you get the integral quotient.
The precision of Float over bigger numbers gets reduced.
If you notice,
>>> 254901590860906524041412370460835L % m
98506080.0
#outputted a float with different precision
>>> 254901590860906524041412370460835L % n
327998297L
#outputted a long int
Check http://www.tutorialspoint.com/python/python_numbers.htm for a basic tutorial on python numbers

Why does this While loop terminate?

x=1.0
i=1
while(1.0+x>1.0):
x=x/2
i=i+1
print i
Follow up question, why is the value of i=54?
My thinking was that the loop would not end as the value of (1.0+x) will always stay greater than 1.0. But when running the code, that's not the case.
Due to the inaccuracy of floating point, there will always come a time when the value of x is so small that Python can't store its value, and it essentially becomes 0. It takes 54 iterations (53, actually) to get to that stage, which is why i is 54.
For example,
>>> 1e-1000
0.0
Why 54? -- Actually it is 53, because it was before you increment it
>>> 2.**-54
5.551115123125783e-17
>>> 2.**-53
1.1102230246251565e-16
>>> 2.**-52
2.220446049250313e-16
>>> sys.float_info.epsilon
2.220446049250313e-16
if you add something so small to 1, it will be still 1.
When dealing with floats or floating point numbers, you will encounter the notorious Floating Point Epsilon:
In your case, this takes 54 iterations to get below that threshold (since the default floating point type in Python is single precision, and the floating point epsilon for single precision is:
def machineEpsilon(func=float):
machine_epsilon = func(1)
while func(1)+func(machine_epsilon) != func(1):
machine_epsilon_last = machine_epsilon
machine_epsilon = func(machine_epsilon) / func(2)
return machine_epsilon_last
Hence:
In [2]: machineEpsilon(float)
Out[2]: 2.2204460492503131e-16
Where does the 53 iterations come from?
From this line in your code:
x=x/2
Which assigns the current value of x to x/2 meaning that on the 53th iteration, it became:
1.11022302463e-16
Which is less than the floating point epsilon.
As has been pointed out - it's because of the accuracy of floats. If you wanted to overcome this "limitation" you can use Python's fractions module, eg:
from fractions import Fraction as F
x = F(1, 1)
i=1
while(F(1, 1)+x>1.0):
print i, x
x = F(1, x.denominator * 2)
i=i+1
print i
(NB: This will continue until interrupted)

Convert fraction to decimal in Python

I want to convert 1/2 in python so that when i say print x (where x = 1/2) it returns 0.5
I am looking for the most basic way of doing this, without using any split functions, loops or maps
I have tried float(1/2) but I get 0...
can someone explain me why and how to fix it?
Is it possible to do this without modifying the variable x= 1/2 ?
In python 3.x any division returns a float;
>>> 1/2
0.5
To achieve that in python 2.x, you have to force float conversion:
>>> 1.0/2
0.5
Or to import the division from the "future"
>>> from __future__ import division
>>> 1/2
0.5
An extra: there is no built-in fraction type, but there is one in Python's standard library:
>>> from fractions import Fraction
>>> a = Fraction(1, 2) #or Fraction('1/2')
>>> a
Fraction(1, 2)
>>> print a
1/2
>>> float(a)
0.5
and so on...
If the input is a string,then you could use Fraction directly on the input:
from fractions import Fraction
x='1/2'
x=Fraction(x) #change the type of x from string to Fraction
x=float(x) #change the type of x from Fraction to float
print x
You're probably using Python 2. You can "fix" division by using:
from __future__ import division
at the start of your script (before any other imports). By default in Python 2, the / operator performs integer division when using integer operands, which discards fractional parts of the result.
This has been changed in Python 3 so that / is always floating point division. The new // operator performs integer division.
Alternatively, you can force floating point division by specifying a decimal or by multiplying by 1.0. For instance (from inside the python interpreter):
>>> print 1/2
0
>>> print 1./2
0.5
>>> x = 1/2
>>> print x
0
>>> x = 1./2
>>> print x
0.5
>>> x = 1.0 * 1/2
>>> print x
0.5
EDIT: Looks like I was beaten to the punch in the time it took to type up my response :)
There is no quantity 1/2 anywhere. Python does not represent rational numbers with a built-in type - just integers and floating-point numbers. 1 is divided by 2 - following the integer division rules - resulting in 0. float(0) is 0.

Categories