I need to calculate exp(x**2) where x = numpy.arange(30,90). This raises the warning:
RuntimeWarning: overflow encountered in exp
inf
I cannot safely ignore this warning, but neither SymPy nor mpmath is a solution and I need to perform array operations so a Numpy solution would be my dream.
Does anyone know how to handle this problem?
You could use a data type that has the necessary range, for example decimal.Decimal:
>>> import numpy as np
>>> from decimal import Decimal
>>> x = np.arange(Decimal(30), Decimal(90))
>>> y = np.exp(x ** 2)
>>> y[-1]
Decimal('1.113246031563799750400684712E+3440')
But what are you using these numbers for? Could you avoid the exponentiation and work with logarithms? More detail about your problem would be helpful.
I think you can use this method to solve this problem:
Normalized
I overcome the problem in this method. Before using this method, my classify accuracy is :86%. After using this method, my classify accuracy is :96%!!!
It's great!
first:
Min-Max scaling
second:
Z-score standardization
These are common methods to implement normalization.
I use the first method. And I alter it. The maximum number is divided by 10.
So the maximum number of the result is 10. Then exp(-10) will be not overflow!
I hope my answer will help you !(^_^)
Related
I encountered a problem when I using Sympy to solve problems
Here is my code:
from math import pi, hypot
from sympy import solve, solveset, sqrt, Symbol
one_x=-0.08
one_y=1.28
second_x=0
second_y=0
second_r=7
one_r=7.3
slopes=-16.0000000000 (maybe more trailing 0s)
intercepts=0.0
x=Symbol('x')
solveset(sqrt((x-second_x)**2+(slope*x+intercept-second_y)**2)+second_r-one_r-sqrt((x-one_x)**2+(slope*x+intercept-one_y)**2),x)
That's only part of my code but it raises a lot of errors
but instead, I replaced all of the variables with its value like
x=Symbol('x')
solveset(sqrt((x)**2+((-16)*x)**2)+7-7.3-sqrt((x+0.08)**2+((-16)*x-1.28)**2),x)
It works nicely and i can get an output {-0.0493567429232771}
I think It's because of the type of slopes(-16 compared with -16.000000), I really wanna know why an equation with float number cannot be calculated, and how I can fix it (cause I need it to be more precise so I cannot just ignore the number after the dot )
Thanks so much!
SymPy + algebraic equation + floating point numbers => trouble. Floating point math does not work like normal math, and SymPy is designed for the latter. Small things like 16 (integer) versus 16.0 (float) make a lot of difference in solving equations with SymPy: ideally, you would have no floating point numbers there, creating exact rational numbers instead, like this.
from sympy import S
one_x = S('-0.08')
However, you have floating point data and are looking for a floating point solution. This makes SymPy the wrong tool for the job. SymPy is for doing math with symbols, not for crunching floating point numbers. The correct solution is to use an appropriate solve from SciPy, such as brentq. It takes a bracketing interval as an input (where the function has different signs at both ends). For example:
from scipy.optimize import brentq
eq = lambda x: np.sqrt((x-second_x)**2 + (slope*x+intercept-second_y)**2) + second_r - one_r - np.sqrt((x-one_x)**2 + (slope*x + intercept - one_y)**2)
brentq(eq, -10, 10) # returns -0.049356742923277075
If you stick with SymPy, that means your equation is going outsourced to mpmath library, which is much more limited in the numerical root finding and optimization. To get a solution to converge with its methods, you'll need a really good starting point: apparently, one_x/2 is such a point.
from sympy import sqrt, Symbol, nsolve
# ... as in your code
nsolve(sqrt((x-second_x)**2+(slope*x+intercept-second_y)**2)+second_r-one_r-sqrt((x-one_x)**2+(slope*x+intercept-one_y)**2), one_x/2)
returns -0.0493567429232771.
By using sympy.solveset, which is intended for symbolic solution, you deprive yourself not only of SciPy's powerful numeric solvers, but also of an opportunity to set a good starting value for the numeric search which sympy.nsolve provides. Hence the lack of convergence in this numerically tricky problem. By the way, this is what makes it numerically tricky: the function is nearly constant most of the time, with one rapid change.
This is most likely because I do not know how to use the standard scipy expect function method. When I use:
from scipy.stats import uniform
uniform.expect(lambda k: k**2,lb=-0.2,ub=0.2)
I got value : 0.0026666666666666666
If I use manual calculation:
np.mean(np.random.uniform(-0.2,0.2,1000)**2)
I got 0.013235491320680141, which is the right value I expect. So what did I do wrong with standard expect or integral function? Any help please.
If you look at the documentation for expect, ub and lb do not mean what you think they do. They are bounds on the integral, not parameters for the distribution.
You actually want:
scipy.stats.uniform(loc=-0.2, scale=0.4).expect(lambda x: x**2)
In SymPy, is it possible to apply limits to an indefinite integral and evaluate it?
import sympy
from sympy.abc import theta
y = sympy.sin(theta)
Y_indef = sympy.Integral(y)
Y_def = sympy.Integral(y, (theta, 0, sympy.pi / 2))
Y_def.evalf() produces a number.
I'm looking for something like Y_indef.evalf((theta, 0, sympy.pi/2)) to get the same answer.
I do not know of a direct way, however you can extract the information from Y_indef in order to create a definite integral:
>>> indef = Integral(x)
>>> to_be_integrated, (free_var,) = indef.args
>>> definite = Integral(to_be_integrated, (free_var, 1, 2))
.args is a general attribute containing anything needed to construct most SymPy objects.
Edit: To address the comments to the questions.
SymPy may succeed evaluating definite integral and at the same time fail to solve their indefinite version. This is due to the existence of additional algorithms to be applied to definite integrals.
Both definite and indefinite integrals are instances of the same class. The only difference is what they contain in their .args. The need for different classes is not yet felt, given that SymPy mostly uses Integral as a flag to say that it can not solve the integral (i.e. the integrate function returns Integral when all of the implemented algorithms fail).
the scipy.special.gammainc can not take negative values for the first argument. Are there any other implementations that could in python? I can do a manual integration for sure but I'd like to know if there are good alternatives that already exist.
Correct result: 1 - Gamma[-1,1] = 0.85
Use Scipy: scipy.special.gammainc(-1, 1) = 0
Thanks.
I typically reach for mpmath whenever I need special functions and I'm not too concerned about performance. (Although its performance in many cases is pretty good anyway.)
For example:
>>> import mpmath
>>> mpmath.gammainc(-1,1)
mpf('0.14849550677592205')
>>> 1-mpmath.gammainc(-1,1)
mpf('0.85150449322407795')
>>> mpmath.mp.dps = 50 # arbitrary precision!
>>> 1-mpmath.gammainc(-1,1)
mpf('0.85150449322407795208164000529866078158523616237514084')
I just had the same issue and ended up using the recurrence relations for the function when a<0.
http://en.wikipedia.org/wiki/Incomplete_gamma_function#Properties
Note also that the scipy functions gammainc and gammaincc give the regularized forms Gamma(a,x)/Gamma(a)
Still an issue in 2021, and they still haven't improved this in scipy. Especially it is frustrating that scipy does not even provide unregularised versions of the upper and lower incomplete Gamma functions. I also ended up using mpmath, which uses its own data type (here mpf for mpmath floating - which supports arbitrary precision). In order to cook up something quick for the upper and lower incomplete Gamma function that works with numpy arrays, and that behaves like one would expect from evaluating those integrals I came up with the following:
import numpy as np
from mpmath import gammainc
"""
In both functinos below a is a float and z is a numpy.array.
"""
def gammainc_up(a,z):
return np.asarray([gammainc(a, zi, regularized=False)
for zi in z]).astype(float)
def gammainc_low(a,z):
return np.asarray([gamainc(a, 0, zi, regularized=False)
for zi in z]).astype(float)
Note again, this is for the un-regularised functions (Eq. 8.2.1 and 8.2.2 in the DLMF), the regularised functions (Eq. 8.2.3 and 8.2.4) can be obtined in mpmath by setting the keyword regularized=True.
I face a problem in scipy 'leastsq' optimisation routine, if i execute the following program it says
raise errors[info][1], errors[info][0]
TypeError: Improper input parameters.
and sometimes index out of range for an array...
from scipy import *
import numpy
from scipy import optimize
from numpy import asarray
from math import *
def func(apar):
apar = numpy.asarray(apar)
x = apar[0]
y = apar[1]
eqn = abs(x-y)
return eqn
Init = numpy.asarray([20.0, 10.0])
x = optimize.leastsq(func, Init, full_output=0, col_deriv=0, factor=100, diag=None, warning=True)
print 'optimized parameters: ',x
print '******* The End ******'
I don't know what is the problem with my func optimize.leastsq() call, please help me
leastsq works with vectors so the residual function, func, needs to return a vector of length at least two. So if you replace return eqn with return [eqn, 0.], your example will work. Running it gives:
optimized parameters: (array([10., 10.]), 2)
which is one of the many correct answers for the minimum of the absolute difference.
If you want to minimize a scalar function, fmin is the way to go, optimize.fmin(func, Init).
The issue here is that these two functions, although they look the same for a scalars are aimed at different goals. leastsq finds the least squared error, generally from a set of idealized curves, and is just one way of doing a "best fit". On the other hand fmin finds the minimum value of a scalar function.
Obviously yours is a toy example, for which neither of these really makes sense, so which way you go will depend on what your final goal is.
Since you want to minimize a simple scalar function (func() returns a single value, not a list of values), scipy.optimize.leastsq() should be replaced by a call to one of the fmin functions (with the appropriate arguments):
x = optimize.fmin(func, Init)
correctly works!
In fact, leastsq() minimizes the sum of squares of a list of values. It does not appear to work on a (list containing a) single value, as in your example (even though it could, in theory).
Just looking at the least squares docs, it might be that your function func is defined incorrectly. You're assuming that you always receive an array of at least length 2, but the optimize function is insanely vague about the length of the array you will receive. You might try writing to screen whatever apar is, to see what you're actually getting.
If you're using something like ipython or the python shell, you ought to be getting stack traces that show you exactly which line the error is occurring on, so start there. If you can't figure it out from there, posting the stack trace would probably help us.