piecewise numpy function with integer arguments
Asked Answered
P

3

3

I define the piecewise function

def Li(x):        
    return piecewise(x, [x < 0, x >= 0], [lambda t: sin(t), lambda t: cos(t)])

And when I evaluate Li(1.0)

The answer is correct

Li(1.0)=array(0.5403023058681398),

But if I write Li(1) the answer is array(0).

I don't understand this behaviour.

Pulvinate answered 21/11, 2014 at 10:55 Comment(1)
I get ValueError: too many boolean indices when running either example. You need to pass an ndarray to Li(). Please update your question with working code.Hoxha
P
3

This function runs correctly.

def Li(x):        
  return  piecewise(float(x), 
                    [x < 0, x >= 0], 
                    [lambda t: sin(t), lambda t: cos(t)])
Pulvinate answered 22/11, 2014 at 20:39 Comment(1)
if x is supposed to be np.array, it should be x.astype(float) instead of float(x).Caines
H
2

It seems that piecewise() converts the return values to the same type as the input so, when an integer is input an integer conversion is performed on the result, which is then returned. Because sine and cosine always return values between −1 and 1 all integer conversions will result in 0, 1 or -1 only - with the vast majority being 0.

>>> x=np.array([0.9])
>>> np.piecewise(x, [True], [float(x)])
array([ 0.9])
>>> x=np.array([1.0])
>>> np.piecewise(x, [True], [float(x)])
array([ 1.])
>>> x=np.array([1])
>>> np.piecewise(x, [True], [float(x)])
array([1])
>>> x=np.array([-1])
>>> np.piecewise(x, [True], [float(x)])
array([-1])

In the above I have explicitly cast the result to float, however, an integer input results in an integer output regardless of the explicit cast. I'd say that this is unexpected and I don't know why piecewise() should do this.

I don't know if you have something more elaborate in mind, however, you don't need piecewise() for this simple case; an if/else will suffice instead:

from math import sin, cos

def Li(t):        
    return sin(t) if t < 0 else cos(t)

>>> Li(0)
1.0
>>> Li(1)
0.5403023058681398
>>> Li(1.0)
0.5403023058681398
>>> Li(-1.0)
-0.8414709848078965
>>> Li(-1)
-0.8414709848078965

You can wrap the return value in an numpy.array if required.

Hoxha answered 21/11, 2014 at 11:19 Comment(0)
P
0

I am sorry, but this example is taken and modified from

http://docs.scipy.org/doc/numpy/reference/generated/numpy.piecewise.html

But, in fact, using ipython with numpy 1.9

""" Python 2.7.8 |Anaconda 2.1.0 (64-bit)| (default, Aug 21 2014, 18:22:21) Type "copyright", "credits" or "license" for more information. IPython 2.2.0 -- An enhanced Interactive Python. """

I have no errors, but "ValueError: too many boolean indices" error appears if I use python 2.7.3 with numpy 1.6

""" Python 2.7.3 (default, Feb 27 2014, 19:58:35) """ I test this function under Linux and Windows and the same error occurs.

Obviously, It is very easy to overcome this situation, but I think that this behaviour is a mistake in the numpy library.

Pulvinate answered 21/11, 2014 at 17:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.