'Evaluate the piecewise polynomial or its derivative.
Parameters
x : array_like
Points to evaluate the interpolant at.
nu : int, optional
Order of derivative to evaluate. Must be non-negative.
extrapolate : {bool, \'periodic\', None}, optional
If bool, determines whether to extrapolate to out-of-bounds points
based on first and last intervals, or to return NaNs.
If \'periodic\', periodic extrapolation is used.
If None (default), use `self.extrapolate`.
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=0, extrapolate=None):

    if (extrapolate is None):
        extrapolate = self.extrapolate
    x = np.asarray(x)
    (x_shape, x_ndim) = (x.shape, x.ndim)
    x = np.ascontiguousarray(x.ravel(), dtype=np.float_)
    if (extrapolate == 'periodic'):
        x = (self.x[0] + ((x - self.x[0]) % (self.x[(-1)] - self.x[0])))
        extrapolate = False
    out = np.empty((len(x), prod(self.c.shape[2:])), dtype=self.c.dtype)
    self._ensure_c_contiguous()
    self._evaluate(x, nu, extrapolate, out)
    out = out.reshape((x_shape + self.c.shape[2:]))
    if (self.axis != 0):
        l = list(range(out.ndim))
        l = ((l[x_ndim:(x_ndim + self.axis)] + l[:x_ndim]) + l[(x_ndim + self.axis):])
        out = out.transpose(l)
    return out
