SymPy中的功能

时间:2013-05-26 02:27:02

标签: python sympy

我是Python对象的新手并且有很多问题。我需要将一个函数传递给我的对象,然后评估该函数。代码类似于:

from sympy import var

class eval:
    def __init__(self, M):
        self.M = M

    def fun(self, x):
        M = self.M
        print M(x)

x = var('x')

ak = eval(x+2)
ak.fun(x)

这是错误:

TypeError
Traceback (most recent call last)
(ipython-input-1-b7ef311bd1f0> in <module)()
     12 
     13 ak = eval(x+2)
---> 14 ak.fun(x)

(ipython-input-1-b7ef311bd1f0) in fun(self, x)
      7     def fun(self, x):
      8         M = self.M
----> 9         print M(x)
     10 
     11 x = var('x')

TypeError: 'Add' object is not callable

3 个答案:

答案 0 :(得分:10)

  

我是Python对象的新手......

有问题很好,但SymPy背后的对象和类非常复杂,并且在强烈鼓励在钻研这样一个库之前学习Python object model的基础知识。

建议的代码存在许多问题:

纯语言相关错误

  • eval是内置的,因此覆盖它的风格很糟糕
  • 使用旧式课程

使用SymPy就好像它是某种语言扩展

SymPy 提供了创建python函数的新语法。特别是(x+2)(4) 会给你6。如果你想要这个,只需写myfun = lambda _: _+2; fun(4)而不使用SymPy。

x+2是一个SymPy对象(Add(Symbol('x')+Integer(2))),而不是一些python AST。您可以将x替换为(x+2).subs(x,y)的其他内容,但是当您编写Symbol('x')时,您不能指望图书馆神奇地知道您在(x+2)(4)时有一些特别的想法。你也可以写blah = Symbol('random_string'); (blah+2)(4)

次要SymPy错误

var是用于创建Symbol个对象的辅助函数,但它用于在解释器中进行交互式使用。不要在库代码中使用它,因为作为副作用,它会在命名空间中注入全局变量。只需使用Symbol('x')

现在约x+2可以调用

在0.7.2中实现了递归调用。这意味着您可以创建一个SymPy Expr树,其中包含未评估的符号对象,并将整个树应用于另一个对象,调用向内传播,直到所有未评估的对象都被评估的对象替换。我想上面的描述并不清楚,所以这里有一个例子:

您想要创建一个差异运算符对象D,它可以执行以下操作:

>>> op = g(y)*D # where g is Function and y is Symbol
>>> op(f(x))
g(y)*f(x).diff(x)

这种方法的工作方式是沿着树(在这种情况下为Mul(g(y), D)),跳过评估的符号对象并评估未评估的符号对象。

因为很多SymPy的用户在阅读数据模型之前就开始使用它,这引起了很多困惑,所以我们将递归调用方案移到了rc方法。在0.7.3 (x+2)(4)中会再次出现错误。

答案 1 :(得分:1)

这有几个问题。

  • 您没有将类定义为对象
  • 您将函数eval命名为保留字

试试这个:

class Eval(object):
    def __init__(self,m):
        self.M = m

    def fun(self,x):
        print self.M(x)

x = var('x')
ak = Eval(x+2)
ak.meth(x)
x + 2

HTH

答案 2 :(得分:1)

您的代码已经可以将函数传递给对象。函数是Python中的一等公民,你可以像任何其他对象一样传递它们。问题可能出在您的sympy版本上。比较:

>>> import sympy
>>> sympy.__version__
'0.7.1.rc1'
>>> from sympy.abc import x
>>> (x + 2)(x)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: 'Add' object is not callable

>>> import sympy
>>> sympy.__version__
'0.7.2'
>>> from sympy.abc import x
>>> (x + 2)(x)
x + 2

即,相同的代码适用于0.7.2,但在0.7.1rc1版本上失败。