在sympy中创建一个块带对角矩阵

时间:2019-07-02 08:17:22

标签: python matrix sympy

我想使用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.lambdifynumpy将计算许多不同参数集的特征值。 我确实找到了一种使用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))

1 个答案:

答案 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]])