В трассировке должно быть указано, находится ли проблема в spsolve
или при создании одного или обоих аргументов, Mt@M
или Mt.dot(dx)
.
С M
и dx
формами ((6891, 474721000)
, (6891, 3)
Mt@M
(474721000,6891) + (6891, 474721000) => (474721000, 474721000)
Mt.dot(dx) # why not Mt@dx?
(474721000,6891) + (6891, 3) => (474721000, 3)
В зависимости от структуры ненулевых в них, возможно, @ продукт имеет намного больше ненулевых, чем M
, и это может привести к ошибке памяти. Отслеживание одного или другого может помочь нам диагностировать это.
Чаще всего ошибки памяти возникают в результате попытки создания плотного массива из разреженного, но здесь, похоже, это действительно так. Но опять же, трассировка может помочь исключить это.
lil
формат рекомендуется, если значения матрицы заполнены постепенно. csr
используется для матричных продуктов, но sparse
легко преобразует lil
в csr
при необходимости. Так что это не должно быть проблемой.
===
Создать разреженную матрицу с 1 ненулевым элементом:
In [263]: M=sparse.lil_matrix((1000,100000))
In [264]: M
Out[264]:
<1000x100000 sparse matrix of type '<class 'numpy.float64'>'
with 0 stored elements in LInked List format>
In [265]: M[0,0]=1
In [266]: M
Out[266]:
<1000x100000 sparse matrix of type '<class 'numpy.float64'>'
with 1 stored elements in LInked List format>
Этот @
не выдал ошибку памяти, и результат имеет только 1 ненулевой термин, как и ожидалось. Но произошла заметная задержка в запуске этого, предполагая, что он делает некоторые большие вычисления:
In [267]: M.T@M
Out[267]:
<100000x100000 sparse matrix of type '<class 'numpy.float64'>'
with 1 stored elements in Compressed Sparse Row format>
То же самое @
в эквиваленте csr
не имеет этой временной задержки:
In [268]: M1=M.tocsr()
In [269]: M1.T@M1
Out[269]:
<100000x100000 sparse matrix of type '<class 'numpy.float64'>'
with 1 stored elements in Compressed Sparse Column format>
===
Вы упоминаете трехмерные разреженные матрицы в MATLAB. Вы должны использовать какое-то стороннее расширение или обходной путь, так как MATLAB sparse ограничен 2d (по крайней мере, так было, когда я использовал его много лет назад для работы в FEM).
Формат scipy.sparse
csc
аналогичен внутреннему разрежению MATLAB. Фактически это то, что вы получите, если передадите матрицу через save
и scipy.io.loadmat
. csr
аналогично, но с ориентацией строки.
Когда я создавал матрицы жесткости FEM в MATLAB, я использовал эквивалент входных данных scipy
coo
. То есть создаем 3 массива data
, row
и col
. Когда coo
преобразуется в csr
, добавляются дублирующие элементы, аккуратно обрабатывая перекрытие подматриц элементов FEM. (это поведение одинаково в scipy
и MATLAB).
Повторное добавление матриц lil
, как вы делаете, должно работать (если индексация верна), но я ожидаю, что это будет существенно медленнее.