Unexpected RuntimeWarning
I have a simple function defined in the following snippet: --- start --- import numpy def chebyshev(x, m): '''Calculates Chebyshev functions of the first kind using the trigonometric identities.''' theta = numpy.where( numpy.abs(x)<=1.0, numpy.arccos(x), numpy.arccosh(numpy.abs(x)) ) y = numpy.where( numpy.abs(x)<=1.0, numpy.cos(m*theta), numpy.cosh(m*theta) * numpy.where( x > 0.0, 1.0, -1.0 )**m ) return y if __name__ == '__main__': x = numpy.linspace(-2.0, 2.0, 21) y = chebyshev(x,3) print(y) --- end --- I'm using the numpy.where() call to extract only legal values for the circular and hyperbolic trigonometric functions. But I still get warnings that I'm passing invalid anrguments: --- start--- $ python3 demo.py demo.py:8: RuntimeWarning: invalid value encountered in arccos numpy.arccos(x), demo.py:9: RuntimeWarning: invalid value encountered in arccosh numpy.arccosh(numpy.abs(x)) [ -2.60000000e+01 -1.79280000e+01 -1.15840000e+01 -6.77600000e+00 -3.31200000e+00 -1.00000000e+00 3.52000000e-01 9.36000000e-01 9.44000000e-01 5.68000000e-01 -1.83697020e-16 -5.68000000e-01 -9.44000000e-01 -9.36000000e-01 -3.52000000e-01 1.00000000e+00 3.31200000e+00 6.77600000e+00 1.15840000e+01 1.79280000e+01 2.60000000e+01] --- end --- (I get the same with Python 2 so don't get excited about that.) I'm guessing that numpy.where() is evaluating the complete arccos and arccosh arrays and therefore getting invalid arguments. Now, I can turn off the warnings with numpy.seterr(invalid='ignore') but that's not what I would regard as good practice. Is there a "numpythonic" way to address the issue?
Bob Dowling
I'm guessing that numpy.where() is evaluating the complete arccos and arccosh arrays and therefore getting invalid arguments.
Now, I can turn off the warnings with numpy.seterr(invalid='ignore') but that's not what I would regard as good practice.
Is there a "numpythonic" way to address the issue?
Correct, the arguments are evaluated first, due to how Python semantics work. You may want to use this: http://docs.scipy.org/doc/numpy/reference/generated/numpy.piecewise.html
You may want to use this: http://docs.scipy.org/doc/numpy/reference/generated/numpy.piecewise.html
Thank you. That's just what I needed. Works a treat: --- start --- import numpy def chebyshev(x, m): '''Calculates Chebyshev functions of the first kind using the trigonometric identities.''' zone_a = x < -1.0 zone_b = numpy.logical_and(-1.0 <= x, x <= 1.0) zone_c = 1.0 < x theta = numpy.piecewise( x, [zone_a, zone_b, zone_c], [lambda z: numpy.arccosh(numpy.abs(z)), numpy.arccos, numpy.arccosh] ) y = numpy.piecewise( theta, [zone_a, zone_b, zone_c], [lambda z: (-1.0)**m*numpy.cosh(m*z), lambda z: numpy.cos(m*z), lambda z: numpy.cosh(m*z)] ) return y if __name__ == '__main__': x = numpy.linspace(-2.0, 2.0, 21) y = chebyshev(x,3) print(y) --- end---
On Fri, Nov 23, 2012 at 4:38 AM, Bob Dowling
I have a simple function defined in the following snippet:
--- start --- import numpy
def chebyshev(x, m): '''Calculates Chebyshev functions of the first kind using the trigonometric identities.'''
theta = numpy.where( numpy.abs(x)<=1.0, numpy.arccos(x), numpy.arccosh(numpy.abs(x)) )
y = numpy.where( numpy.abs(x)<=1.0, numpy.cos(m*theta), numpy.cosh(m*theta) * numpy.where( x > 0.0, 1.0, -1.0 )**m )
return y
if __name__ == '__main__': x = numpy.linspace(-2.0, 2.0, 21) y = chebyshev(x,3) print(y)
--- end ---
I'm using the numpy.where() call to extract only legal values for the circular and hyperbolic trigonometric functions. But I still get warnings that I'm passing invalid anrguments:
--- start---
$ python3 demo.py demo.py:8: RuntimeWarning: invalid value encountered in arccos numpy.arccos(x), demo.py:9: RuntimeWarning: invalid value encountered in arccosh numpy.arccosh(numpy.abs(x)) [ -2.60000000e+01 -1.79280000e+01 -1.15840000e+01 -6.77600000e+00 -3.31200000e+00 -1.00000000e+00 3.52000000e-01 9.36000000e-01 9.44000000e-01 5.68000000e-01 -1.83697020e-16 -5.68000000e-01 -9.44000000e-01 -9.36000000e-01 -3.52000000e-01 1.00000000e+00 3.31200000e+00 6.77600000e+00 1.15840000e+01 1.79280000e+01 2.60000000e+01]
--- end ---
(I get the same with Python 2 so don't get excited about that.)
I'm guessing that numpy.where() is evaluating the complete arccos and arccosh arrays and therefore getting invalid arguments.
Now, I can turn off the warnings with numpy.seterr(invalid='ignore') but that's not what I would regard as good practice.
Is there a "numpythonic" way to address the issue?
Are you aware of the Chebyshev series in numpy ? In [1]: from numpy.polynomial import Chebyshev as T In [2]: p = T([1,2,3]) In [3]: p(linspace(-2,2, 10)) Out[3]: array([ 18. , 9.40740741, 3.18518519, -0.66666667, -2.14814815, -1.25925926, 2. , 7.62962963, 15.62962963, 26. ])
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
participants (3)
-
Bob Dowling
-
Charles R Harris
-
Pauli Virtanen