Sorry about the length of this answer, but I think you need to see the full debugging process. I had to look at the tracebacks and test small pieces of your code to identify the exact problem. I've seen a lot of the numpy ambiguity error, but not this sympy relational error.
===
Lets look at the whole traceback, not just one line of it. At the very least we need to identify which line of your code is producing the problem.
In [4]: expr = np.piecewise((0, x-a <= -2*h), ((1/6)*(2*h+(x-a))**3, -2*h<=x-a<
...: =-h), (2*h**3/3-0.5*(x-a)**2*(2*h+(x-a)), -h<= x-a<= 0), (2*(h**3/3)-0.5
...: *(x-a)**2*(2*h+(x-a)), 0<=x-a<=2*h), ((1/6)*(2*h-(x-a))**3, h<=x-a<=2*h)
...: , (0, x-a<=2*h))
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-4-893bb4b36321> in <module>
----> 1 expr = np.piecewise((0, x-a <= -2*h), ((1/6)*(2*h+(x-a))**3, -2*h<=x-a<=-h), (2*h**3/3-0.5*(x-a)**2*(2*h+(x-a)), -h<= x-a<= 0), (2*(h**3/3)-0.5*(x-a)**2*(2*h+(x-a)), 0<=x-a<=2*h), ((1/6)*(2*h-(x-a))**3, h<=x-a<=2*h), (0, x-a<=2*h))
/usr/local/lib/python3.8/dist-packages/sympy/core/relational.py in __nonzero__(self)
382
383 def __nonzero__(self):
--> 384 raise TypeError("cannot determine truth value of Relational")
385
386 __bool__ = __nonzero__
TypeError: cannot determine truth value of Relational
While np.piecewise is a numpy function, because x is a sympy.Symbol, the equations are sympy expressions. numpy and sympy are not well integrated. Somethings work, many others don't.
Did you try a small expression? Good programming practice is to start with small pieces, making sure those work first.
Let's try something smaller:
In [8]: expr = np.piecewise((0, x-a <= -2*h),
...: ((1/6)*(2*h+(x-a))**3, -2*h<=x-a<=-h))
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-8-37ff62e49efb> in <module>
1 expr = np.piecewise((0, x-a <= -2*h),
----> 2 ((1/6)*(2*h+(x-a))**3, -2*h<=x-a<=-h))
/usr/local/lib/python3.8/dist-packages/sympy/core/relational.py in __nonzero__(self)
382
383 def __nonzero__(self):
--> 384 raise TypeError("cannot determine truth value of Relational")
385
386 __bool__ = __nonzero__
TypeError: cannot determine truth value of Relational
and smaller pieces:
In [10]: (0, x-a <= -2*h)
Out[10]: (0, x + 1 ≤ -1.0)
In [11]: ((1/6)*(2*h+(x-a))**3, -2*h<=x-a<=-h)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-11-7bd9f95d077d> in <module>
----> 1 ((1/6)*(2*h+(x-a))**3, -2*h<=x-a<=-h)
/usr/local/lib/python3.8/dist-packages/sympy/core/relational.py in __nonzero__(self)
382
383 def __nonzero__(self):
--> 384 raise TypeError("cannot determine truth value of Relational")
385
386 __bool__ = __nonzero__
TypeError: cannot determine truth value of Relational
In [12]: (1/6)*(2*h+(x-a))**3
Out[12]:
3
1.33333333333333⋅(0.5⋅x + 1)
But:
In [13]: -2*h<=x-a<=-h
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-13-5ffb419cd443> in <module>
----> 1 -2*h<=x-a<=-h
/usr/local/lib/python3.8/dist-packages/sympy/core/relational.py in __nonzero__(self)
382
383 def __nonzero__(self):
--> 384 raise TypeError("cannot determine truth value of Relational")
385
386 __bool__ = __nonzero__
TypeError: cannot determine truth value of Relational
Simplify further:
In [14]: 0 < x < 3
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-14-59ba4ce00627> in <module>
----> 1 0 < x < 3
/usr/local/lib/python3.8/dist-packages/sympy/core/relational.py in __nonzero__(self)
382
383 def __nonzero__(self):
--> 384 raise TypeError("cannot determine truth value of Relational")
385
386 __bool__ = __nonzero__
TypeError: cannot determine truth value of Relational
While a < b < c is allowed for regular Python variables and scalars, it does not work for numpy arrays, and evidently doesn't work for sympy variables either.
So the immediate problem has nothing to do with numpy. You are using invalid sympy expressions!
===
Your basis function reveals an aspect of the same problem. Again we need to look at the FULL traceback, and then test portions to identify the exact problem expression.
In [16]: basis(x, -1,0.5,0)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-16-b328f95b3c79> in <module>
----> 1 basis(x, -1,0.5,0)
<ipython-input-15-c6436540e3f3> in basis(x, a, b, h)
1 def basis(x,a,b, h):
----> 2 if x <= a-2*h:
3 return 0;
4 elif (x<=a-h) or (x >=2*h):
5 return (1/6)*(2*h+(x-a))**3
/usr/local/lib/python3.8/dist-packages/sympy/core/relational.py in __nonzero__(self)
382
383 def __nonzero__(self):
--> 384 raise TypeError("cannot determine truth value of Relational")
385
386 __bool__ = __nonzero__
TypeError: cannot determine truth value of Relational
This expression is a sympy relational:
In [17]: x <= -1
Out[17]: x ≤ -1
But we can't use such a relational in a Python if statement.
In [18]: if x <= -1: pass
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-18-b56148a48367> in <module>
----> 1 if x <= -1: pass
/usr/local/lib/python3.8/dist-packages/sympy/core/relational.py in __nonzero__(self)
382
383 def __nonzero__(self):
--> 384 raise TypeError("cannot determine truth value of Relational")
385
386 __bool__ = __nonzero__
TypeError: cannot determine truth value of Relational
Python if is simple True/False switch; its argument must evaluate to one or the other. The error is telling us that a sympy.Relational does not work. 0 < x < 1 is variation on that basic Python if (it tests 0<x and x<1 and performs a and).
A variation on this that we often see in numpy (and pandas) is:
In [20]: 0 < np.array([0,1,2])
Out[20]: array([False, True, True])
In [21]: 0 < np.array([0,1,2])<1
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-21-bc1039cec1fc> in <module>
----> 1 0 < np.array([0,1,2])<1
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
The numpy expression has multiple True/False values, and can't be used im a Python expression that requires a simple True/False.
edit
Correctly expanding the two sided tests:
In [23]: expr = np.piecewise((0, x-a <= -2*h),
...: ((1/6)*(2*h+(x-a))**3, (-2*h<=x-a)&(x-a<=-h)),
...: (2*h**3/3-0.5*(x-a)**2*(2*h+(x-a)), (-h<= x-a)&(x-a<= 0)),
...: (2*(h**3/3)-0.5*(x-a)**2*(2*h+(x-a)), (0<=x-a)&(x-a<=2*h)),
...: ((1/6)*(2*h-(x-a))**3, (h<=x-a)&(x-a<=2*h)), (0, x-a<=2*h))
In [24]: expr
Out[24]:
array([-0.5*(x + 1)**2*(x + 2.0) + 0.0833333333333333,
-0.5*(x + 1)**2*(x + 2.0) + 0.0833333333333333], dtype=object)
In [26]: p = lambdify((x,), expr)
x is the only sympy symbol in expr.
Looking at the resulting function:
In [27]: print(p.__doc__)
Created with lambdify. Signature:
func(x)
Expression:
[-0.5*(x + 1)**2*(x + 2.0) + 0.0833333333333333 -0.5*(x + 1)**2*(x + 2.0)...
Source code:
def _lambdifygenerated(x):
return ([-0.5*(x + 1)**2*(x + 2.0) + 0.0833333333333333, -0.5*(x + 1)**2*(x + 2.0) + 0.0833333333333333])
sympyquestion thannumpy. In any case your function call fornp.piecewiseis not at all what the function expects so that's probably part of the problem