Exemple #1
0
 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
Exemple #2
0
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
Exemple #3
0
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])
Exemple #4
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")
Exemple #5
0
    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")
Exemple #6
0
    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")
Exemple #7
0
    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")
Exemple #8
0
 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
Exemple #9
0
 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
Exemple #10
0
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
Exemple #11
0
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]
Exemple #12
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
Exemple #13
0
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