1

The function has this mathematical form

f(x) = 1, if x<1
     = g(x), for 1<=x<10
     = 0, for x >=10

where g(x) is a simple function.

It is straightforward to write such a function if the input is a float using if/else. If the input is a numpy array, is there a neat/efficient implementation without explicit loop?

1
  • Is f continuous at x=1 and x=10? If it is then put the clips on x, not the function. Commented Nov 6, 2024 at 14:12

2 Answers 2

1

You can use numpy.piecewise:

x = np.linspace(0, 20, 30)
g = lambda x: -x

y = np.piecewise(x, [x<1, (1<=x)&(x<10), x>=10],
                    [1, g, 0])

NB. In contrast to numpy.where, it will only evaluate the function for each valid chunk of x.

Output:

array([ 1.        ,  1.        , -1.37931034, -2.06896552, -2.75862069,
       -3.44827586, -4.13793103, -4.82758621, -5.51724138, -6.20689655,
       -6.89655172, -7.5862069 , -8.27586207, -8.96551724, -9.65517241,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ])

As a function:

def f(x):
    return np.piecewise(x,
                        [x<1, (1<=x)&(x<10), x>=10],
                        [1, np.log, 0])

x = np.linspace(-10, 20, num=200)

plt.plot(x, f(x))

Output:

enter image description here

Sign up to request clarification or add additional context in comments.

2 Comments

The lambda function can be simplified with the number directly
@nos that's right, I'll simplify ;)
0

Another possible solution, which uses np.where:

np.where(x < 1, 1, np.where(x < 10, g(x), 0))

NB: In case there are values of x for which g is not defined, we can use the np.errstate:

with np.errstate(invalid='ignore'):
    y = np.where(x < 1, 1, np.where(x < 10, g(x), 0))

Output (using @mozway's data):

array([ 1.        ,  1.        , -1.37931034, -2.06896552, -2.75862069,
       -3.44827586, -4.13793103, -4.82758621, -5.51724138, -6.20689655,
       -6.89655172, -7.5862069 , -8.27586207, -8.96551724, -9.65517241,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ])

2 Comments

Actually, you shouldn't use np.where in this case as it will evaluate the function for potentially invalid values of x. For instance x = np.linspace(-10, 20) ; g = np.log ;)
You are right, @mozway! I have just added a way to deal with that situation. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.