Я пишу свой собственный решатель конечных элементов для динамического моделирования в cython с использованием библиотеки ceygen (представление в виде векторов и матриц Эйгена в оболочке памяти).На каждом временном шаге я должен собрать матрицу жесткости и оценить ее наибольшее собственное значение с помощью теоремы о круге Гершгоринга, добавив абсолютную величину каждой записи строки в матрице.Для сборки я использую формат coo_matrix
.Вот краткая версия моего ассемблерного кода:
for el in range(nElemens):
Klocal()
for i in range(9):
for j in range(9):
data(index) = Klocal(i,j)
index += 1
K = coo_matrix((data, (row, col)), shape=(ndof, ndof)).tocsc()
K.eliminate_zeros()
При запуске профилировщика я получаю следующие результаты:
ncalls tottime percall cumtime percall filename:lineno(function)
458 264.720 0.578 264.720 0.578 {built-in method lexsort}
1 84.764 84.764 486.663 486.663 main.py:9(main)
458 61.473 0.134 343.218 0.749 coo.py:460(_sum_duplicates)
458 12.933 0.028 12.933 0.028 {method 'reduceat' of 'numpy.ufunc' objects}
2775 11.192 0.004 11.193 0.004 {method 'reduce' of 'numpy.ufunc' objects}
16063 8.627 0.001 8.627 0.001 {built-in method array}
28419916 6.933 0.000 6.933 0.000 membrane3D.pyx:366(membrane3DKmat)
Огромное количество времени теряется lexsort
и reduceat
функции, вызываемые изнутри scipy каждый раз, когда я собираю матрицу.Мой вопрос заключается в том, могу ли я повторно использовать ненулевую структуру матрицы (которая остается постоянной и может быть легко вычислена) в scipy, чтобы сэкономить время?Или, в качестве альтернативы, вы бы порекомендовали мне использовать обертку для разреженной матрицы Эйгена?
Любая помощь будет признательна!