How to use permutation symmetry in this loop?

I have a scalar function f(a,b,c,d)that has the following permutation symmetry

f(a,b,c,d) = f(c,d,a,b) = -f(b,a,d,c) = -f(d,c,b,a)

I use it to completely populate a 4D array. This code (using python / NumPy) below works:

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)

But obviously, I would like to use symmetry to shorten the execution time of this section of code. I tried:

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)

Which cuts execution time in half. But for the last symmetry, I tried:

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]

Which works, but does not allow me to approach another coefficient with two accelerations. I do not think this is right for the right reasons, but I cannot understand why.

How can I better use this particular permutation symmetry here?

+4
1

!

N=3 81 4 . 156.

, or (a >= b) or (c >= d), . (a >= b) and (c >= d) .

a + c >= b + d. ( ), a + c ac :

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):
            ac = a + c
            for d in range(N):
                cd += 1
                if (ab >= cd and ac >= b+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]

112 , , , .

Update

, :

from itertools import product

N = 3
ab = 0

all_combinations = set(product(range(N), repeat=4))
zeroes = ((x, x, y, y) for x, y in product(range(N), repeat=2))
calculated = list()

for a in range(N):
    for b in range(N):
        ab += 1
        cd = 0
        for c in range(N):
            ac = a + c
            for d in range(N):
                cd += 1
                if (ab >= cd and ac >= b + d) and not (a == b and c == d):
                    calculated.append((a, b, c, d))
                    calculated.append((c, d, a, b))
                    calculated.append((b, a, d, c))
                    calculated.append((d, c, b, a))

missing = all_combinations - set(calculated) - set(zeroes)

if missing:
    print "Some sets weren't calculated :"
    for s in missing:
        print s
else:
    print "All cases were covered"
    print len(calculated)

and not (a==b and c==d) 88.

+1

Source: https://habr.com/ru/post/1672409/


All Articles