def _complement(self, other): """complement two set builder >>> from sympy import * >>> from symplus.strplus import init_mprinting >>> init_mprinting() >>> x, y = symbols('x y') >>> AbstractSet(y, abs(y)<=3)._complement(AbstractSet(x, abs(x)>1)) {y | (|y| > 1) /\ (|y| > 3)} >>> AbstractSet((x,y), abs(x-y)>1)._complement(AbstractSet(x, abs(x)>1)) {x | |x| > 1} >>> AbstractSet(y, y<=x)._complement(AbstractSet(x, abs(x)>1)) {y | (y > x) /\ (|y| > 1)} >>> x2 = symbols('x2', positive=True) >>> AbstractSet(x, abs(x)>1)._complement(AbstractSet(x2, x2<=y)) {x | (x =< y) /\ (|x| =< 1)} >>> m, n = MatrixSymbol('m', 2, 2), MatrixSymbol('n', 2, 2) >>> AbstractSet(n, Eq(det(n),0))._complement(AbstractSet(m, Eq(m[0,0]+m[1,1],0))) {n | (0 =/= ||n||) /\ (0 == n[0, 0] + n[1, 1])} >>> AbstractSet(x, abs(x)>1)._complement(AbstractSet(m, Eq(m[0,0]+m[1,1],0))) {m | 0 == m[0, 0] + m[1, 1]} >>> AbstractSet(x, abs(x)>1)._complement(Interval(1,2)) """ if isinstance(other, AbstractSet): vars1 = self.variables vars2 = other.variables if not type_match(vars1, vars2): return other vars12 = rename_variables_in(vars1, free_symbols(self) | free_symbols(other)) expr12 = And( other.expr.xreplace(dict(zip(vars2, vars12))), Not(self.expr.xreplace(dict(zip(vars1, vars12)))) ) return AbstractSet(vars12, expr12)
def is_equivalent(self, other): """ >>> from sympy import * >>> from symplus.strplus import init_mprinting >>> init_mprinting() >>> x, y = symbols('x y') >>> AbstractSet(x, x-y>1).is_equivalent(AbstractSet(x, x-y>1)) True >>> AbstractSet(x, x<1).is_equivalent(AbstractSet(x, x-1<0)) A. x st (x - 1 < 0) <=> (x < 1) >>> AbstractSet(x, abs(x)>1).is_equivalent(Interval(1,2)) A. x st (x =< 2) /\ (x >= 1) <=> (|x| > 1) """ if isinstance(other, AbstractSet): vars1 = self.variables vars2 = other.variables if not type_match(vars1, vars2): return false vars12 = rename_variables_in(vars1, free_symbols(self) | free_symbols(other)) return Forall( vars12, Equivalent(self.expr.xreplace(dict(zip(vars1, vars12))), other.expr.xreplace(dict(zip(vars2, vars12)))), ) else: other_ = as_abstract(other) if isinstance(other_, AbstractSet): return self.is_equivalent(other_) else: raise ValueError("Unknown argument '%s'" % other)
def eval(func): if func == Id: return Id elif isinstance(func, FunctionInverse): return func.function elif isinstance(func, FunctionCompose): return FunctionCompose( *[FunctionInverse(f, evaluate=True) for f in func.functions[::-1]], evaluate=False) if hasattr(func, '_inv'): inv_func = func._inv() if inv_func is not None: return inv_func elif isinstance(func, Lambda): var = symbols('a:%s'%nres(func)) var = rename_variables_in(var, free_symbols(func)) res = solve_inv(func, *var) if res is not None: return Lambda(var, res) elif isinstance(func, FunctionClass): return FunctionClass_inverse(func) return FunctionInverse(func, evaluate=False)
def _union(self, other): """union two set builder >>> from sympy import * >>> from symplus.strplus import init_mprinting >>> init_mprinting() >>> x, y = symbols('x y') >>> AbstractSet(x, abs(x)>1)._union(AbstractSet(y, abs(y)<3)) {x | (|x| < 3) \/ (|x| > 1)} >>> AbstractSet(x, abs(x)>1)._union(AbstractSet((x,y), abs(x-y)>1)) >>> AbstractSet(x, abs(x)>1)._union(AbstractSet(y, y<x)) {x_ | (x_ < x) \/ (|x_| > 1)} >>> x2 = symbols('x2', positive=True) >>> AbstractSet(x, abs(x)>1)._union(AbstractSet(x2, x2<y)) {x | (x < y) \/ (|x| > 1)} >>> m, n = MatrixSymbol('m', 2, 2), MatrixSymbol('n', 2, 2) >>> AbstractSet(m, Eq(m[0,0]+m[1,1],0))._union(AbstractSet(n, Eq(det(n),0))) {m | (0 == m[0, 0] + m[1, 1]) \/ (0 == ||m||)} >>> AbstractSet(m, Eq(m[0,0]+m[1,1],0))._union(AbstractSet(x, abs(x)>1)) >>> AbstractSet(x, abs(x)>1)._union(Interval(1,2)) """ if isinstance(other, AbstractSet): vars1 = self.variables vars2 = other.variables if not type_match(vars1, vars2): return None vars12 = rename_variables_in(vars1, free_symbols(self) | free_symbols(other)) expr12 = Or(self.expr.xreplace(dict(zip(vars1, vars12))), other.expr.xreplace(dict(zip(vars2, vars12)))) return AbstractSet(vars12, expr12)
def as_abstract(zet): if hasattr(zet, "as_abstract"): return zet.as_abstract() elif isinstance(zet, ProductSet): args = tuple(as_abstract(arg) for arg in zet.args) if all(isinstance(arg, AbstractSet) for arg in args): return reduce(operator.mul, args) else: return zet elif isinstance(zet, (Intersection, Union, Complement, AbsoluteComplement)): return zet.func(*[as_abstract(e) for e in zet.args]) else: x = Symbol("x", real=True) x = rename_variables_in(x, free_symbols(zet)) expr = zet.contains(x) return AbstractSet(x, expr)
def solve_inv(func, *args): vars = symbols('a:%s'%narg(func)) vars = rename_variables_in(vars, free_symbols(func) | free_symbols(Tuple(*args))) exprs = pack_if_not(func(*vars)) if len(args) != len(exprs): raise ValueError try: solns = solve([expr - val for val, expr in zip(args, exprs)], vars) if isinstance(solns, list): solns = dict(zip(vars, solns[0])) if len(vars) == 1: return solns[vars[0]] else: return tuple(solns[var] for var in vars) except NotImplementedError: return None
def _eval_product(self, other): """ >>> from sympy import * >>> from symplus.strplus import init_mprinting >>> init_mprinting() >>> x, y = symbols('x y') >>> AbstractSet(x, abs(x)>1)._eval_product(AbstractSet(y, y<x)) {(x, y) | (y < x) /\ (|x| > 1)} >>> AbstractSet(x, abs(x)>1)._eval_product(AbstractSet((x,y), abs(x-y)>1)) {(x, x_, y) | (|x_ - y| > 1) /\ (|x| > 1)} """ if isinstance(other, AbstractSet): vars1 = self.variables expr1 = self.expr vars2 = other.variables expr2 = other.expr vars2_ = rename_variables_in(vars2, free_symbols(self) | set(vars1)) expr2_ = expr2.xreplace(dict(zip(vars2, vars2_))) return AbstractSet(tuple(vars1) + tuple(vars2_), And(expr1, expr2_)) else: return None
def as_lambda(func): """ >>> from sympy import * >>> from symplus.strplus import init_mprinting >>> init_mprinting() >>> as_lambda(exp) (a0 |-> exp(a0)) >>> as_lambda(FunctionCompose(exp, sin)) (a0 |-> exp(sin(a0))) >>> x = symbols('x') >>> as_lambda(FunctionInverse(Lambda(x, sin(x)+exp(x)))) (a0 |-> Apply(FunctionInverse(Lambda(x, exp(x) + sin(x))), a0)) """ if isinstance(func, Lambda): return func elif hasattr(func, 'as_lambda'): return func.as_lambda() else: var = symbols('a:%s'%narg(func)) var = rename_variables_in(var, free_symbols(func)) return Lambda(var, func(*var))
def reduce(funcs): i = 0 while i < len(funcs): if funcs[i] == Id: funcs = funcs[:i] + funcs[i+1:] elif isinstance(funcs[i], FunctionCompose): funcs = funcs[:i] + funcs[i].functions + funcs[i+1:] elif i-1 >= 0: if is_inverse_of(funcs[i-1], funcs[i]): funcs = funcs[:i-1] + funcs[i+1:] i = i - 2 elif hasattr(funcs[i-1], '_compose'): comp_funcs = funcs[i-1]._compose(funcs[i]) if comp_funcs is not None: funcs = funcs[:i-1] + (comp_funcs,) + funcs[i+1:] i = i - 1 elif isinstance(funcs[i-1], Lambda) and isinstance(funcs[i], Lambda): variables = rename_variables_in(funcs[i].variables, free_symbols(funcs[i-1])) expr = funcs[i].expr comp_funcs = Lambda(variables, funcs[i-1](*pack_if_not(expr))) funcs = funcs[:i-1] + (comp_funcs,) + funcs[i+1:] i = i - 1 i = i + 1 return funcs
def as_lambda(self): lambdas = tuple(pth.as_lambda() for pth in self.paths) t = lambdas[0].variables t = rename_variables_in(t, free_symbols(lambdas)) return Lambda(t, tuple(f(*t) for f in lambdas))
def as_lambda(self): t = Symbol('t') t = rename_variables_in(t, free_symbols(self)) return Lambda(t, self(t))