c++mathmatrixlinear-algebratriangular

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


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):

1
2  3
4  5  6
7  8  9  10
11 12 13 14 15
16 17 18 19 20 21
etc...

and I need to get i,j coordinates from these indexes:

1,1
2,1 2,2
3,1 3,2 3,3
4,1 4,2 4,3 4,4
5,1 5,2 5,3 5,4 5,5
6,1 6,2 6,3 6,4 6,5 6,6
etc...

When I need to calculate coordinates I have only one index and cannot access others.


Solution

  • Not optimized at all :

    int j = idx;
    int i = 1;
    
    while(j > i) {
        j -= i++;
    }
    

    Optimized :

    int i = std::ceil(std::sqrt(2 * idx + 0.25) - 0.5);
    int j = idx - (i-1) * i / 2;
    

    And here is the demonstration:

    You're looking for i such that :

    sumRange(1, i-1) < idx && idx <= sumRange(1, i)
    

    when sumRange(min, max) sum integers between min and max, both inxluded. But since you know that :

    sumRange(1, i) = i * (i + 1) / 2
    

    Then you have :

    idx <= i * (i+1) / 2
    => 2 * idx <= i * (i+1)
    => 2 * idx <= i² + i + 1/4 - 1/4
    => 2 * idx + 1/4 <= (i + 1/2)²
    => sqrt(2 * idx + 1/4) - 1/2 <= i