I am using Numba to speed up a function and I bumped into the following problem.
When using the decorator #njit (or #jit) the behaviour of some numpy function is changed.
For example if I use the following function to calculate tanh
from numba import njit
import numpy as np
#njit
def check_tanh(z):
return np.tanh(z)
and I run it for real values of z I get the same as np.tanh(z) as it should be.
If I move instead parallel to the real axis but with an imaginary part, for example z = x+ 1.j, and increase x, the numpy tanh will converge to 1.+0.j, while check_tanh(z) will return a nan (on my computer this is happening when x>360).
Does anyone have an idea of what is going on and how can be fixed?
Thanks in advance!
Using tanh from cmath fixes the issue.
Seems that is still a problem in Numba
https://github.com/numba/numba/issues/2919
Related
I'm trying to use least square to minimize a loss function by changing x,y,z. My problem is nonlinear hence why i chose scipy least_squares. The general structure is:
from scipy.optimize import least_squares
def loss_func(x, *arguments):
# plug x's and args into an arbitrary equation and return loss
return loss # loss here is an array
# x_arr contains x,y,z
res = least_squares(loss_func, x_arr, args=arguments)
I am trying to constraint x,y,z by: x-y = some value, z-y = some value. How do I go about doing so? The scipy least_squares documentation only provided bounds. I understand I can create bounds like 0<x<5. However, my constraints is an equation and not a constant bound. Thank you in advance!
If anyone ever stumble on this question, I've figured out how to overcome this issue. Since least_squares does not have constraints, it is best to just use linear programming with scipy.optimize.minimize. Since the loss_func returns an array of residuals, we can use L1 norm (as we want to minimize the absolute difference of this array of residuals).
from scipy.optimize import minimize
import numpy as np
def loss_func(x, *arguments):
# plug x's and args into an arbitrary equation and return loss (loss is an array)
return np.linalg.norm(loss, 1)
The bounds can be added to scipy.optimize.minimize fairly easily:)
I'm trying to solve a nonlinear equation with Python and Scipy, heres the simple input:
from numpy import exp
from scipy.optimize import fsolve
def func(x):
return 5*x*(2*x-1+exp(2*x))-5
x0 = fsolve(func,0)
print(x0)
However executing the function leads to RuntimeWarning: overflow encountered in exp message.
Using Matlab and fzero with the same function works fine and returns 0.4385 for the root.
How can I solve this?
using 0 as a starting estimate causes some problems
you can use any arbitary value and if you want to start from zero use something like 1e-6
from numpy import exp
from scipy.optimize import fsolve
def func(x):
return 5*x*(2*x-1+exp(2*x))-5
x0 = fsolve(func,1e-6)
print(x0)
yields
[0.43848533]
I've been trying to solve a nonlinear ordinary differential equation numerically by using Scipy, in particular by the scipy.integrate.RK23 command. It returns <scipy.integrate._ivp.rk.RK23 at 0x7f2b1a908390>. How can I plot the solution?
Thank you in advance for your help!
EDIT:
As a simple example for testing:
import numpy
import scipy.integrate
t0=0;
tf=1;
x0=numpy.array([0]);
def F(t,x): return t**2;
x=scipy.integrate.RK23(F,t0,x0,tf)
RK23 is a class that implements a way to solve an ODE, that is, it is an OdeSolver so it should not be used directly but in other functions like solve_ivp:
import numpy
from scipy.integrate import solve_ivp, RK23
import matplotlib.pyplot as plt
t0=0
tf=1
x0=numpy.array([0])
def F(t,x): return t**2
sol = solve_ivp(F, [t0, tf], x0, RK23)
print(sol)
plt.plot(sol.t, sol.y[0])
plt.show()
OdeSolver allows the developer to add custom methods without the need to rewrite scipy, but since RK23 is a classic method already implemented by scipy, you could pass just the name and scipy search for the appropriate class:
...
sol = solve_ivp(F, [t0, tf], x0, "RK23")
...
I got something wrong going on :
import numpy as np
import matplotlib.pyplot as plt
x = np.concatenate((np.linspace(0,1,100),np.linspace(1,2,50)));
f = np.power(x,2);
df = 2*x;
Df = np.gradient(f,x);
plt.plot(x,df,'r', x,Df,'b');plt.show()
This is what I get :
Otherwise things work ok if using linearly spaced array and not using argument x.
Any suggestions?
I think this is because numpy versions before 1.13 expect the "x" argument to be the constant grid spacing (see https://docs.scipy.org/doc/numpy-1.11.0/reference/generated/numpy.gradient.html#numpy.gradient). Even though the earlier versions expect a scalar dx, they do not check for this, and the result is np.gradient(f) / x, which is a valid division. This is pretty annoying since code written for numpy 1.13 may run on earlier versions with incorrect output and no errors.
I've been rewriting a matlab/octave program into numpy and ran across a difference in some resultant values.
This occurs with both the percentile/prctile and the stdard-deviation functions.
In Numpy:
import matplotlib.mlab as ml
import numpy
>>> t = numpy.linspace(0,100, 100)
>>> numpy.percentile(t,95)
95.0
>>> numpy.std(t)
29.157646512850626
>>> ml.prctile(t,95)
95.000000000000014
In Octave:
octave:1> t = linspace(0,100,100)';
octave:2> prctile(t,95)
ans = 95.454545
octave:3> std(t)
ans = 29.304537
Although the array values of 't' are the same, the results are more different than I would suspect.
In the numpy help(numpy.std) they specifically mention that the algorithm is:
std = sqrt(mean(abs(x - x.mean())**2))
So I implemented that in octave and got the exact answer numpy gives. So it seems the std-deviation function differs.
But why/how? And which is correct? (if there is such a thing)
And even prctile/percentile?
Just in case since I'm in Linux aptosid...
GNU Octave, version 3.6.2
numpy.version '1.6.2rc1'
Numpy simply uses a different algorithm when the percentile lies between two data points. Octave, Matlab and R always center it exactly between two points when needed (I believe), numpy does a bit more then that... if you check http://en.wikipedia.org/wiki/Percentile you will see there are a couple of ways to calculate percentiles.
It seems like Octave assumes ddof=1, at least by default, and numpy uses 0 by default:
>>> numpy.std(t, ddof=0)
29.157646512850633
>>> numpy.std(t, ddof=1)
29.304537349375785