scipy.linalg.expm эрмитова не является специальным унитарным - PullRequest
0 голосов
/ 24 февраля 2020

Если у меня есть (настоящая) эрмитова матрица, например,

H = matrix([[-2. ,  0.5,  0.5,  0. ],
        [ 0.5,  2. ,  0. ,  0.5],
        [ 0.5,  0. ,  0. ,  0.5],
        [ 0. ,  0.5,  0.5,  0. ]])

(эта матрица эрмитова; это гамильтониан 2-спиновой цепи Изинга со связью с внешним полем.)

Тогда существует специальное ортогональное преобразование O (сохраняет длину векторов столбцов и строк матрицы) st

H = O.transpose() @ D @ O

, где D - диагональ. Для экспоненциальной матрицы это приводит к

T = expm(1j * H) = O.transpose() @ expm(1j * D) @ O

, поэтому все векторы столбцов / строк T должны иметь длину 1.

Если я использую scipy.linalg.expm это свойство нарушено:

In [1]: import numpy as np                                                      

In [2]: from numpy import matrix                                                

In [3]: from scipy.linalg import expm                                           

In [4]: H = matrix([[-2. ,  0.5,  0.5,  0. ], 
   ...:         [ 0.5,  2. ,  0. ,  0.5], 
   ...:         [ 0.5,  0. ,  0. ,  0.5], 
   ...:         [ 0. ,  0.5,  0.5,  0. ]])                                      

In [5]: T = expm(1j * H)                                                        

In [6]: np.sum(np.abs(T[0]))                                                    
Out[6]: 1.6099093263121051

In [7]: np.sum(np.abs(T[1]))                                                    
Out[7]: 1.609909326312105

In [8]: np.sum(np.abs(T[2]))                                                    
Out[8]: 1.7770244703003222

In [9]: np.sum(np.abs(T[3]))                                                    
Out[9]: 1.7770244703003222

Это ошибка в expm или я здесь ошибаюсь?

1 Ответ

2 голосов
/ 24 февраля 2020

вы используете неправильную норму. Используйте

np.sqrt( np.sum( np.abs(T[0])**2 ) )

Или даже более коротким способом

np.linalg.norm( T[0] )
...