Sympy:手动处理等式

9
我目前正在学习数学课程,我的目标是理解概念和过程,而不是尽可能快地完成问题集。在解决方程时,我希望能够自己研究它们,而不是让它们为我解决。
假设我们有一个非常简单的方程z + 1 = 4 - 如果我要自己解决这个问题,我显然会从两边减去1,但我想知道是否有一个简单的方法在sympy中实现这个过程。目前,我能想到的最好的解决办法是:
from sympy import *
z = symbols('z')
eq1 = Eq(z + 1, 4)
Eq(eq1.lhs - 1, eq1.rhs - 1)
# Output:
# z == 3

更为显然的表达式eq1 - 1只是从左侧减去。我该如何使用sympy逐步处理这样的等式(即不使用solve()方法直接获得答案)?非常感谢提供有关sympy等式实际可操作性的任何指针。


我向开发人员提出了同样的问题,因为我觉得现有的方法不直观。不过,Mathematica 的行为方式也是如此。 - Omegaman
“如果你只需要输入 eq_2 = eq * denom 就能完成操作,那不是很好吗?” 答案在这里:自定义 Python 的 sympy 以便轻松操作方程式 - mins
1个回答

11

https://github.com/sympy/sympy/issues/5031#issuecomment-36996878有一个“do”方法和讨论,可以让您对等式的两边进行操作。虽然它还没有被作为 SymPy 的新功能接受,但这是一个简单的插件,您可以使用。以下是方便起见贴出的内容:

def do(self, e, i=None, doit=False):
    """Return a new Eq using function given or a model
    model expression in which a variable represents each
    side of the expression.

    Examples
    ========

    >>> from sympy import Eq
    >>> from sympy.abc import i, x, y, z
    >>> eq = Eq(x, y)

    When the argument passed is an expression with one
    free symbol that symbol is used to indicate a "side"
    in the Eq and an Eq will be returned with the sides
    from self replaced in that expression. For example, to
    add 2 to both sides:

    >>> eq.do(i + 2)
    Eq(x + 2, y + 2)

    To add x to both sides:

    >>> eq.do(i + x)
    Eq(2*x, x + y)

    In the preceding it was actually ambiguous whether x or i
    was to be added but the rule is that any symbol that are
    already in the expression are not to be interpreted as the
    dummy variable. If we try to add z to each side, however, an 
    error is raised because now it is unclear whether i or z is being
    added:

    >>> eq.do(i + z)
    Traceback (most recent call last):
    ...
    ValueError: not sure what symbol is being used to represent a side

    The ambiguity must be resolved by indicating with another parameter 
    which is the dummy variable representing a side:

    >>> eq.do(i + z, i)
    Eq(x + z, y + z)

    Alternatively, if only one Dummy symbol appears in the expression then
    it will be automatically used to represent a side of the Eq.

    >>> eq.do(2*Dummy() + z)
    Eq(2*x + z, 2*y + z)

    Operations like differentiation must be passed as a
    lambda:

    >>> Eq(x, y).do(lambda i: i.diff(x))
    Eq(1, 0)

    Because doit=False by default, the result is not evaluated. to
    evaluate it, either use the doit method or pass doit=True.

    >>> _.doit == Eq(x, y).do(lambda i: i.diff(x), doit=True)
    True
    """
    if not isinstance(e, (FunctionClass, Lambda, type(lambda:1))):
      e = S(e)
      imaybe = e.free_symbols - self.free_symbols
      if not imaybe:
          raise ValueError('expecting a symbol')
      if imaybe and i and i not in imaybe:
          raise ValueError('indicated i not in given expression')
      if len(imaybe) != 1 and not i:
          d = [i for i in imaybe if isinstance(i, Dummy)]
          if len(d) != 1:
              raise ValueError(
                  'not sure what symbol is being used to represent a side')
          i = set(d)
      else:
          i = imaybe
      i = i.pop()
      f = lambda side: e.subs(i, side)
    else:
      f = e
    return self.func(*[f(side) for side in self.args], evaluate=doit)

from sympy.core.relational import Equality
Equality.do = do

很遗憾,六年后尚未合并 - mins
请参阅 https://awstip.com/customizing-pythons-sympy-for-easy-equation-manipulation-ca30b9d0dabf,了解有关自定义Python SymPy以便于方程操作的更多信息。 - smichr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接