Сложение разреженных матриц в схеме CSR / CRS / Метод разряженных строк / Схема Чанга и Густавсона

Здравствуйте, нужна ваша помощь!

Стоит задача "свернуть" две разреженные матрицы в CRS схему (названий у нее много, в заголовке написал все, что нашел), сложить их в "свернутом" виде, а потом "развернуть" результат.

CSR схема состоит в следующем - матрица записывается в три массива:

массив ненулевых элементов матрицы A, в котором они перечислены по строкам от первой до последней (обозначим его как values);
массив номеров столбцов для соответствующих элементов массива values (обозначим его как cols);
массив указателей позиций, с которых начинается описание очередной строки (обозначим его pointer).

Пример:

Кликните здесь для просмотра всего текста

Матрица:
1 1 0 3 0
2 5 0 0 0
0 0 4 6 4
4 0 2 7 0
0 8 0 0 5

Она же в "свернутом" виде:
values: 1 1 3 2 5 4 6 4 4 2 7 8 5
__cols: 0 1 3 0 1 2 3 4 0 2 3 1 4 //сместил для наглядности
pointer: 0 3 5 8 11

Метод "сворачивания" написал, вот он, может пригодится:

Кликните здесь для просмотра всего текста

C#Выделить код

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

public void Comprass()
        {
            for (int i = 0; i < n; i++)
            {
                pointer.Add(cols.Count);
 
                for (int j = 0; j < m; j++)
                {
                    if (matrix[i, j] != 0)
                    {
                        values.Add(matrix[i, j]);
                        cols.Add(j);
                    }
                }
            }
        }

А вот как сложить "свернутые" матрицы ума не приложу... Подскажите!

Добавлено через 20 часов 17 минут

Никто не сталкивался что ли? Удивительно...

Добавлено через 12 минут

Метод "сворачивания" (старый не совсем верен):

Кликните здесь для просмотра всего текста

C#Выделить код

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

public void Comprass()
        {
            pointer.Clear();
            values.Clear();
            cols.Clear();
            for (int i = 0; i < n; i++)
            {
                pointer.Add(cols.Count);
 
                for (int j = 0; j < m; j++)
                {
                    if (matrix[i, j] != 0)
                    {
                        values.Add(matrix[i, j]);
                        cols.Add(j);
                    }
                }
            }
            pointer.Add(cols.Count);
        }

Метод разворачивания дописал:

Кликните здесь для просмотра всего текста

C#Выделить код

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

public void deComprass()
        {
            //заполняем матрицу нулями
            for (int i = 0; i < n; i++)
                for (int j = 0; j < m; j++)
                    matrix[i,j] = 0;
            //заполняем ненулевыми элементами
            int matrix_i = 0;
            for (int i = 0; i < pointer.Count - 1; i++)
            {
                for (int j = pointer[i]; j < pointer[i+1]; j++)
                    matrix[matrix_i, cols[j]] = values[j];
                matrix_i++;
            }
        }