numpy 计算SymPy中基于数组的项的总和[ValueError:给定的限制无效]

brccelvz  于 2022-12-29  发布在  其他
关注(0)|答案(2)|浏览(135)

我一直试图从下面的总和中获得一些数值输出。它需要正常地给出数值输出。然而,我收到了一个与极限有关的错误。
我有一个sum,数学上下限为i = 0,上限为i = k-1。我取(i, 0, k)是因为最后一项被SymPy,Sum排除。此外,我需要在这个嵌套的for循环中得到结果。**for循环和sum之间会不会有不匹配?**即使如此,我也不能更改kNt的for循环。这里,k依赖于Nt
代码:

import numpy as np
from sympy import *
from sympy import Sum

Nx = 31          
Nt = 17
tau = .85 / Nt   
u = np.ones((Nt, Nx)) * np.sin(np.pi)
Sigma = np.zeros((Nt, Nx))   

for k in range(1, Nt): 
  for i in range(1, k):
    for j in range(1, Nx-1):   
      #define sum
      Sigma[i, j] = Sum( ((u[i+1][j] - u[i][j]) / tau * 97.1), (i, 0, k)).doit()    
      print(Sigma[i, j])

错误:

---> 16       Sigma[i, j] = Sum( ((u[i+1][j] - u[i][j]) / tau * 97.1), (i, 0, k) ).doit()

ValueError: Invalid limits given: ((1, 0, 2),)

另外,我对sumSumsummation感到困惑。这些都没有给我数值结果,或者很可能我没有正确使用这些方法。**如何获得数值输出?**下面我再次尝试了np.sum()

for k in range(1, Nt): 
  for i in range(1, k):
    for j in range(1, Nx-1):   
      #define sum
      Sigma[i, j] = np.sum( ((u[i+1][j] - u[i][j]) / tau * 97.1), 0, k-1)    
      print(Sigma[i, j])

输出:

0.0
0.0
0.0...

我想我不能正确地写np.sum()中的和的极限。我该如何更正?我该如何避免0结果?

    • 编辑:**我使用了sum():
for k in range(1, Nt): 
  for i in range(1, k):
    for j in range(1, Nx-1):   
      #define sum
      Sigma[i, j] = sum(u[i+1][j] - u[i][j])
      print(Sigma[i, j])

错误:

TypeError: 'numpy.float64' object is not iterable

谢谢你的帮助!

qaxu7uf2

qaxu7uf21#

这是你要找的吗?

for k in range(1, Nt): 
  for i in range(1, k):
    for j in range(1, Nx-1):   
      #define sum
      Sigma[i, j] = sum(u[_+1][j] - u[_][j] for _ in range(0, k))
      print(Sigma[i, j])

