I'm attempting to fit a three-segment line to a set of data, using np.piecewise
and scipy.optimize.curve_fit()
. I can accomplish this for a two-line segment by using the following function:
def piecewise_line(t,m1,m2,t0,y0):
conds = [t < t0, t >= t0]
functions = [lambda t:m1*(t-t0) + y0, lambda t:m2*(t-t0) + y0]
y = np.piecewise(t,conds,functions)
return y
Then applying it to a set of data, which works without issue.
t_space = np.linspace(2,4,100)
y = np.exp(t_space)
p, e = scipy.optimize.curve_fit(piecewise_line, t_space, y)
However, when I use a function corresponding to a 3-part piecewise line, as below:
def piecewise_line(t,m1,m2,m3,t0,y0,t1):
y1 = y0 + m2*(t1-t0)
conds = [t < t0, (t >= t0) and (t < t1), t >= t1]
functions = [lambda t:m1*(t-t0) + y0, lambda t:m2*(t-t0) + y0, lambda t:m3*(t-t1) + y1]
return np.piecewise(t, conds,functions)
I get the following error:
File ...\site-packages\scipy\optimize\_minpack_py.py:26, in _check_func(checker, argname, thefunc, x0, args, numinputs, output_shape)
...
---> 16 conds = [t < t0, (t >= t0) and (t < t1), t >= t1]
17 functions = [lambda t:m1*(t-t0) + y0, lambda t:m2*(t-t0) + y0, lambda t:m3*(t-t1) + y1]
18 return np.piecewise(t, conds,functions)
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
This error isn't thrown if I remove the middle condition, (t >= t0) and (t < t1)
or change it to a random, singular check (like t=9999
), but also throws on t0 <= t < t1
.
What about the middle condition causes this error while the "singular" comparisons don't?