首页 > 解决方案 > 带有 sympy 的基本循环给了我这个错误信息:'Symbol' object is not subscriptable

问题描述

H = Matrix([[J[0,:],J[1,:],J[2,:]]])

我想在 sympy 中创建一个循环,所以我不需要手动输入 0、1、2 等。 J 是一个符号矩阵

这是我的代码:

from sympy import *
def make_Aij(m, n, a='a') :
    from sympy import Symbol, Matrix # just in case they aren't already loaded
    A = zeros(m, n)
    for i in range(0, m) :
        for j in range(0, n) :
            s = a+'_'+str(i)+str(j)
            exec  (s + "= Symbol('" + s + "')") # go look up what "exec" does!
            exec ("A[i, j] = " + s)
    return A
C = make_Aij(5, 5, 'c')
tri_upper_no_diag = np.triu(C, k=1)
J = Matrix(tri_upper_no_diag)
J

Z = zeros(5,5)

i = 0
while i < 1:
    J[:,i] = Z[:,i]
    J[i,:] = Z[i,:]
    i = i + 1
J

i = 1
T = ('J[0,:]')
while i < 5:
    s = (",J[i,:]")
    T = T + s
    i = i + 1
    
    d = Matrix([[T]])
d

错误信息:

TypeError                                 Traceback (most recent call last)
<ipython-input-60-0220d335bd1c> in <module>
      6     i = i + 1
      7 
----> 8     d = Matrix([[T]])
      9 d
     10 

~\anaconda3\lib\site-packages\sympy\matrices\dense.py in __new__(cls, *args, **kwargs)
    294 
    295     def __new__(cls, *args, **kwargs):
--> 296         return cls._new(*args, **kwargs)
    297 
    298     @classmethod

~\anaconda3\lib\site-packages\sympy\matrices\dense.py in _new(cls, *args, **kwargs)
    306             rows, cols, flat_list = args
    307         else:
--> 308             rows, cols, flat_list = cls._handle_creation_inputs(*args, **kwargs)
    309             flat_list = list(flat_list) # create a shallow copy
    310         self = object.__new__(cls)

~\anaconda3\lib\site-packages\sympy\matrices\matrices.py in _handle_creation_inputs(cls, *args, **kwargs)
   1087                             else:
   1088                                 c = len(row)
-> 1089                                 flat = [cls._sympify(i) for i in row]
   1090                         ncol.add(c)
   1091                         if len(ncol) > 1:

~\anaconda3\lib\site-packages\sympy\matrices\matrices.py in <listcomp>(.0)
   1087                             else:
   1088                                 c = len(row)
-> 1089                                 flat = [cls._sympify(i) for i in row]
   1090                         ncol.add(c)
   1091                         if len(ncol) > 1:

~\anaconda3\lib\site-packages\sympy\core\sympify.py in sympify(a, locals, convert_xor, strict, rational, evaluate)
    404     try:
    405         a = a.replace('\n', '')
--> 406         expr = parse_expr(a, local_dict=locals, transformations=transformations, evaluate=evaluate)
    407     except (TokenError, SyntaxError) as exc:
    408         raise SympifyError('could not parse %r' % a, exc)

~\anaconda3\lib\site-packages\sympy\parsing\sympy_parser.py in parse_expr(s, local_dict, transformations, global_dict, evaluate)
   1006         code = compile(evaluateFalse(code), '<string>', 'eval')
   1007 
-> 1008     return eval_expr(code, local_dict, global_dict)
   1009 
   1010 

~\anaconda3\lib\site-packages\sympy\parsing\sympy_parser.py in eval_expr(code, local_dict, global_dict)
    900     Generally, ``parse_expr`` should be used.
    901     """
--> 902     expr = eval(
    903         code, global_dict, local_dict)  # take local objects in preference
    904 

<string> in <module>

TypeError: 'Symbol' object is not subscriptable

我认为错误来自逗号和 sympy 语言之间的混合,但我找不到解决它的方法。

任何帮助将不胜感激提前谢谢您!

标签: loopsmatrixsympy

解决方案


isympy会话中,第一个J是:

In [12]: J
Out[12]: 
⎡0  c₀₁  c₀₂  c₀₃  c₀₄⎤
⎢                     ⎥
⎢0   0   c₁₂  c₁₃  c₁₄⎥
⎢                     ⎥
⎢0   0    0   c₂₃  c₂₄⎥
⎢                     ⎥
⎢0   0    0    0   c₃₄⎥
⎢                     ⎥
⎣0   0    0    0    0 ⎦

第二个只是第一行的0。

然后:

In [15]: i = 1
    ...: T = ('J[0,:]')
    ...: while i < 5:
    ...:     s = (",J[i,:]")
    ...:     T = T + s
    ...:     i = i + 1
    ...: 
In [16]: T
Out[16]: 'J[0,:],J[i,:],J[i,:],J[i,:],J[i,:]'

但是sympify(T)给出了TypeError: 'Symbol' object is not subscriptable

但是一个简单的列表推导会产生:

In [26]: Matrix([[J[i,:] for i in range(0,5)]])
Out[26]: [0  0  0  0  0  0  0  c₁₂  c₁₃  c₁₄  0  0  0  c₂₃  c₂₄  0  0  0  0  c₃₄  0  0  0  0  0]

虽然sympy可以sympify字符串,但我认为在其他工具可用时使用它不是一个好主意,例如 Python 列表。

In [27]: [J[i,:] for i in range(0,5)]
Out[27]: 
[[0  0  0  0  0], [0  0  c₁₂  c₁₃  c₁₄], [0  0  0  c₂₃  c₂₄], [0  0  0  0  c₃₄], [0  0  0  0 
 0]]

sympy矩阵之类的操作reshape

In [29]: J.reshape(1,25)
Out[29]: [0  0  0  0  0  0  0  c₁₂  c₁₃  c₁₄  0  0  0  c₂₃  c₂₄  0  0  0  0  c₃₄  0  0  0  0  0]

好像

sympify('J[0,:]')

是问题所在。我怀疑它“看到”J并使其成为symbol,而没有“知识”你已经创建了一个J矩阵对象。

eval确实有效:

In [38]: eval('J[0,:],J[1,:]')
Out[38]: ([0  0  0  0  0], [0  0  c₁₂  c₁₃  c₁₄])

还要注意在Out[16]重复[i,:]。该字符串构造不执行整数替换。当遇到调试问题时,检查中间步骤。重要的是细节。


推荐阅读