尽管您可以编写Sum(u[_+1[j] - u[_], (_, 0, k)).doit(),但内置的sum才是您真正想要做的:字面值的元素级求和,而不是像Sum(1/x, (x, 0, 5))这样的符号项的求和--SymPy不需要x数组来计算该求和,因为限制指示x的值将是什么。

pgky5nke

pgky5nke2#

重读sympy文档。我认为他们指定sum应该与:

Sum(expr, (var, a, b)

(我可能不应该试着凭记忆工作,但你可以检查)。
在您的:

Sum( ((u[i+1][j] - u[i][j]) / tau * 97.1), (i, 0, k))

((u[i+1][j] - u[i][j]) / tau * 97.1)是一个数,由numpy u导出,它不是一个渐近表达式。
并且i是一个数字,而不是符号。错误告诉我们"给定的限制无效:((1,0,2),)"。
对于刚接触Python的人来说,尝试使用sympy将是困难的。
问题是

np.sum( ((u[i+1][j] - u[i][j]) / tau * 97.1), 0, k-1)

np.sum不像symy Sum那样接受限制。不要假设一个函数的文档适用于另一个包中名称相似的函数。如果你读过它的文档,np.sum接受一个数组,带有axis这样的可选参数。
至于你最后一次尝试:

sum(u[i+1][j] - u[i][j])

pythonsum接受一个"可迭代的",有点像listu[i+1][j] - u[i][j]是一个单一的数字。
u是二维numpy数组。u[i]是一维数组,即"行";,u[i,j]是数组的单个元素。
你到底想总结什么?
我猜你脑子里有某种数学求和,并试图用symy代数来表达,但你的u是一个2d numpy数组,所以u[i+1,j]-u[i,j]是一个单一的数,即两个元素之间的差,u[1:,j]-u[:-1,j]取所有这样的行对之间的差。
我还没有试图弄清楚嵌套循环在做什么,特别是因为i是可能行的子集。

编辑

让我们稍微简化一下你的例子--减小维数,并删除不改变行为的常量:

In [5]: Nx = 4          
   ...: Nt = 3   
   ...: u = np.ones((Nt, Nx))
   ...: Sigma = np.zeros((Nt, Nx))   
   ...: 
   ...: for k in range(1, Nt):
   ...:   print('k',k) 
   ...:   for i in range(1, k):
   ...:     print('i',i)
   ...:     for j in range(1, Nx-1):
   ...:       print('j',j)   
   ...:       Sigma[i,j] = u[i+1,j] - u[i,j]   
   ...:   print(Sigma)
   ...:   
k 1
[[0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]
k 2
i 1
j 1
j 2
[[0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]

k为1时,因为range(1,1)为空,所以没有i迭代,所以Sigma仍然是原来的0。
对于k 2,i的范围为(1,2),即j迭代范围(1,3)一次,即1和2,但是Sigma仍然是0,u是全1,所以配对差为0,@smichr已经指出了这一点(我在前面的阅读中错过了)。

In [3]: u
Out[3]: 
array([[1., 1., 1., 1.],
       [1., 1., 1., 1.],
       [1., 1., 1., 1.]])

In [4]: u[1:]-u[:-1]
Out[4]: 
array([[0., 0., 0., 0.],
       [0., 0., 0., 0.]])

我不确定是否值得进一步研究,你需要一个现实的例子来说明u的差异很重要,但是要让它保持很小(像这样(4,3),这样你就可以指定你想要的值。
如果我定义一个randomu

In [13]: u
Out[13]: 
array([[14,  1,  1, 11],
       [ 2,  4, 17,  4],
       [11,  2,  6, 19]])

In [14]: u[1:]-u[:-1]
Out[14]: 
array([[-12,   3,  16,  -7],
       [  9,  -2, -11,  15]])

对于k 1,sigma仍然是0,但是对于k 2:

k 2
i 1
j 1
j 2
[[  0.   0.   0.   0.]
 [  0.  -2. -11.   0.]
 [  0.   0.   0.   0.]]

该代码从差异数组设置Sigma[1,1]Sigma[1,2]值。
下面是一个包含更多行的案例的运行示例:

In [16]: Nt,Nx = 5,4

In [17]: u = np.random.randint(0,20,(Nt,Nx))

In [18]: u
Out[18]: 
array([[18, 15, 17,  3],
       [ 9,  2,  5, 16],
       [11, 19,  5,  2],
       [13,  0,  4,  5],
       [ 8, 10, 10,  0]])

In [19]: u[1:]-u[:-1]
Out[19]: 
array([[ -9, -13, -12,  13],
       [  2,  17,   0, -14],
       [  2, -19,  -1,   3],
       [ -5,  10,   6,  -5]])

In [20]: Sigma = np.zeros((Nt, Nx))   
    ...: for k in range(1, Nt):
    ...:   print('k',k) 
    ...:   for i in range(1, k):
    ...:     print('i',i)
    ...:     for j in range(1, Nx-1):
    ...:       print('j',j)   
    ...:       Sigma[i,j] = u[i+1,j] - u[i,j]   
    ...:   print(Sigma)
    ...:   
k 1
[[0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]
k 2
i 1
j 1
j 2
[[ 0.  0.  0.  0.]
 [ 0. 17.  0.  0.]
 [ 0.  0.  0.  0.]
 [ 0.  0.  0.  0.]
 [ 0.  0.  0.  0.]]
k 3
i 1
j 1
j 2
i 2
j 1
j 2
[[  0.   0.   0.   0.]
 [  0.  17.   0.   0.]
 [  0. -19.  -1.   0.]
 [  0.   0.   0.   0.]
 [  0.   0.   0.   0.]]
k 4
i 1
j 1
j 2
i 2
j 1
j 2
i 3
j 1
j 2
[[  0.   0.   0.   0.]
 [  0.  17.   0.   0.]
 [  0. -19.  -1.   0.]
 [  0.  10.   6.   0.]
 [  0.   0.   0.   0.]]

让我们尝试一种情况,其中连续的k值被添加到原始值,而不是简单地覆盖。

In [21]: Sigma = np.zeros((Nt, Nx))   
    ...: for k in range(1, Nt):
    ...:   print('k',k) 
    ...:   for i in range(1, k):
    ...:     print('i',i)
    ...:     for j in range(1, Nx-1):
    ...:       print('j',j)   
    ...:       Sigma[i,j] += u[i+1,j] - u[i,j]   # <== change here
    ...:   print(Sigma)
    ...:   
k 1
[[0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]
k 2
i 1
j 1
j 2
[[ 0.  0.  0.  0.]
 [ 0. 17.  0.  0.]
 [ 0.  0.  0.  0.]
 [ 0.  0.  0.  0.]
 [ 0.  0.  0.  0.]]
k 3
i 1
j 1
j 2
i 2
j 1
j 2
[[  0.   0.   0.   0.]
 [  0.  34.   0.   0.]
 [  0. -19.  -1.   0.]
 [  0.   0.   0.   0.]
 [  0.   0.   0.   0.]]
k 4
i 1
j 1
j 2
i 2
j 1
j 2
i 3
j 1
j 2
[[  0.   0.   0.   0.]
 [  0.  51.   0.   0.]           # 3*17
 [  0. -38.  -2.   0.]           # 2* (-19 -1)
 [  0.  10.   6.   0.]
 [  0.   0.   0.   0.]]

不知道你的目的是什么,我不能说这是否更有意义。

相关问题