'Evaluate the piecewise polynomial or its derivative
Parameters
x : array-like
Points to evaluate the interpolant at.
nu : tuple, optional
Orders of derivatives to evaluate. Each must be non-negative.
extrapolate : bool, optional
Whether to extrapolate to out-of-bounds points based on first
and last intervals, or to return NaNs.
Returns
y : array-like
Interpolated values. Shape is determined by replacing
the interpolation axis in the original array with the shape of x.
Notes
Derivatives are evaluated piecewise for each polynomial
segment, even if the polynomial is not differentiable at the
breakpoints. The polynomial intervals are considered half-open,
``[a, b)``, except for the last interval which is closed
``[a, b]``.'

def __call__(self, x, nu=None, extrapolate=None):

    if (extrapolate is None):
        extrapolate = self.extrapolate
    else:
        extrapolate = bool(extrapolate)
    ndim = len(self.x)
    x = _ndim_coords_from_arrays(x)
    x_shape = x.shape
    x = np.ascontiguousarray(x.reshape((-1), x.shape[(-1)]), dtype=np.float_)
    if (nu is None):
        nu = np.zeros((ndim,), dtype=np.intc)
    else:
        nu = np.asarray(nu, dtype=np.intc)
        if ((nu.ndim != 1) or (nu.shape[0] != ndim)):
            raise ValueError('invalid    number    of    derivative    orders    nu')
    dim1 = prod(self.c.shape[:ndim])
    dim2 = prod(self.c.shape[ndim:(2 * ndim)])
    dim3 = prod(self.c.shape[(2 * ndim):])
    ks = np.array(self.c.shape[:ndim], dtype=np.intc)
    out = np.empty((x.shape[0], dim3), dtype=self.c.dtype)
    self._ensure_c_contiguous()
    _ppoly.evaluate_nd(self.c.reshape(dim1, dim2, dim3), self.x, ks, x, nu, bool(extrapolate), out)
    return out.reshape((x_shape[:(-1)] + self.c.shape[(2 * ndim):]))
