Пример #1
0
def interpolate(ts, xs, t, equidistant, mode=0):
    if interp1d is not None:
        if mode == 0:
            mode_str = 'linear'
        elif mode == 1:
            mode_str = 'floor'
        else:
            mode_str = 'ceil'
        return interp1d(ts, xs, t, mode_str, equidistant)
    else:
        if mode == 1:
            xs = xs[:-1]  # block-forward
        else:
            xs = xs[1:]  # block-backward
        t = ca.MX(t)
        if t.size1() > 1:
            t_ = ca.MX.sym('t')
            xs_ = ca.MX.sym('xs', xs.size1())
            f = ca.Function('interpolant', [t_, xs_], [
                ca.mtimes(ca.transpose((t_ >= ts[:-1]) * (t_ < ts[1:])), xs_)
            ])
            f = f.map(t.size1(), 'serial')
            return ca.transpose(f(ca.transpose(t), ca.repmat(xs, 1,
                                                             t.size1())))
        else:
            return ca.mtimes(ca.transpose((t >= ts[:-1]) * (t < ts[1:])), xs)
Пример #2
0
def interp(x, xp, fp, left=None, right=None, period=None):
    """
    One-dimensional linear interpolation, analogous to numpy.interp().

    Returns the one-dimensional piecewise linear interpolant to a function with given discrete data points (xp, fp),
    evaluated at x.

    See syntax here: https://numpy.org/doc/stable/reference/generated/numpy.interp.html

    Specific notes: xp is assumed to be sorted.
    """
    if not is_casadi_type([x, xp, fp], recursive=True):
        return _onp.interp(x=x,
                           xp=xp,
                           fp=fp,
                           left=left,
                           right=right,
                           period=period)

    else:
        ### If xp or x are CasADi types, this is unsupported :(
        if is_casadi_type([x, xp], recursive=True):
            raise NotImplementedError(
                "Unfortunately, CasADi doesn't yet support a dispatch for x or xp as CasADi types."
            )

        ### Handle period argument
        if period is not None:
            if any(logical_or(xp < 0, xp > period)):
                raise NotImplementedError(
                    "Haven't yet implemented handling for if xp is outside the period."
                )  # Not easy to implement because casadi doesn't have a sort feature.

            x = _cas.mod(x, period)

        ### Make sure x isn't an int
        if isinstance(x, int):
            x = float(x)

        ### Make sure that x is an iterable
        try:
            x[0]
        except TypeError:
            x = array([x], dtype=float)

        ### Make sure xp is an iterable
        xp = array(xp, dtype=float)

        ### Do the interpolation
        f = _cas.interp1d(xp, fp, x)

        ### Handle left/right
        if left is not None:
            f = where(x < xp[0], left, f)
        if right is not None:
            f = where(x > xp[-1], right, f)

        ### Return
        return f
Пример #3
0
    def create_objective(self, model):
        self.obj_1 = sum(
            w / len(ov) * ca.sumsqr(self.densities * (ov - cm @ ca.interp1d(
                model.observation_times,
                om(model.observation_times, model.ps, *
                   (model.xs[j] for j in oj)), self.observation_times)))
            for om, oj, ov, w, cm in zip(
                self.observation_model, self.observation_vector,
                self.observations, self.weightings, self.collocation_matrices))
        self.obj_2 = sum(
            ca.sumsqr((model.xdash[:, i] - model.model(
                model.observation_times, *model.cs, *model.ps)[:, i]))
            for i in range(model.s)) / model.n

        self.regularisation = ca.sumsqr(
            (ca.vcat(model.ps) - ca.vcat(self.regularisation_vector)) /
            (1 + ca.vcat(self.regularisation_vector)))

        self.objective = self.obj_1 + self.rho * self.obj_2 + self.alpha * self.regularisation