Does Python have an equivalent to java.lang.Math.nextUp? [duplicate] - python

This question already has answers here:
Increment a Python floating point value by the smallest possible amount
(15 answers)
Closed 6 years ago.
I have a Python float, and I want to have the floats which are 1 ULP greater and lesser.
In Java, I would do this with Math.nextUp(x) and Math.nextAfter(x, Double.NEGATIVE_INFINITY).
Is there a way to do this in Python? I thought about implementing it myself with math.frexp and math.ldexp but as far as I know Python doesn't specify the size of floating point types.

Update: In Python 3.9+ there is math.nextafter():
>>> import math
>>> x = 4
>>> math.nextafter(x, math.inf)
4.000000000000001
Old answer:
You could look at how Decimal.next_plus()/Decimal.next_minus() are implemented:
>>> from decimal import Decimal as D
>>> d = D.from_float(123456.78901234567890)
>>> d
Decimal('123456.789012345674564130604267120361328125')
>>> d.next_plus()
Decimal('123456.7890123456745641306043')
>>> d.next_minus()
Decimal('123456.7890123456745641306042')
>>> d.next_toward(D('-inf'))
Decimal('123456.7890123456745641306042')
Make sure that decimal context has values that you need:
>>> from decimal import getcontext
>>> getcontext()
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,
capitals=1, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow])
Alternatives:
Call C99 nextafter() using ctypes:
>>> import ctypes
>>> nextafter = ctypes.CDLL(None).nextafter
>>> nextafter.argtypes = ctypes.c_double, ctypes.c_double
>>> nextafter.restype = ctypes.c_double
>>> nextafter(4, float('+inf'))
4.000000000000001
>>> _.as_integer_ratio()
(4503599627370497, 1125899906842624)
Using numpy:
>>> import numpy
>>> numpy.nextafter(4, float('+inf'))
4.0000000000000009
>>> _.as_integer_ratio()
(4503599627370497, 1125899906842624)
Despite different repr(), the result is the same.
If we ignore edge cases then a simple frexp/ldexp solution from #S.Lott answer works:
>>> import math, sys
>>> m, e = math.frexp(4.0)
>>> math.ldexp(2 * m + sys.float_info.epsilon, e - 1)
4.000000000000001
>>> _.as_integer_ratio()
(4503599627370497, 1125899906842624)
pure Python next_after(x, y) implementation by #Mark Dickinson that takes into account edge cases. The result is the same in this case.

I am not sure if this is what you want, but sys.float_info.epsilon is the "difference between 1 and the least value greater than 1 that is representable as a float", and you could do x * (1 + sys.float_info.epsilon).
http://docs.python.org/library/sys.html#sys.float_info

Related

sympy.simplify doesn't work on "tanh^2(x-y) + sech^2(x-y)"

I use sympy (ver1.9).
I calculate the following expressions((1)~(4)) by sympy.simplify().
All of them are expected to be identical to 1 analytically.
but (4) did not return 1, and the expression isn't simplified.
Why does this happen?
Try rewriting to exp and then simplifying:
>>> eq=tanh(x-y)**2 + sech(x-y)**2
>>> eq.rewrite(exp).simplify()
1
or use the function to rewrite hyperbolics to trigonometric functions before simplifying, e.g. with fu:
>>> from sympy.simplify.fu import hyper_as_trig
>>> e,f=hyper_as_trig(eq)
>>> f(fu(e))
1
See also hyper_as_trig in simplify/fu.py.

Complex number Data type in Python3

If I write x=5+j in python3. It shows me type(x) is an int. why this
not considered as a complex number?
You forgot write number before j if you write 5+1j and check type you get what you want (complex type), like below:
x = 5+1j
type(x)
#complex
For define complex numbers you can use different approaches.
You can use np.complex like below:
import numpy as np
x = np.complex(5,1)
type(x)
# complex
print(x)
# (5+1j)
Also You can use cmath:
import cmath
x = complex(5,1)
type(x)
# complex
print(x)
# (5+1j)
You could use the cmath module which allows you to work with complex numbers.
A very simple example of usage:
import cmath
x = 5 + 1*1j
# alternatively
# x = complex(5,1)
print(type(x))
print(x)
Check out more: https://docs.python.org/3/library/cmath.html
It's a standard package, so you don't have to install anything.
The fact that type(x) is int probably means that you already have a variable j in your code, and that variable is an int. Just like this:
>>> j = 10
>>> x = 5 + j
>>> type(x)
<class 'int'>
Now, if you wish to create a complex number, you may either use the built-in complex function:
>>> x = complex(5, 1)
>>> x
(5+1j)
>>> type(x)
<class 'complex'>
or write a literal complex number:
>>> x = 5 + 1j
>>> x
(5+1j)
>>> type(x)
<class 'complex'>
The main difference between this and what you wrote is that 5 + j means "5 plus a variable called j", whereas 5 + 1j means "5 plus the complex number 1j". Remember that j is not the imaginary unit, it is the name of a variable. If you wish to write a complex literal, you need to write something like <number>j. In particular, the imaginary unit can be written as 1j.

Python: float(var) conversion in Python wont work [duplicate]

