how do I solve the overflow error : math range error - python

I am getting an overflow error
import numpy as np
pi = np.pi
from scipy.integrate import quad
from math import exp
hbar = 1.055e-34
boltz = 1.381e-23
c = 2.998e8
def z(x):
return (x**3)/(exp(x)-1)
B=quad(z,0,np.inf)
A= ((boltz**4)*B)/(4*(pi**2)*(c**2)*(hbar**3))
print (A)
It is giving me an overflow error in line 11, i.e return (x**3)/(exp(x)-1)

You're hitting machine precision and python is freaking out.
>>> def z(x):
... return (x**3)/(exp(x)-1)
...
>>> z(709)
4.336616682334302e-300
>>> z(710)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in z
OverflowError: math range error
Just integrate up to ~700 and you'll be fine.

You can use np.exp instead of math.exp: it will raise a Warning for large numbers and return np.inf (which results in 1/np.inf = 0), instead of raising an OverFlowError
def z(x):
return (x**3)/(np.exp(x)-1) #replace math.exp by np.exp
B, err =quad(z,0,np.inf) # add the err, or use B=quad(...)[0] as quad will also return the integration error
A= ((boltz**4)*B)/(4*(pi**2)*(c**2)*(hbar**3))
print(A)
>> 5.668949306250541e-08

Related

Why lambdify never stops?

x = symbols('x')
ch = 'exp(cos(cos(exp((sin(-0.06792841536110628))**(-6.045461643745118)))))'
f = lambdify(x, ch, "numpy")
print(float(f(2)))
It does not work, the programm is running and never ends(no error is issued).
My goal is to avoid this kind of cases (among multiple cases) by doing a try/except but i can't as there is no error
Why no error is released?
How can i avoid these cases ?
Thanks for your helping me !
In general, I'm not sure you can. SymPy or NumPy will keep trying to compute the number until precision is exhausted. But you can create a function that will raise and error if numbers are out of bounds for your interest:
>>> from sympy import cos as _cos, I, exp
>>> def cos(x):
... if abs(x) > 10**20: raise ValueError
... return _cos(x)
>>> exp(cos(cos(exp(5*(1+I)))))
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "<string>", line 2, in cos
ValueError
>>> f = lambda x: exp(cos(cos(exp(x))))
>>> f(sin(-0.06792841536110628)**-6.045461643745118)
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "<string>", line 1, in <lambda>
File "<string>", line 2, in cos
ValueError
But you have to think carefully about when you want to raise such an error. For example, SymPy has no trouble computing f(100) or f(100*I) if the non-error-catching cos is used. So think about when actually you want the error to rise.
lambdify is a lexical translator, converting a sympy expression to a python/numpy function.
Make a string with a symbol:
In [27]: ch = 'exp(cos(cos(exp((sin(x))**(-6.045461643745118)))))'
sympify(ch) has no problem, because it doesn't need to do any numeric calculation. So lambdify also works:
In [28]: f=lambdify(x,ch)
In [29]: f?
Signature: f(x)
Docstring:
Created with lambdify. Signature:
func(x)
Expression:
exp(cos(cos(exp((sin(x))**(-6.045461643745118)))))
Source code:
def _lambdifygenerated(x):
return (exp(cos(cos(exp(sin(x)**(-6.045461643745118))))))
The equivalent mpmath:
def _lambdifygenerated(x):
return (exp(cos(cos(exp(sin(x)**(mpf((1, 54452677612106279, -53, 56))))))))
And a working numeric evaluation:
In [33]: f(0j)
Out[33]: mpc(real='nan', imag='0.0')

"Can't convert expression to float" error with sympy

