Sparse matrix storage in C

前端 未结 3 1976
逝去的感伤
逝去的感伤 2021-01-15 11:42

I have a sparse matrix that is not symmetric I.E. the sparsity is somewhat random, and I can\'t count on all the values being a set distance away from the diagonal.

3条回答
  •  南笙
    南笙 (楼主)
    2021-01-15 12:33

    I would implement this as a ragged array, with A[n][0] always returning the element on the diagonal. A[n][1] will return the item just to the right of the diagonal, A[n][2] will return the item to the left of the diagonal, and so. Then, you just need a function that maps matrix index [i,j] to ragged array index[r][s].

    This has the advantage of sparsity, and if your values stay close to the diagonal the arrays are not very long.


    Alternatively, you could have this definition:

    struct Row
    {
        int InitialOffset;
        int NumElements;
        int[] Values;
    }
    

    Then you would have a Row[]. Retrieving a value based on matrix index would look like this:

    //matrix is merely an array of rows...
    int GetValue(*matrix this, int i, int j)
    {
        Row CurrentRow = (*this)[i];
        if (CurrentRow.InitialOffset > j)
            return 0;
        else if (CurrentRow.InitialOffset + CurrentRow.NumElements < j)
            return 0; 
        return CurrentRow.Values[j - CurrentRow.InitialOffset]
    }
    

    My C syntax is a little hazy, but you should get the idea.


    Based on your demonstration, I would recommend this:

    struct Matrix
    {
        int[,] Data
        int[] StartOffset;
        int[] NumberElements;
    }
    

    Used as follows...

    int GetValue(*Matrix this, int i, int j)
    {
        if (this.StartOffset[i] > j)
            return 0;
        else if (this.StartOffset[i] + this.NumberElements[i] < j)
            return 0; 
        return this.Data[i, j-this.StartOffset[i]];
    }
    

    Your initialization procedure would look something like this

    //Data is a struct that holds row index, col index, and value
    Matrix* InitMatrix (*Data values, int numVals)
    {
        //loop through values to find longest row and number of rows
        //create new matrix, malloc matrix for longrow * numRows
        //malloc numrows elements for StartOffset and NumItems
        //foreach row, find min() and max()-min() of col indexs and 
        //store in StartOffset and NumItems
    }
    

    You need to do some processing, but data compression isn't cheap.

提交回复
热议问题