Search code examples
pythonfunctionpiecewise

Defining a piecewise multivariate function


I want to define a function in Python, of variables x (position) and t (time). The function is periodic in time. Each cycle consists of two time intervals, namely toff and ton in that order. In the first half, i.e. from the beginning of a cycle to t=toff, the function is zero. While after that, till t=toff+ton, the function is a sawtooth function in x.

I tried defining the function in the following way.

def F_f(y):
    return 0
def F_n(y):
    return signal.sawtooth(y)
def F(y,t):
    if((t%T)<=t_F):
        return 0
    elif((t%T)>t_F):
        return F_n(y)

Now, when I proceed to plot the function against t, keeping x constant, I get an error that reads,

The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

I also tried using the piecewise function but that too runs into an error while plotting against x whiel keeping t constant.

How can I redefine my function to avoid these issues? Thanks!


Solution

  • The function F assumes single values for both inputs, not arrays. If t is an array, then (t%T)<=t_F is an array of booleans, not a single boolean, thus also the error. You could change the way you use it, e.g. as follows:

    import numpy as np
    from scipy.signal import sawtooth
    
    x = np.arange(0, 10, 0.1)
    t = np.arange(0, 10, 0.1)
    T = 2
    t_F = 1.5
    
    def F_f(x):
        return 0
    
    def F_n(x):
        return sawtooth(x)
    
    def F(x,t):
        if ((t%T)<=t_F):
            return F_f(x)
        elif ((t%T)>t_F):
            return F_n(x)
    
    res = np.full((len(x), len(t)), np.nan)
    for i, a in enumerate(x):
        for j, b in enumerate(t):
            res[i, j] = F(a, b)
    

    But you can replace

    def F_f(x):
        return 0
    

    by

    def F_f(x):
        return np.full((len(x),), 0)
    

    and then you can use it as you intended:

    res = np.full((len(x), len(t)), np.nan)
    for j, b in enumerate(t):
        res[:, j] = F(x, b)