This question already has answers here:
How do I get a decimal value when using the division operator in Python?
(13 answers)
Closed 8 years ago.
this is my code:
def pmi(w1,w2):
x = float(1)
x = (bg_fdist[(w1, w2)])/(f_brown[(w1)]*f_brown[(w2)])
print x
the values entered will be:
>>> bg_fdist[('of','the')]
9781
>>> f_brown[('of')]
36412
>>> f_brown[('the')]
6997`
so i expect my x to be very small and between 0 and 1.
but i get as a return:
>>>> pmi('of','the')
0
i assume that might be, because x gets still handled as an integer? why is this? can anyone point out how i might get my expected result?
greetings!
The x that you have declared as float(1) has nothing whatsoever to do with the result of the calculation in the second line: it was simply thrown away and replaced with the result from there. Instead, you'll need to explicitly case some of the elements of that calculation to floats.
The whole thing could be made clearer by splitting it up, like this:
def pmi(w1,w2):
first = float(bg_fdist[(w1, w2)])
second = float(f_brown[(w1)]*f_brown[(w2)])
result = first/second
return result
If you do
>>> x = float(1)
>>> x
1.0
>>> type(x)
<type 'float'>
x is indeed a float. But if after you instanciate it with an int, it's not a float anymore:
>>> x = 2
>>> x
2
>>> type(x)
<type 'int'>
When doing your division, you are using integer so:
>>> x = 2/4
>>> x
0
>>> type(x)
<type 'int'>
You still have an integer. Instead you could use float on your variable in your equation:
>>> x = float(2)/4
>>> x
0.5
You could also use from __future__ import division.
The current division (/) operator has an ambiguous meaning for
numerical arguments: it returns the floor of the mathematical
result of division if the arguments are ints or longs, but it
returns a reasonable approximation of the division result if the
arguments are floats or complex.
See: PEP 238

Python Logarithm Function

I'm looking for an example of operations with logarithms in Python. I've tried with sympy and numpy and I still can't do what I want. For example, for an input like this:
log(x+1)+log(4-x)=log(100) # it's just an example
the output should give me the x value. I need to do this with any other functions like log(x+1)=4 or log(x)-log(x+1)=log(x).
Is there some method or somewhere (documentation or similar) where can I find how to do this?
I may be misunderstanding what you need to do because you said you tried sympy already. However, it looks like you just want to solve for x in an algebraic equation.
Solving for x in the equation
log(x+1)+log(4-x)=log(100)
using sympy would be
>>> from sympy import Symbol, solve, log
>>> x = Symbol('x')
>>> solve(log(x+1) + log(4-x) - log(100), x)
[3/2 - 5*sqrt(15)*I/2, 3/2 + 5*sqrt(15)*I/2]
If you want, you can check that these two solutions are correct with numpy.
>>> import numpy as np
>>> a = 3/2 - 5*np.sqrt(15)*1j/2
>>> b = 3/2 + 5*np.sqrt(15)*1j/2
>>> np.log(a + 1) + np.log(4-a)
(4.6051701859880918+0j)
>>> np.log(b + 1) + np.log(4-b)
(4.6051701859880918+0j)
>>> np.log(100)
4.6051701859880918
Is that not what you are looking for?
Since log is a non-linear function, you will need to use a non-linear solver like scipy.optimize.fsolve. It take in a function and a guess value and returns the answer in the form of an array. For simplicity reason, I defined the function as a lambda function since we don't need it outside of this line, but creating a function using standard def methods would work as well. The [0] on the back end get the value out of the array to return just the float.
import scipy.optimize
import math
scipy.optimize.fsolve(lambda x: math.log(x+1) - 4, 5)[0] # 5 is guess value
>>> 53.598
# Check
math.exp(4) - 1
>>> 53.598
Good advice already given. I just note that you can also check the answer in SymPy.
>>> L, R = log(x+1)+log(4-x), log(100)
>>> eq = Eq(L, R)
>>> eq
log(-x + 4) + log(x + 1) == log(100)
>>> sol = solve(eq)
>>> [eq.subs(x, i) for i in sol]
[True, True]
So in the Eq form the solutions were verified automatically. This is not always
true but you can use numerical evaluation to check the value:
>>> f = eq.lhs - eq.rhs; f
log(-x + 4) + log(x + 1) - log(100)
>>> f.subs(x, sol[0])
-log(100) + log(5/2 - 5*sqrt(15)*I/2) + log(5/2 + 5*sqrt(15)*I/2)
>>> _.n()
0.e-124 + 0.e-125*I
>>> f.subs(x, sol[0]).n(chop=True) # the small numbers can be chopped
0

Complex number in python

How to write a complex number in python? Indeed I have:
import math
a=3
b=4
function=a*j*x+b*y
I don't want to write directly 3j in my function since I absolutely want to use a, so how to convert a into a complex number? Cause in matlab it works when printing :
a=3
b=a*i
The result will gave: 0 + 3.0000i
Thank you for your answers.
j alone is a variable, you can have the complex number by typing 1j
>>> type(j)
NameError: name 'j' is not defined
>>> type(1j)
<type 'complex'>
So your code can be written as a function as
def function(x, y):
a = 3
b = 4
return a*1j*x+b*y
You can use the complex function to create a complex number from variables:
>>> a = 3
>>> b = 4
>>> complex(a, b)
(3+4j)
You can simply use Python's Built in complex() function
>>> first_number = 10
>>> second_number = 15
>>> complex(first_number, second_number)
(10+15j)

Categories