我有一个标量函数f(a,b,c,d)
,它具有以下置换对称性
f(a,b,c,d) = f(c,d,a,b) = -f(b,a,d,c) = -f(d,c,b,a)
我用它来填充一个4D数组。下面的代码(使用python/NumPy)起作用:
A = np.zeros((N,N,N,N))
for a in range(N):
for b in range(N):
for c in range(N):
for d in range(N):
A[a,b,c,d] = f(a,b,c,d)
但显然我想利用对称性来减少这段代码的执行时间。我试过:
A = np.zeros((N,N,N,N))
ab = 0
for a in range(N):
for b in range(N):
ab += 1
cd = 0
for c in range(N):
for d in range(N):
cd += 1
if ab >= cd:
A[a,b,c,d] = A[c,d,a,b] = f(a,b,c,d)
这将执行时间缩短了一半。但最后一次我试着对称:
A = np.zeros((N,N,N,N))
ab = 0
for a in range(N):
for b in range(N):
ab += 1
cd = 0
for c in range(N):
for d in range(N):
cd += 1
if ab >= cd:
if ((a >= b) or (c >= d)):
A[a,b,c,d] = A[c,d,a,b] = f(a,b,c,d)
A[b,a,d,c] = A[d,c,b,a] = -A[a,b,c,d]
这是可行的,但并没有给我接近另一个因素的两个加速。我不认为这是正确的理由,但不明白为什么。你知道吗
我怎样才能更好地利用这个特殊的排列对称性呢?你知道吗
有趣的问题!你知道吗
对于
N=3
,应该有81个包含4个元素的组合。 使用循环创建156。你知道吗看起来复制的主要来源是
or
中的(a >= b) or (c >= d)
,它太过宽容了。(a >= b) and (c >= d)
限制性太强了。你知道吗不过,你可以比较一下
a + c >= b + d
。要获得几毫秒(如果有的话),可以在第3个循环中将a + c
保存为ac
:在这段代码中,我们创建了112个组合,因此与您的方法相比,重复的数量更少,但可能仍有一些优化。你知道吗
更新
下面是我用来计算创建的组合数的代码:
随着
and not (a==b and c==d)
,这个数字降到了88。你知道吗相关问题 更多 >
编程相关推荐