Exemple #1
0
def inverse(expr):
    if type(expr) == atoms.ceil:
        return lambda t: atoms.floor(t)
    elif type(expr) == atoms.floor:
        return lambda t: atoms.ceil(t)
    elif type(expr) == NegExpression:
        return lambda t: -t
    elif type(expr) == atoms.exp:
        return lambda t: atoms.log(t) if t.is_nonneg() else -np.inf
    elif type(expr) == atoms.log:
        return lambda t: atoms.exp(t)
    elif type(expr) == atoms.log1p:
        return lambda t: atoms.exp(t) - 1
    elif type(expr) == atoms.logistic:
        return lambda t: atoms.log(atoms.exp(t) - 1) if t.is_nonneg() else -np.inf
    elif type(expr) == atoms.power:
        def power_inv(t):
            if expr.p == 1:
                return t
            return atoms.power(t, 1/expr.p) if t.is_nonneg() else np.inf
        return power_inv
    elif type(expr) == atoms.multiply:
        if expr.args[0].is_constant():
            const = expr.args[0]
        else:
            const = expr.args[1]
        return lambda t: t / const
    elif type(expr) == DivExpression:
        if expr.args[0].is_constant():
            const = expr.args[0]
        else:
            const = expr.args[1]
        return lambda t: t * const
    else:
        raise ValueError
Exemple #2
0
def inverse(expr):
    if type(expr) == atoms.ceil:
        return lambda t: atoms.floor(t)
    elif type(expr) == atoms.floor:
        return lambda t: atoms.ceil(t)
    elif type(expr) == NegExpression:
        return lambda t: -t
    elif type(expr) == atoms.exp:
        return lambda t: atoms.log(t) if t.is_nonneg() else -np.inf
    elif type(expr) == atoms.log:
        return lambda t: atoms.exp(t)
    elif type(expr) == atoms.log1p:
        return lambda t: atoms.exp(t) - 1
    elif type(expr) == atoms.logistic:
        return lambda t: atoms.log(atoms.exp(t) - 1) if t.is_nonneg(
        ) else -np.inf
    elif type(expr) == atoms.power:

        def power_inv(t):
            if expr.p.value == 1:
                return t
            return atoms.power(t, 1 /
                               expr.p.value) if t.is_nonneg() else np.inf

        return power_inv
    elif type(expr) == atoms.multiply:
        if expr.args[0].is_constant():
            const = expr.args[0]
        else:
            const = expr.args[1]
        return lambda t: t / const
    elif type(expr) == DivExpression:
        # either const / x <= t or x / const <= t
        if expr.args[0].is_constant():
            # numerator is constant
            const = expr.args[0]
            return lambda t: const / t
        else:
            # denominator is constant
            const = expr.args[1]
            return lambda t: const * t
    elif type(expr) == AddExpression:
        if expr.args[0].is_constant():
            const = expr.args[0]
        else:
            const = expr.args[1]
        return lambda t: t - const
    elif type(expr) == atoms.abs:
        arg = expr.args[0]
        if arg.is_nonneg():
            return lambda t: t
        elif arg.is_nonpos():
            return lambda t: -t
        else:
            raise ValueError("Sign of argument must be known.")
    elif type(expr) in (Sum, atoms.cumsum):
        return lambda t: t
    else:
        raise ValueError