我试图使用数组方法求和二维函数,以某种方式,使用for循环无法输出正确的答案。我想找到(在乳胶中)$$ \ sum_ {i = 1} ^ {M} \ sum_ {j = 1} ^ {M_2} \ cos(i)\ cos(j)$$,其中根据Mathematica,答案是当M = 5为1.52725时。根据for循环:
def f(N):
s1=0;
for p1 in range(N):
for p2 in range(N):
s1+=np.cos(p1+1)*np.cos(p2+1)
return s1
print(f(4))
为0.291927。
因此,我一直试图使用以下形式的代码:
def f1(N):
mat3=np.zeros((N,N),np.complex)
for i in range(0,len(mat3)):
for j in range(0,len(mat3)):
mat3[i][j]=np.cos(i+1)*np.cos(j+1)
return sum(mat3)
再次
print(f1(4))
输出0.291927。查看数组,我们应该为i和j的每个值找到
形式的矩阵mat3=[[np.cos(1)*np.cos(1),np.cos(2)*np.cos(1),...],[np.cos(2)*np.cos(1),...]...[np.cos(N+1)*np.cos(N+1)]]
所以对于N = 4,我们应该有
mat3=[[np.cos(1)*np.cos(1) np.cos(2)*np.cos(1) ...] [np.cos(2)*np.cos(1) ...]...[... np.cos(5)*np.cos(5)]]
但是我实际上得到的是以下
mat3=[[0.29192658+0.j 0.+0.j 0.+0.j ... 0.+0.j] ... [... 0.+0.j]]
或除mat3 [0] [0]元素之外为全零的矩阵。
有人知道这样做的正确方法并获得正确答案吗?我选择此示例作为示例,因为我要解决的问题涉及绘制一个已在两个索引上求和的函数,而python输出的函数与Mathematica不同(即,形式为$$ f( E)= \ sum_ {i = 1} ^ {M} \ sum_ {j = 1} ^ {M_2} F(i,j,E)$$)。
答案 0 :(得分:1)
示例代码中的return语句未正确缩进。它在第一个循环迭代中立即返回。缩进它在函数体上,以便两个for循环都完成:
def f(N):
s1=0;
for p1 in range(N):
for p2 in range(N):
s1+=np.cos(p1+1)*np.cos(p2+1)
return s1
>>> print(f(5))
1.527247272700347
答案 1 :(得分:1)
我已经将您的代码移到了更加麻木的版本:
import numpy as np
N = 5
x = np.arange(N) + 1
y = np.arange(N) + 1
x = x.reshape((-1, 1))
y = y.reshape((1, -1))
mat = np.cos(x) * np.cos(y)
print(mat.sum()) # 1.5272472727003474
这里的技巧是将x重塑为列,将y重塑为行向量。如果将它们相乘,它们就像在循环中一样被匹配。
这应该更有效,因为cos()
仅被调用2 * N次。而且它避免了循环(在python中很糟糕)。
更新(关于您的评论):
此模式可以在任何维度上扩展。基本上,您会得到类似交叉产品的东西。沿相应维度,x的每个实例与y,z,u,k,...的每个实例匹配。
描述起来有点混乱,所以这里有更多代码:
import numpy as np
N = 5
x = np.arange(N) + 1
y = np.arange(N) + 1
z = np.arange(N) + 1
x = x.reshape((-1, 1, 1))
y = y.reshape((1, -1, 1))
z = z.reshape((1, 1, -1))
mat = z**2 * np.cos(x) * np.cos(y)
# x along first axis
# y along second, z along third
# mat[0, 0, 0] == 1**2 * np.cos(1) * np.cos(1)
# mat[0, 4, 2] == 3**2 * np.cos(1) * np.cos(5)
如果将其用于多个维度,并且将N设置为较大的值,则会遇到内存问题。