def _eval_simplify(self, **kwargs): from .add import Add from sympy.core.expr import Expr from sympy.solvers.solveset import linear_coeffs # standard simplify e = super()._eval_simplify(**kwargs) if not isinstance(e, Equality): return e if not isinstance(e.lhs, Expr) or not isinstance(e.rhs, Expr): return e free = self.free_symbols if len(free) == 1: try: x = free.pop() m, b = linear_coeffs(e.rewrite(Add, evaluate=False), x) if m.is_zero is False: enew = e.func(x, -b / m) else: enew = e.func(m * x, -b) measure = kwargs['measure'] if measure(enew) <= kwargs['ratio'] * measure(e): e = enew except ValueError: pass return e.canonical
def T_eq_to_matrix(i): eq = T[i] print(f'Now seperating {i+1}/{len(T)}th row') arg_list = linear_coeffs(eq, *var_list_dt_dt) b = arg_list.pop() A = arg_list return A, b
def _solve(eq, target, **kwargs): """ To be remved at next Devito release """ if isinstance(eq, Eq): eq = eq.lhs - eq.rhs if eq.rhs != 0 else eq.lhs # Try first linear solver cc = linear_coeffs(eq.evaluate, target) return diffify(-cc[1] / cc[0])
def __new__(cls, *args, **kwargs): from sympy.geometry.util import find from .polygon import Triangle evaluate = kwargs.get('evaluate', global_parameters.evaluate) if len(args) == 1 and isinstance(args[0], (Expr, Eq)): x = kwargs.get('x', 'x') y = kwargs.get('y', 'y') equation = args[0] if isinstance(equation, Eq): equation = equation.lhs - equation.rhs x = find(x, equation) y = find(y, equation) try: a, b, c, d, e = linear_coeffs(equation, x**2, y**2, x, y) except ValueError: raise GeometryError( "The given equation is not that of a circle.") if a == 0 or b == 0 or a != b: raise GeometryError( "The given equation is not that of a circle.") center_x = -c / a / 2 center_y = -d / b / 2 r2 = (center_x**2) + (center_y**2) - e return Circle((center_x, center_y), sqrt(r2), evaluate=evaluate) else: c, r = None, None if len(args) == 3: args = [Point(a, dim=2, evaluate=evaluate) for a in args] t = Triangle(*args) if not isinstance(t, Triangle): return t c = t.circumcenter r = t.circumradius elif len(args) == 2: # Assume (center, radius) pair c = Point(args[0], dim=2, evaluate=evaluate) r = args[1] # this will prohibit imaginary radius try: r = Point(r, 0, evaluate=evaluate).x except ValueError: raise GeometryError( "Circle with imaginary radius is not permitted") if not (c is None or r is None): if r == 0: return c return GeometryEntity.__new__(cls, c, r, **kwargs) raise GeometryError("Circle.__new__ received unknown arguments")
def __new__(cls, *args, **kwargs): from sympy.geometry.util import find from .polygon import Triangle evaluate = kwargs.get('evaluate', global_evaluate[0]) if len(args) == 1 and isinstance(args[0], Expr): x = kwargs.get('x', 'x') y = kwargs.get('y', 'y') equation = args[0] if isinstance(equation, Eq): equation = equation.lhs - equation.rhs x = find(x, equation) y = find(y, equation) try: a, b, c, d, e = linear_coeffs(equation, x**2, y**2, x, y) except ValueError: raise GeometryError("The given equation is not that of a circle.") if a == 0 or b == 0 or a != b: raise GeometryError("The given equation is not that of a circle.") center_x = -c/a/2 center_y = -d/b/2 r2 = (center_x**2) + (center_y**2) - e return Circle((center_x, center_y), sqrt(r2), evaluate=evaluate) else: c, r = None, None if len(args) == 3: args = [Point(a, dim=2, evaluate=evaluate) for a in args] t = Triangle(*args) if not isinstance(t, Triangle): return t c = t.circumcenter r = t.circumradius elif len(args) == 2: # Assume (center, radius) pair c = Point(args[0], dim=2, evaluate=evaluate) r = args[1] # this will prohibit imaginary radius try: r = Point(r, 0, evaluate=evaluate).x except: raise GeometryError("Circle with imaginary radius is not permitted") if not (c is None or r is None): if r == 0: return c return GeometryEntity.__new__(cls, c, r, **kwargs) raise GeometryError("Circle.__new__ received unknown arguments")
def __new__(cls, *args, **kwargs): from sympy.geometry.util import find from .polygon import Triangle if len(args) == 1 and isinstance(args[0], Expr): x = kwargs.get('x', 'x') y = kwargs.get('y', 'y') equation = args[0] if isinstance(equation, Eq): equation = equation.lhs - equation.rhs x = find(x, equation) y = find(y, equation) try: co = linear_coeffs(equation, x**2, y**2, x, y) except ValueError: raise GeometryError( "The given equation is not that of a circle.") a, b, c, d, e = [co[i] for i in (x**2, y**2, x, y, 0)] if a == 0 or b == 0 or a != b: raise GeometryError( "The given equation is not that of a circle.") center_x = -c / a / 2 center_y = -d / b / 2 r2 = (center_x**2) + (center_y**2) - e return Circle((center_x, center_y), sqrt(r2)) else: c, r = None, None if len(args) == 3: args = [Point(a, dim=2) for a in args] t = Triangle(*args) if not isinstance(t, Triangle): return t c = t.circumcenter r = t.circumradius elif len(args) == 2: # Assume (center, radius) pair c = Point(args[0], dim=2) r = sympify(args[1]) if not (c is None or r is None): if r == 0: return c return GeometryEntity.__new__(cls, c, r, **kwargs) raise GeometryError("Circle.__new__ received unknown arguments")
def __new__(cls, *args, **kwargs): from sympy.geometry.util import find from .polygon import Triangle if len(args) == 1 and isinstance(args[0], Expr): x = kwargs.get('x', 'x') y = kwargs.get('y', 'y') equation = args[0] if isinstance(equation, Eq): equation = equation.lhs - equation.rhs x = find(x, equation) y = find(y, equation) try: co = linear_coeffs(equation, x**2, y**2, x, y) except ValueError: raise GeometryError("The given equation is not that of a circle.") a, b, c, d, e = [co[i] for i in (x**2, y**2, x, y, 0)] if a == 0 or b == 0 or a != b: raise GeometryError("The given equation is not that of a circle.") center_x = -c/a/2 center_y = -d/b/2 r2 = (center_x**2) + (center_y**2) - e return Circle((center_x, center_y), sqrt(r2)) else: c, r = None, None if len(args) == 3: args = [Point(a, dim=2) for a in args] t = Triangle(*args) if not isinstance(t, Triangle): return t c = t.circumcenter r = t.circumradius elif len(args) == 2: # Assume (center, radius) pair c = Point(args[0], dim=2) r = sympify(args[1]) if not (c is None or r is None): if r == 0: return c return GeometryEntity.__new__(cls, c, r, **kwargs) raise GeometryError("Circle.__new__ received unknown arguments")
def _eval_simplify(self, ratio, measure, rational, inverse): from sympy.solvers.solveset import linear_coeffs # standard simplify e = super(Equality, self)._eval_simplify(ratio, measure, rational, inverse) if not isinstance(e, Equality): return e free = self.free_symbols if len(free) == 1: try: x = free.pop() m, b = linear_coeffs(e.rewrite(Add, evaluate=False), x) if m.is_zero is False: enew = e.func(x, -b / m) else: enew = e.func(m * x, -b) if measure(enew) <= ratio * measure(e): e = enew except ValueError: pass return e.canonical
def _eval_simplify(self, ratio, measure, rational, inverse): from sympy.solvers.solveset import linear_coeffs # standard simplify e = super(Equality, self)._eval_simplify( ratio, measure, rational, inverse) if not isinstance(e, Equality): return e free = self.free_symbols if len(free) == 1: try: x = free.pop() m, b = linear_coeffs( e.rewrite(Add, evaluate=False), x) if m.is_zero is False: enew = e.func(x, -b/m) else: enew = e.func(m*x, -b) if measure(enew) <= ratio*measure(e): e = enew except ValueError: pass return e.canonical
def eqsimp(eq, **kwargs): # standard simplify eq = relsimp(eq.function, eq.arguments, **kwargs) if not isinstance(eq.lhs, Expr) or not isinstance(eq.rhs, Expr): return eq free = eq.free_symbols if len(free) == 1: try: x = free.pop() m, b = linear_coeffs( _convert_to_Add(eq, evaluate=False), x) if m.is_zero is False: eqnew = eq.function(x, -b / m) else: eqnew = eq.function(m * x, -b) measure = kwargs['measure'] if measure(eqnew) <= kwargs['ratio'] * measure(eq): eq = eqnew except ValueError: pass return eq.canonical
def solve(eq, target, **kwargs): """ Algebraically rearrange an Eq w.r.t. a given symbol. This is a wrapper around ``sympy.solve``. Parameters ---------- eq : expr-like The equation to be rearranged. target : symbol The symbol w.r.t. which the equation is rearranged. May be a `Function` or any other symbolic object. **kwargs Symbolic optimizations applied while rearranging the equation. For more information. refer to ``sympy.solve.__doc__``. """ if isinstance(eq, Eq): eq = eq.lhs - eq.rhs if eq.rhs != 0 else eq.lhs sols = [] for e, t in zip(as_tuple(eq), as_tuple(target)): # Try first linear solver try: cc = linear_coeffs(e._eval_at(t).evaluate, t) sols.append(-cc[1] / cc[0]) except ValueError: warning( "Equation is not affine w.r.t the target, falling back to standard" "sympy.solve that may be slow") kwargs['rational'] = False # Avoid float indices kwargs['simplify'] = False # Do not attempt premature optimisation sols.append(sympy.solve(e.evaluate, t, **kwargs)[0]) # We need to rebuild the vector/tensor as sympy.solve outputs a tuple of solutions if len(sols) > 1: return target.new_from_mat(sols) else: return sols[0]
def _eval_simplify(self, **kwargs): from .add import Add from sympy.core.expr import Expr r = self r = r.func(*[i.simplify(**kwargs) for i in r.args]) if r.is_Relational: if not isinstance(r.lhs, Expr) or not isinstance(r.rhs, Expr): return r dif = r.lhs - r.rhs # replace dif with a valid Number that will # allow a definitive comparison with 0 v = None if dif.is_comparable: v = dif.n(2) elif dif.equals(0): # XXX this is expensive v = S.Zero if v is not None: r = r.func._eval_relation(v, S.Zero) r = r.canonical # If there is only one symbol in the expression, # try to write it on a simplified form free = list( filter(lambda x: x.is_real is not False, r.free_symbols)) if len(free) == 1: try: from sympy.solvers.solveset import linear_coeffs x = free.pop() dif = r.lhs - r.rhs m, b = linear_coeffs(dif, x) if m.is_zero is False: if m.is_negative: # Dividing with a negative number, so change order of arguments # canonical will put the symbol back on the lhs later r = r.func(-b / m, x) else: r = r.func(x, -b / m) else: r = r.func(b, S.zero) except ValueError: # maybe not a linear function, try polynomial from sympy.polys import Poly, poly, PolynomialError, gcd try: p = poly(dif, x) c = p.all_coeffs() constant = c[-1] c[-1] = 0 scale = gcd(c) c = [ctmp / scale for ctmp in c] r = r.func( Poly.from_list(c, x).as_expr(), -constant / scale) except PolynomialError: pass elif len(free) >= 2: try: from sympy.solvers.solveset import linear_coeffs from sympy.polys import gcd free = list(ordered(free)) dif = r.lhs - r.rhs m = linear_coeffs(dif, *free) constant = m[-1] del m[-1] scale = gcd(m) m = [mtmp / scale for mtmp in m] nzm = list(filter(lambda f: f[0] != 0, list(zip(m, free)))) if scale.is_zero is False: if constant != 0: # lhs: expression, rhs: constant newexpr = Add(*[i * j for i, j in nzm]) r = r.func(newexpr, -constant / scale) else: # keep first term on lhs lhsterm = nzm[0][0] * nzm[0][1] del nzm[0] newexpr = Add(*[i * j for i, j in nzm]) r = r.func(lhsterm, -newexpr) else: r = r.func(constant, S.zero) except ValueError: pass # Did we get a simplified result? r = r.canonical measure = kwargs['measure'] if measure(r) < kwargs['ratio'] * measure(self): return r else: return self
def relsimp(func, args, **kwargs): lhs, rhs = args r = func(lhs.simplify(**kwargs), rhs.simplify(**kwargs)) if not isinstance(r.lhs, Expr) or not isinstance(r.rhs, Expr): return r.canonical dif = r.lhs - r.rhs r = r.canonical # If there is only one symbol in the expression, # try to write it on a simplified form free = list(filter(lambda x: x.is_real is not False, r.free_symbols)) if len(free) == 1: try: x = free.pop() dif = r.lhs - r.rhs m, b = linear_coeffs(dif, x) if m.is_zero is False: if m.is_negative: # Dividing with a negative number, so change order of arguments # canonical will put the symbol back on the lhs later r = r.function(-b / m, x) else: r = r.function(x, -b / m) else: r = r.function(b, S.Zero) except ValueError: # maybe not a linear function, try polynomial try: p = poly(dif, x) c = p.all_coeffs() constant = c[-1] c[-1] = 0 scale = gcd(c) c = [ctmp / scale for ctmp in c] r = r.function(Poly.from_list(c, x).as_expr(), -constant / scale) except PolynomialError: pass elif len(free) >= 2: try: free = list(ordered(free)) dif = r.lhs - r.rhs m = linear_coeffs(dif, *free) constant = m[-1] del m[-1] scale = gcd(m) m = [mtmp / scale for mtmp in m] nzm = list(filter(lambda f: f[0] != 0, list(zip(m, free)))) if scale.is_zero is False: if constant != 0: # lhs: expression, rhs: constant newexpr = Add(*[i * j for i, j in nzm]) r = r.function(newexpr, -constant / scale) else: # keep first term on lhs lhsterm = nzm[0][0] * nzm[0][1] del nzm[0] newexpr = Add(*[i * j for i, j in nzm]) r = r.function(lhsterm, -newexpr) else: r = r.function(constant, S.Zero) except ValueError: pass # Did we get a simplified result? r = r.canonical rel = func(*args) measure = kwargs['measure'] if measure(r) < kwargs['ratio'] * measure(rel): return r else: return rel
def linearcoeff(i): output = linear_coeffs(T[i], *q_list_dt_dt) print(f'Now finished calculating {i+1}/{len(q_list_dt_dt)} th row') return output