[英]Scipy.sparse CSC-matrix performance
我目前正在尝试使用隐式欧拉求解某些方程。 由于我对Fortran感到无聊,所以我认为最好是使用Python尝试一下,看看从现有的性能来看,与现有的Fortran程序之间的距离有多近。 对于我的问题,我想利用稀疏矩阵。 我遇到了程序的当前瓶颈是初始化稀疏矩阵并从对角线中减去一些东西。
以下最小示例说明了这一点:
import numpy as np
from scipy.sparse import csc_matrix
from scipy.sparse.linalg import spsolve
from timeit import default_timer
# Example data for Sparse Matrix in CSC format
data = np.array([ -6.07315337e+07, -1.08191534e+06, -5.85677031e+07, \
5.96496184e+07, 1.99723260e+07, -3.99136095e+07, \
-3.10384281e+04, 1.99412852e+07, 3.10384281e+04, \
4.14012789e+04, -4.13845644e+04, -4.14179805e+04, \
4.13845708e+04, 1.67016486e+01, 6.40664368e+03, \
-1.21556953e+02, 6.28508672e+03, -6.40664368e+03, \
1.21556953e+02, 1.87698938e-03, 1.87698938e-03, \
-1.87698938e-03, 6.17782975e-05, 6.17782975e-05, \
-6.17782975e-05, 3.23024684e+00, 3.23024684e+00, \
-3.23024684e+00, 1.59838512e+00, 1.59838512e+00, \
-1.59838512e+00, 1.96353333e-02, 1.96353333e-02, \
-1.96353333e-02, 4.25269958e+01, 4.25269958e+01, \
-4.25269958e+01, 4.84489810e-06, 4.84489810e-06, \
-4.84489810e-06, 2.54951658e-07, 2.54951658e-07, \
-2.54951658e-07, 6.42250438e-08, 6.42250438e-08, \
-6.42250438e-08])
indices = np.array([ 0, 1, 2, 3, 0, 1, 2, 3, 4, 0,\
1, 2, 4, 5, 0, 1, 2, 3, 5, 0,\
3, 4, 0, 4, 5, 0, 5, 6, 0, 6,\
7, 0, 7, 8, 0, 8, 9, 0, 9, 10,\
0, 10, 11, 0, 11, 12], dtype=np.int32)
indptr = np.array([ 0, 4, 9, 14, 19, 22, 25, 28, 31, 34,\
37, 40, 43, 46], dtype=np.int32)
# Stop the time to initialize the Sparse matrix in CSC-format
start = default_timer()
for i in range(10000):
J = csc_matrix((data, indices, indptr), shape=(13, 13))
stop = default_timer()
print 'Initialize:'.ljust(15),stop - start
# Set the diagonal of the matrix. The diagonal is in principle known.
start = default_timer()
for i in range(10000):
J.setdiag(1./1e-10 + J.diagonal())
stop = default_timer()
print 'Set diagonal:'.ljust(15), stop - start
# Set an array to solve something
b = np.array([ -4.16737068e+05, 8.32180182e+05, 1.29378997e+03,\
-4.15443441e+05,-1.29326784e+03,-2.60963259e-01,\
0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\
0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\
0.00000000e+00])
# Stop the time to solve the system
start = default_timer()
for i in range(10000):
x = spsolve(J,b)
stop = default_timer()
print 'Solve:'.ljust(15), stop - start
我知道更改矩阵的稀疏度通常很昂贵。 原则上,我知道对角线的索引,但是一旦将数据存储在scipy csc_matrix中,我就不知道如何更改数据。 但是,矩阵的初始化几乎和解决系统一样昂贵吗? 对我而言,示例程序的输出为:
初始化:0.516402959824
设置对角线:1.67107796669
解决:0.845117807388
有没有办法绕过稀疏的稀疏矩阵或加快速度呢? 我曾考虑过直接打电话给Pardiso,但对我来说,这似乎很复杂。
仅初始化一次scipy.sparse.csc_matrix实例一次,可以大大减少计算时间。 而不是写作
J = csc_matrix((data, indices, indptr), shape=(13, 13))
在每次迭代中,最好编写以下内容:
J.data = data
J.indices = indices
J.indptr = indptr
如果稀疏性没有变化并且对角线的索引已知,则可以直接使用对角线的数据,而不必使用scipy的setdiag和对角线属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.