Python中的矩阵求幂

时间:2016-02-18 15:55:45

标签: python numpy scipy linear-algebra

我正在尝试用Python取代复杂矩阵并遇到麻烦。我正在使用scipy.linalg.expm函数,并且在尝试以下代码时出现了一条相当奇怪的错误消息:

import numpy as np
from scipy import linalg

hamiltonian = np.mat('[1,0,0,0;0,-1,0,0;0,0,-1,0;0,0,0,1]')

# This works
t_list = np.linspace(0,1,10)
unitary = [linalg.expm(-(1j)*t*hamiltonian) for t in t_list]

# This doesn't
t_list = np.linspace(0,10,100)
unitary = [linalg.expm(-(1j)*t*hamiltonian) for t in t_list]

运行第二个实验时的错误是:

This works!
Traceback (most recent call last):
  File "matrix_exp.py", line 11, in <module>
    unitary_t = [linalg.expm(-1*t*(1j)*hamiltonian) for t in t_list]
  File "/usr/lib/python2.7/dist-packages/scipy/linalg/matfuncs.py",     line 105, in expm
    return scipy.sparse.linalg.expm(A)
  File "/usr/lib/python2.7/dist- packages/scipy/sparse/linalg/matfuncs.py", line 344, in expm
    X = _fragment_2_1(X, A, s)
  File "/usr/lib/python2.7/dist-  packages/scipy/sparse/linalg/matfuncs.py", line 462, in _fragment_2_1
    X[k, k] = exp_diag[k]
TypeError: only length-1 arrays can be converted to Python scalars

这看起来很奇怪,因为我所改变的只是我使用的t范围。是因为汉密尔顿主义是对角线吗?一般来说,汉密尔顿主义者不会,但我也希望它能用于对角线。我真的不知道expm的机制,所以任何帮助都会非常感激。

1 个答案:

答案 0 :(得分:3)

这很有趣。我可以说的一件事是问题是np.matrix子类特有的。例如,以下工作正常:

h = np.array(hamiltonian)
unitary = [linalg.expm(-(1j)*t*h) for t in t_list]

深入挖掘追溯,_fragment_2_1 scipy.sparse.linalg.matfuncs.py中的n = X.shape[0] diag_T = T.diagonal().copy() # Replace diag(X) by exp(2^-s diag(T)). scale = 2 ** -s exp_diag = np.exp(scale * diag_T) for k in range(n): X[k, k] = exp_diag[k] 引发了异常,特别是these lines

    X[k, k] = exp_diag[k]
TypeError: only length-1 arrays can be converted to Python scalars

错误消息

exp_diag[k]

向我建议X[k, k]应该是一个标量,而是返回一个向量(并且你不能将一个向量赋给ipdb> l 751 # Replace diag(X) by exp(2^-s diag(T)). 752 scale = 2 ** -s 753 exp_diag = np.exp(scale * diag_T) 754 for k in range(n): 755 import ipdb; ipdb.set_trace() # breakpoint e86ebbd4 // --> 756 X[k, k] = exp_diag[k] 757 758 for i in range(s-1, -1, -1): 759 X = X.dot(X) 760 761 # Replace diag(X) by exp(2^-i diag(T)). ipdb> exp_diag.shape (1, 4) ipdb> exp_diag[k].shape (1, 4) ipdb> X[k, k].shape () ,这是一个标量。)

设置断点并检查这些变量的形状证实了这一点:

exp_diag

潜在的问题是np.matrix被假定为1D或列向量,但np.matrix对象的对角线是行向量。这突出了一个更普遍的观点,np.ndarray通常不如np.ravel()支持,所以在大多数情况下使用后者更好。

一种可能的解决方案是使用diag_Tnp.ndarray展平为1D diag_T = np.ravel(T.diagonal().copy())

np.matrix

这似乎解决了您遇到的问题,尽管可能还有其他与dnx ef database update相关的问题,但我还没有发现。

我已经打开了拉取请求here