How to convert triangular matrix indexes in to row, column coordinates?

前端 未结 2 1727
抹茶落季
抹茶落季 2021-01-06 17:34

I have these indexes:

1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,etc...

Which are indexes of nodes in a matrix (including diagonal elements):

2条回答
  •  天涯浪人
    2021-01-06 17:51

    In my case (a CUDA kernel implemented in standard C), I use zero-based indexing (and I want to exclude the diagonal) so I needed to make a few adjustments:

    // idx is still one-based
    unsigned long int idx = blockIdx.x * blockDim.x + threadIdx.x + 1; // CUDA kernel launch parameters
    // but the coordinates are now zero-based
    unsigned long int x = ceil(sqrt((2.0 * idx) + 0.25) - 0.5);
    unsigned long int y = idx - (x - 1) * x / 2 - 1;
    

    Which results in:

    [0]: (1, 0)
    [1]: (2, 0)
    [2]: (2, 1)
    [3]: (3, 0)
    [4]: (3, 1)
    [5]: (3, 2)
    

    I also re-derived the formula of Flórez-Rueda y Moreno 2001 and arrived at:

    unsigned long int x = floor(sqrt(2.0 * pos + 0.25) + 0.5);
    

    CUDA Note: I tried everything I could think of to avoid using double-precision math, but the single-precision sqrt function in CUDA is simply not precise enough to convert positions greater than 121 million or so to x, y coordinates (when using 1,024 threads per block and indexing only along 1 block dimension). Some articles have employed a "correction" to bump the result in a particular direction, but this inevitably falls apart at a certain point.

提交回复
热议问题