Да.
Сохранять элементы по строкам, где i
-я строка и j
-й столбец хранятся в индексе k=i*NC+j
с NC
количеством столбцов. Это относится к несимметричной общей матрице.
Чтобы сохранить симметричную матрицу размера N
, вам нужно всего лишь N*(N+1)/2
элементов в массиве. Можно предположить, что i<=j
таков, что индексы массива идут так:
k(i,j) = i*N-i*(i+1)/2+j i<=j //above the diagonal
k(i,j) = j*N-j*(j+1)/2+i i>j //below the diagonal
с
i = 0 .. N-1
j = 0 .. N-1
Пример, когда N = 5, индексы массива идут следующим образом
| 0 1 2 3 4 |
| |
| 1 5 6 7 8 |
| |
| 2 6 9 10 11 |
| |
| 3 7 10 12 13 |
| |
| 4 8 11 13 14 |
Общее количество необходимых элементов: 5*(5+1)/2 = 15
, поэтому индексы начинаются с 0..14
.
i
-я диагональ имеет индекс k(i,i) = i*(N+1)-i*(i+1)/2
. Таким образом, третий ряд (i=2
) имеет диагональный индекс k(2,2) = 2*(5+1)-2*(2+1)/2 = 9
.
Последний элемент i
-ой строки имеет индекс = k(i,N) = N*(i+1)-i*(i+1)/2-1
. Таким образом, последний элемент 3-й строки - k(2,4) = 5*(2+1)-2*(2+1)/2-1 = 11
.
Последняя часть, которая может вам понадобиться, - как перейти от индекса массива k
к строке i
и столбцу j
. Снова при условии, что i<=j
(выше диагонали) ответ будет
i(k) = (int)Math.Floor(N+0.5-Math.Sqrt(N*(N+1)-2*k+0.25))
j(k) = k + i*(i+1)/2-N*i
Чтобы проверить вышесказанное, я запустил это для N=5
, k=0..14
и получил следующие результаты:
Что правильно!
Чтобы сделать копию, просто используйте Array.Copy()
на элементах, которые очень быстрые. Также для выполнения таких операций, как сложение и масштабирование, вам просто нужно работать с уменьшенными элементами в массиве, а не с полной матрицей N*N
. Матричное умножение немного сложнее, но выполнимо. Может быть, вы можете задать другой вопрос для этого, если хотите.