查找数组对,例如 array_1 = -array_2

Find pairs of array such as array_1 = -array_2

我寻找一种方法从 np.meshgrid(xrange, xrange, xrange) 中找到与 k = -k 相关的所有向量。

目前我这样做:


@numba.njit
def find_pairs(array):
    boolean = np.ones(len(array), dtype=np.bool_)
    pairs = []
    idx = [i for i in range(len(array))]
    while len(idx) > 1:
        e1 = idx[0]
        for e2 in idx:
            if (array[e1] == -array[e2]).all():
                boolean[e2] = False
                pairs.append([e1, e2])
                idx.remove(e1)
                if e2 != e1:
                    idx.remove(e2)
                break 
    return boolean, pairs

# Give array of 3D vectors
krange = np.fft.fftfreq(N)
comb_array = np.array(np.meshgrid(krange, krange, krange)).T.reshape(-1, 3)

# Take idx of the pairs k, -k vector and boolean selection that give position of -k vectors
boolean, pairs = find_pairs(array)

它有效,但执行时间随着 N 的增加而迅速增加...

也许有人已经处理过了?

主要问题是 comb_array 的形状为 (R, 3),其中 R = N**3find_pairs 中的嵌套循环 运行 至少在二次方自 idx.remove 运行s 以来的线性时间,并在 for 循环中调用。此外,在某些情况下,for 循环不会更改 idx 的大小,并且循环似乎永远 运行(例如 N=4)。

O(R log R)中解决这个问题的一个方法是对数组进行排序,然后在线性时间内检查相反的值:

import numpy as np
import numba as nb

# Give array of 3D vectors
krange = np.fft.fftfreq(N)
comb_array = np.array(np.meshgrid(krange, krange, krange)).T.reshape(-1, 3)

# Sorting
packed = comb_array.view([('x', 'f8'), ('y', 'f8'), ('z', 'f8')])
idx = np.argsort(packed, axis=0).ravel()
sorted_comb = comb_array[idx]

# Find pairs
@nb.njit
def findPairs(sorted_comb, idx):
    n = idx.size
    boolean = np.zeros(n, dtype=np.bool_)
    pairs = []
    cur = n-1
    for i in range(n):
        while cur >= i:
            if np.all(sorted_comb[i] == -sorted_comb[cur]):
                boolean[idx[i]] = True
                pairs.append([idx[i], idx[cur]])
                cur -= 1
                break
            cur -= 1
    return boolean, pairs

findPairs(sorted_comb, idx)

请注意,该算法假设每一行最多只有一对有效匹配。如果有几个相等的行,则将它们 2 对 2 配对。如果您的目标是在这种情况下提取所有相等行的组合,那么请注意输出将呈指数增长(恕我直言,这是不合理的)。

即使对于 N = 100,此解决方案也非常快。大部分时间都花在效率不高的排序上(不幸的是,Numpy 没有提供一种方法来有效地对行进行字典顺序 argsort,尽管这种操作从根本上来说是昂贵的)。