CVS Transpose And Re-ordering Features

My current study is to add more features/methods for the compressed value storage (CVS) format. CVS is a lossless compression format for sparse matrices. A lot of things are easier with CVS than CRS/CCS. Let's look at Transpose(), SetLinearIndexMode() and TransposeToNewCVS().

In many ways, CVS is coordinate-wise and can be comparable to traversing a DOK sparse matrix. Thus, if you can write the DOK traversal logic, it can be used as basis to traverse through CVS data.

CVS has an existing method to Transpose() in place. Transposing a matrix is described as flipping the matrix on its main diagonal. Wikipedia has a beautiful animation that illustrates this.


Transpose, Wikipedia

Programmatically, it can be achieved by switching the coordinates of the entries in the matrix such that in a tuple (int row, int column) the row becomes the column and the column becomes the row. In CVS, the operation can be achieved with minimal memory requirement during and after the process is done.

CVS has an existing method to SetLinearIndexMode() in place. Basically, what this does is to switch the linear index mode from row-major order to column-major order, or vise versa. In CVS, the operation can be achieved with minimal memory requirement during and after the process is done.

CVSExtensions adds a TransposeToNewCVS() method which creates a transposed version of a CVS instance. A new CVS instance is returned and the original CVS instance is untouched.

        public static CVS<T> TransposeToNewCVS<T>(this CVS<T> cvs)
        {
            (List<T> value, 
             List<List<int>> linearIndex, 
             MatrixLinearIndexMode linearIndexMode, 
             (int rows, int columns) size) = cvs;
            List<T> newValue = new List<T>();
            List<List<int>> newLinearIndex = new List<List<int>>();
            List<int> lis;
            for (int i = 0; i < value.Count; i++)
            {
                newValue.Add(value[i]);
                lis = new List<int>();
                foreach (var li in linearIndex[i])
                {
                    lis.Add(MatrixCoordinates.TransposeLinearIndex(
                        size, li, linearIndexMode).linearIndex);
                }
                lis.Sort();
                newLinearIndex.Add(lis);
            }
            return new CVS<T>(newValue, newLinearIndex, 
                linearIndexMode, (size.columns, size.rows));
        }

This code uses the existing CVS.Transpose() logic to create a new CVS instance with the transposed matrix. Note the use of MatrixCoordinates.TransposeLinearIndex() which performs the actual switching. Simple, right?

Comments