Example #1
0
    def __new__ (cls, arg, **options):
#        print "Inverse(", arg, ")"
#        print INVERTIBLE
        if isinstance(arg, Inverse):
            return arg.args[0]
        if arg.is_Number:
            return 1 / arg

        arg_rank = expr_rank(arg)
        if arg_rank == 1:
            raise NotInvertibleError

        if is_one(arg):
            return arg
        if is_zero(arg):
            raise NotInvertibleError

        # FIXME: Funky case trying to catch lower triangular or diagonal
        #        muls like T(P_0)*A*P_0
        if arg in INVERTIBLE:
            pass
        elif isinstance(arg, TensorExpr) and not arg.has_inverse:
            raise NotInvertibleError
        elif isinstance(arg, Mul):
            if arg.args[0] == S(-1):
                return - Inverse(reduce(operator.mul, arg.args[1:]))
        if not expr_invertible(arg):
            raise NotInvertibleError
        options['commutative'] = arg.is_commutative
        return Basic.__new__(cls, arg, **options)
Example #2
0
def expr_invertible(expr):
    if expr.is_Number:
        return True
    if isinstance(expr, TensorExpr) and expr.has_inverse:
        return True
    elif isinstance(expr, Pow):
        return expr_invertible(expr.args[0])
    if isinstance(expr, Inverse):
        return True
    if expr in INVERTIBLE:
        return True
    er = expr_rank(expr)
    if er == 1:
        return False
    if is_one(expr):
        return True
    if is_zero(expr):
        return False
    # FIXME: Funky case trying to catch lower triangular or diagonal
    #        muls like T(P_0)*A*P_0
    if isinstance(expr, Mul):
        return reduce(lambda acc, x: acc and expr_invertible(x), expr.args,
                      True)
    if isinstance(expr, Pow):
        return expr_invertible(expr.args[0])
def expr_invertible(expr):
    if expr.is_Number:
        return True
    if isinstance(expr, TensorExpr) and expr.has_inverse:
        return True
    elif isinstance(expr, Pow):
        return expr_invertible(expr.args[0])
    if isinstance(expr, Inverse):
        return True
    if expr in INVERTIBLE:
        return True
    er = expr_rank(expr)
    if er == 1:
        return False
    if is_one(expr):
        return True
    if is_zero(expr):
        return False
    # FIXME: Funky case trying to catch lower triangular or diagonal
    #        muls like T(P_0)*A*P_0
    if isinstance(expr, Mul):
        return reduce(lambda acc, x: acc and expr_invertible(x), expr.args, True)
    if isinstance(expr, Pow):
        return expr_invertible(expr.args[0])