我想使用sympy
创建一个块带对角矩阵。
基本上,矩阵应该看起来像
D N 0 0 0 0
R D N 0 0 0
0 R D N 0 0
0 0 R D N 0
0 0 0 R D N
0 0 0 0 R D
此矩阵随后将通过numpy
馈送到sympy.lambdify
,numpy
将计算许多不同参数集的特征值。
我确实找到了一种使用sympy.kronecker_product
构造矩阵的方法,但是它的速度非常慢。我看了一下为什么我的程序这么慢,发现kronecker.py
是元凶。这真是令人惊讶,因为我认为对角化矩阵将是最慢的部分。甚至更多,因为矩阵只需构造一次,然后就经常对角线化。
因此,我正在寻找一种无需使用sympy.kronecker_product
即可构造矩阵的方法。任何建议表示赞赏。
这里是示例程序:
import sympy
a,b,c,d = sympy.symbols('a b c d', real=True)
e,f,g,h = sympy.symbols('e f g h', real=True)
D = sympy.Matrix([[a,b-sympy.I*c],[b+sympy.I*c,d]])
#usually more complicated, with constants and sin/cos terms
N = sympy.Matrix([[e,sympy.I*f],[g,-sympy.I*h]])
R = sympy.adjoint(N)
size = 20 #usually around 100
H = sympy.kronecker_product(sympy.eye(size),D) \
+ sympy.kronecker_product(sympy.jordan_cell(0,size),N) \
+ sympy.kronecker_product(sympy.transpose(sympy.jordan_cell(0,size)),R)
H_numpy = sympy.lambdify((a,b,c,d,e,f,g,h), H, 'numpy')
import numpy
for i in range(10*size):
eigenvalues = numpy.linalg.eigvalsh(H_numpy(i,2,3,4,5,6,7,8))
答案 0 :(得分:1)
最近添加的banded
可能是您的解决方案:
>>> size=3
>>> var('d n r')
(d, n, r)
带标量
>>> banded(size,{0:d,1:n,-1:r})
Matrix([
[d, n, 0],
[r, d, n],
[0, r, d]])
使用您定义的矩阵:
>>> banded(2*size, {0:D,2:N,-2:R})
Matrix([
[ a, b - I*c, e, I*f, 0, 0],
[b + I*c, d, g, -I*h, 0, 0],
[ e, g, a, b - I*c, e, I*f],
[ -I*f, I*h, b + I*c, d, g, -I*h],
[ 0, 0, e, g, a, b - I*c],
[ 0, 0, -I*f, I*h, b + I*c, d]])