【问题标题】:How to assign properties to symbols in SymPy and have them in the same domain?如何在 SymPy 中为符号分配属性并将它们放在同一个域中?
【发布时间】:2019-08-02 22:07:10
【问题描述】:

我想扩展SymPy 中的Symbols 类,以便添加布尔属性。我可以为单个符号完成此操作(请参阅我的问题 here,以及其他人的问题 here)。完成此操作的代码在下面重复:

from sympy.core.symbol import Symbol
class State(Symbol):
    def __init__(self, name, boolean_attr):
        self.boolean_attr = boolean_attr
        super(State, self).__init__(name)

但是,这个解决方案的问题在于,当我定义一个多项式或某种涉及多个 State 的表达式时,这是我对 Symbol 类的扩展,如您在上面看到的,我需要当我评估它们时,它们都在同一个域中:

单独定义的符号不能用数值计算:

x=sympy.symbols('x')
y=sympy.symbols('y')
some_poly = Poly(x+y)
print some_poly.evalf(subs=dict(zip([sympy.symbols('x, y')],[1,4])))
>>> Poly(x + y, x, y, domain='ZZ')

在同一域中定义的符号可以进行数值计算:

x, y = sympy.symbols('x, y')
some_poly = Poly(x+y)
print some_poly.evalf(subs=dict(zip(sympy.symbols('x,y'),[1,1])))
>>> 2.00000

这是我的问题:如何在我的class State 中实现同样的行为?理想情况下,它的工作方式如下:

x=State('x', boolean_attr=True)
y=State('y', boolean_attr=False)
states_poly = Poly(x+y)
print states_poly.evalf(subs=dict(zip(States('x,y'),[1,1])))
>>> 2.00000

但这不起作用,因为Sympy 将 x 和 y 解释为位于不同的域中。我该怎么做:

  • Sympyxy 解释为在同一个域中 或
  • 扩展State 类以能够在同一域中定义符号,例如:

    x, y =State('x, y', boolean_attr=[True, False])

如何允许对使用扩展类定义的多项式进行数值计算?

【问题讨论】:

    标签: python python-2.7 oop sympy


    【解决方案1】:

    在您的第一个示例中,您将 symbols 放在一个列表中,因此您没有使用值 1、4 压缩 x 和 y:

    >>> Poly(x+y).evalf(subs=dict(zip(sympy.symbols('x, y'),[1,4])))
    5.00000000000000
    

    如果您使用您定义的相同状态符号,您将获得所需的结果

    >>> x=State('x', boolean_attr=True)
    ... y=State('y', boolean_attr=False)
    ... states_poly = Poly(x+y)
    ... states_poly.evalf(subs=dict(zip((x,y),[1,1])))
    2.00000000000000
    

    (在您提出的语法中,您使用了未定义的States。即使它确实有效,这样的例程也不会将一个boolean_attr 设置为True,将另一个设置为False,并且由于符号在属性上匹配,因此替换会失败。)

    【讨论】:

    • 啊,我不敢相信它是那么微不足道!谢谢@smichr。我将它包含在列表中的原因是zip(sympy.symbols('x'),[1]) 不起作用,因为sympy.symbols('x') 不可迭代。但对于多个符号来说,这并不重要。
    • 也许是一个后续问题,那么一起初始化和单独初始化之间有没有区别:x=sympy.symbols('x'), y=sympy.symbols('y')x, y = sympy.symbols('x, y') 而我的问题只是错误地使用了zip。对吗?
    • 但是,正如您的回答帖子所示,states_poly.evalf(subs=dict(zip((x,y),[1,1])))states_poly.evalf(subs=dict(zip(sympy.symbols('x,y'),[1,1]))) 之间存在 区别。
    • symbols('x,') 将创建 (x,) 而不是 x。并且在一次初始化多个变量时,它们都使用相同的属性创建。
    • 但是如果你已经用一些特殊属性定义了 x 和 y,那么symbols('x,y') 不会创建相同的符号,它会创建 2 个具有相同名称但属性不同的新符号,并且是不同的。这就是你替换失败的原因。
    猜你喜欢
    • 2011-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-14
    • 1970-01-01
    • 2020-02-06
    • 1970-01-01
    相关资源
    最近更新 更多