I am trying to solve the equations like this,
from sympy.solvers import solve
from sympy import Symbol
import math
x = Symbol('x')
A, B = 1, 2
print(solve((x) + (A/math.sqrt(x**4)) - (B * math.exp(-x)), x))
Traceback (most recent call last):
File "C:\Users\****\Desktop\Python Stuff\****\***.py", line 7, in <module>
print(solve((x) + (A/math.sqrt(x**4)) - (B * math.exp(-x)), x))
File "C:\Users\****\AppData\Local\Programs\Python\Python37\lib\site-packages\sympy\core\expr.py", line 280, in __float__
raise TypeError("can't convert expression to float")
TypeError: can't convert expression to float
Why this is happening?
x is a sympy.Symbol, so you can't use it with normal math library functions because they don't know about sympy. Instead, use sympy functions like sympy.sqrt:
from sympy.solvers import solve
import sympy
x = sympy.Symbol('x')
A, B = 1, 2
print(solve((x) + (A / sympy.sqrt(x ** 4)) - (B * sympy.exp(-x)), x))
(This raises another exception, with sympy complaining that it doesn't have an algorithm to solve this problem -- if you have problems with that too, you should post separate question.)
PS: as pointed out in a comment, the actual error you're getting is from a different expression. You'll need to fix this throughout.

Cannot find mpmath package in python

I am using Python35. I would like to use the mpmath.invertlaplace function used in this question. Unfortunately I am having some trouble:
>>> import mpmath as mp
>>> import numpy as np
>>> def f(s):
return(1/s)
>>> t = np.linspace(0.01,0.5,10)
>>> G = []
>>> for i in range(0,10):
G.append(mp.invertlaplace(f, t[i], method = 'dehoog', degree = 18))
Traceback (most recent call last):
File "<pyshell#254>", line 2, in <module>
G.append(mp.invertlaplace(f, t[i], method = 'dehoog', degree = 18))
AttributeError: module 'mpmath' has no attribute 'invertlaplace'
Has this function been added too recently for Python35 to pick up? Am I missing something here? I feel like this should work...

How to parallel a Theano function using multiprocessing?

I have a function returned by theano.function(), and I want to use it within multiprocessing for speedup. The following is a simplified demo script to show where I run into problem:
import numpy as np
from multiprocessing import Pool
from functools import partial
import theano
from theano import tensor
def get_theano_func():
x = tensor.dscalar()
y = x + 0.1
f = theano.function([x], [y])
return f
def func1(func, x):
return func(x)
def MPjob(xlist):
f = get_theano_func()
fp = partial(func1, func=f)
pool = Pool(processes=5)
Results = pool.imap(fp, xlist)
Y = []
for y in Results:
Y.append(y[0])
pool.close()
return Y
if __name__ == '__main__':
xlist = np.arange(0, 5, 1)
Y = MPjob(xlist)
print(Y)
In the above codes, the theano function 'f' is fed to 'func1()' as input argument. If MPjob() runs correctly, it should return [0.1, 1.1, 2.1, 3.1, 4.1]. However, an exception "TypeError: func1() got multiple values for argument 'func'" raised.
The full trackback log is as follows:
multiprocessing.pool.RemoteTraceback:
"""
Traceback (most recent call last):
File "C:\Python35\lib\multiprocessing\pool.py", line 119, in worker
result = (True, func(*args, **kwds))
TypeError: func1() got multiple values for argument 'func'
"""
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "F:/DaweiLeng/Code/workspace/Python/General/theano_multiprocess_debug.py", line 36, in <module>
Y = MPjob(xlist)
File "F:/DaweiLeng/Code/workspace/Python/General/theano_multiprocess_debug.py", line 29, in MPjob
for y in Results:
File "C:\Python35\lib\multiprocessing\pool.py", line 695, in next
raise value
TypeError: func1() got multiple values for argument 'func'
Anyone got a hint?
Turns out it's related with the partial() function. The full explanation is here https://github.com/Theano/Theano/issues/4720#issuecomment-232029702

How to fix this python program?

import math
def p(n):
return 393000*((288200/393000)^n * math.exp(-(288200/393000)))/math.factorial(n)
print p(3)
When I run it, I get the following error message:
Traceback (most recent call last):
File "poisson.py", line 6, in <module>
print p(3)
File "poisson.py", line 4, in p
return 393000*((288200/393000)^n * math.exp(-(288200/393000)))/math.factoria
l(n)
TypeError: unsupported operand type(s) for ^: 'int' and 'float'
Replace ^ with ** in
(288200/393000)^n
Bear in mind that
288200/393000
Returns 0
Maybe you should try using decimal numbers:
import math
def p(n):
a = 393000.0 # <-- notice the .0
b = 288200.0
c = b / a
return a * ( c**n * math.exp(-c) )/ math.factorial(n)
print p(3)
Returns:
12406.890756
Is the ^ supposed to mean exponentiation? If so, use ** instead.
You can also use math.pow:
>>> import math
>>> math.pow(3,2)
9.0
Though actually it looks like maybe this isn't the best idea, since math.pow is more for C extension compatibility, and doesn't handle all the cases that ** does:
>>> 2**3000
1230231922161117176931558813276752514640713895736833715766118029160058800614672948775360067838593459582429649254051804908512884180898236823585082482065348331234959350355845017413023320111360666922624728239756880416434478315693675013413090757208690376793296658810662941824493488451726505303712916005346747908623702673480919353936813105736620402352744776903840477883651100322409301983488363802930540482487909763484098253940728685132044408863734754271212592471778643949486688511721051561970432780747454823776808464180697103083861812184348565522740195796682622205511845512080552010310050255801589349645928001133745474220715013683413907542779063759833876101354235184245096670042160720629411581502371248008430447184842098610320580417992206662247328722122088513643683907670360209162653670641130936997002170500675501374723998766005827579300723253474890612250135171889174899079911291512399773872178519018229989376L
vs.
>>> import math
>>> math.pow(2, 3000)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: math range error
see http://mail.python.org/pipermail/python-list/2003-November/236169.html for a little more detail
EDIT: In response to your question as to why it returns 0.0, that's because you are raising 0 to a power - you are using / for division, which by default is integer division and will truncate. use from __future__ import division to get floating point divison.

Categories