简体   繁体   English

我可以使用什么样的索引方法来存储没有冗余的数组中X ^ 2向量之间的距离?

[英]What sort of indexing method can I use to store the distances between X^2 vectors in an array without redundancy?

I'm working on a demo that requires a lot of vector math, and in profiling, I've found that it spends the most time finding the distances between given vectors. 我正在开发一个需要大量矢量数学的演示,在剖析中,我发现它花费最多的时间来找到给定矢量之间的距离。

Right now, it loops through an array of X^2 vectors, and finds the distance between each one, meaning it runs the distance function X^4 times, even though (I think) there are only (X^2)/2 unique distances. 现在,它循环遍历一个X ^ 2向量数组,并找到每个向量之间的距离,这意味着它运行距离函数X ^ 4次,即使(我认为)只有(X ^ 2)/ 2唯一距离。

It works something like this: (pseudo c) 它的工作原理如下:(伪c)

#define MATRIX_WIDTH 8

typedef float vec2_t[2];
vec2_t matrix[MATRIX_WIDTH * MATRIX_WIDTH];

...

for(int i = 0; i < MATRIX_WIDTH; i++)
{
    for(int j = 0; j < MATRIX_WIDTH; j++)
    {
        float xd, yd;
        float distance;

        for(int k = 0; k < MATRIX_WIDTH; k++)
        {
            for(int l = 0; l < MATRIX_WIDTH; l++)
            {
                int index_a = (i * MATRIX_LENGTH) + j;
                int index_b = (k * MATRIX_LENGTH) + l;

                xd = matrix[index_a][0] - matrix[index_b][0];
                yd = matrix[index_a][1] - matrix[index_b][1];

                distance = sqrtf(powf(xd, 2) + powf(yd, 2));
            }
        }

        // More code that uses the distances between each vector
    }
}

What I'd like to do is create and populate an array of (X^2) / 2 distances without redundancy, then reference that array when I finally need it. 我想做的是创建并填充一个(X ^ 2)/ 2距离数组而没有冗余,然后在我最终需要它时引用该数组。 However, I'm drawing a blank on how to index this array in a way that would work. 但是,我在如何以一种可行的方式索引这个数组上的空白。 A hash table would do it, but I think it's much too complicated and slow for a problem that seems like it could be solved by a clever indexing method. 哈希表可以做到这一点,但我认为这对于一个似乎可以通过一个聪明的索引方法解决的问题来说太复杂和缓慢。

EDIT: This is for a flocking simulation. 编辑:这是一个植绒模拟。

performance ideas: a) if possible work with the squared distance, to avoid root calculation b) never use pow for constant, integer powers - instead use xd*xd 表现思路:a)如果可能的话,用平方距离工作,避免根计算b)永远不要使用pow作为常数,整数幂 - 而是使用xd * xd

I would consider changing your algorithm - O(n^4) is really bad. 我会考虑改变你的算法--O(n ^ 4)真的很糟糕。 When dealing with interactions in physics (also O(n^4) for distances in 2d field) one would implement b-trees etc and neglect particle interactions with a low impact. 当处理物理学中的相互作用(对于2d场中的距离也是O(n ^ 4))时,人们将实现b树等,并忽略具有低影响的粒子相互作用。 But it will depend on what "more code that uses the distance..." really does. 但它取决于“使用距离的更多代码......”确实如此。

just did some considerations: the number of unique distances is 0.5*n*n(+1) with n = w*h. 只是做了一些考虑:唯一距离的数量是0.5 * n * n(+1),其中n = w * h。 If you write down when unique distances occur, you will see that both inner loops can be reduced, by starting at i and j. 如果在发生唯一距离时写下来,您将看到通过从i和j开始可以减少两个内部循环。

Additionally if you only need to access those distances via the matrix index, you can set up a 4D-distance matrix. 此外,如果您只需要通过矩阵索引访问这些距离,则可以设置4D距离矩阵。

If memory is limited we can save up nearly 50%, as mentioned above, with a lookup function that will access a triangluar matrix, as Code-Guru said. 如果内存有限,我们可以节省近50%,如上所述,具有访问三角形矩阵的查找功能,正如Code-Guru所说。 We would probably precalculate the line index to avoid summing up on access 我们可能会预先计算行索引,以避免对访问进行总结

float distanceArray[(H*W+1)*H*W/2];
int lineIndices[H];

searchDistance(int i, int j)
{
    return i<j?distanceArray[i+lineIndices[j]]:distanceArray[j+lineIndices[i]];
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM