最近,我重新安装了anaconda和sympy。然后,我运行以下示例的相同代码,这给了我错误。 (我之前没有这样的错误)
import sympy as sp
a, b= sp.symbols('a b', cls=sp.IndexedBase)
l= sp.symbols('l', cls=sp.Wild)
def Bfunc(expr,p1,p2):
if expr.base==p1:return expr.replace(p1[l],0.2*(p2[l]+p1[-l]),map=False, simultaneous=True, exact=True)
else: return expr.replace(p2[l],0.2*(p1[l]+p2[-l]),map=False, simultaneous=True, exact=True)
inputstate=a[0]*b[0]
psi0=inputstate.replace(lambda expr: expr.base in [a,b], lambda expr: Bfunc(expr,a,b))
它给了我错误:
问题是 expr.base ,它不能给出基数 a 或 b 。
让我们看一个非常简单的示例:
import sympy as sp
a, b= sp.symbols('a b', cls=sp.IndexedBase)
l= sp.symbols('l', cls=sp.Wild)
inputstate=a[0]*b[0]
inputstate.base
错误:
Traceback (most recent call last):
File "<ipython-input-59-7cc51ba4a4cd>", line 6, in <module>
inputstate.base
AttributeError: 'Mul' object has no attribute 'base'
如果 inputstate = a [0] ,则 inputstate.base 给您 < em> a 。
所以我想知道为什么在重新安装sympy和anaconda之后会发生这种错误。还是有任何方法可以提供所有基本列表并修复错误?
如果有人有类似情况,请给我一些提示,这将非常酷。预先谢谢你!
答案 0 :(得分:2)
您的foo
函数在遇到属性错误时返回None,并向replace
发出信号,表明该节点不应执行任何操作。当您使用lambda时,没有任何东西可以捕获该错误,因此该过程会引起您的注意。一种选择是更改replace
,使其忽略错误并仅跳过节点。但是,不这样做的好处是,它提醒您以下事实:您在做某事时会丢失要处理的对象。因此,要使用lambda,您必须帮助其成功识别感兴趣的条款。
>>> L1 = lambda x: x.is_Pow and x.base in [a, b]
>>> inputstate.replace(L1, lambda expr: Bfunc(expr,a,b))
a[0]*b[0]
>>> L2 = lambda x: x.as_base_exp()[0] in [a, b]
>>> inputstate.replace(L1, lambda expr: Bfunc(expr,a,b))
a[0]*b[0]
(我更喜欢L1,因为它使用快速is_Pow
测试来知道一个人是否正在处理电源。您的Bfunc假定它正在处理电源,因此L2不适用于所有情况,除非您还修改 it 来处理非战俘案件。)
要回答的一个问题是,您是要针对实际幂还是对幂为1的“幂”。例如,如果要将所有幂的指数提高1,您是否要x*y**2 -> x**2*y**3
还是只x*y**3
? L1适用于第一种情况,L2适用于第二种情况。
答案 1 :(得分:0)
a
是IndexedBase
,而a[0]
是Indexed
对象,其base is
a`:
In [21]: type(a)
Out[21]: sympy.tensor.indexed.IndexedBase
In [22]: type(a[0])
Out[22]: sympy.tensor.indexed.Indexed
In [23]: a[0].base
Out[23]: a
In [25]: inputstate=a[0]*b[0]
In [26]: inputstate
Out[26]: a[0]*b[0]
In [27]: type(inputstate)
Out[27]: sympy.core.mul.Mul
inputstate
是Mul
expr
对象。它不是Indexed
,所以没有基数。
您在sympy
的早期版本中是否有“正确”行为的记录,或者文档中有某种更改的证据。它在哪个版本上工作?
您的Bfunc
和replace
似乎对我有用:
In [51]: ab = inputstate.replace(lambda expr: expr.base in [a,b], lambda expr: Bfunc(expr,a,b))
In [52]: ab
Out[52]: a[0]*b[0]
In [53]: type(ab)
Out[53]: sympy.core.mul.Mul
我应该看到什么变化?
In [55]: sp.__version__
Out[55]: '1.3'
如果我通过一个小的函数来更改replace
lambda:
In [71]: def foo(expr):
...: try:
...: print(expr, expr.base)
...: return expr.base in [a,b]
...: except AttributeError:
...: print(expr)
...:
...:
In [72]: ab = inputstate.replace(foo, lambda expr: Bfunc(expr,a,b))
a
a
0
a[0] a
b
b
0
b[0] b
a[0]*b[0]
似乎replace
将expr
的各种元素传递给此函数。诸如此类AttributeError
的错误将被忽略。
1.4发行说明包含有关replace
及其参数exact
的信息。我不知道使用exact=False
是否可以解决1.4中的问题(如果不进行评分,我将无法对其进行测试)。
https://docs.sympy.org/latest/modules/core.html#sympy.core.basic.Basic.replace
答案 2 :(得分:0)
让我们说以下代码:
import sympy as sp
a, b= sp.symbols('a b', cls=sp.IndexedBase)
l= sp.symbols('l', cls=sp.Wild)
def Bfunctest(expr,p1,p2):
if expr.base==p1:return expr.replace(p1[l],0.2*p1[-l],map=False, simultaneous=True, exact=False)
else: return expr.replace(p2[l],0.2*p2[-l],map=False, simultaneous=True, exact=False)
L1 = lambda expr: expr.is_Pow and expr.base in [a, b]
inputstate=a[1]*b[1]
out=inputstate.replace(L1, lambda expr: Bfunctest(expr,a,b))
输出为a[1]*b[1]
而不是0.04*a[-1]*b[-1]
,这意味着不排除 Bfunctest()
。
因为inputstate.is_Pow and inputstate.base in [a, b]
给您假。当您使用inputstate.as_base_exp()[0] in [a, b]
时,会出现 False 的情况。因此,不会排除 Bfunctest()
。