Как удалить разрывы из комплексного угла компонентов собственного вектора NumPy?

Я использую linalg.eig NumPy для квадратных матриц. Мои квадратные матрицы являются функцией 2D-области, и я смотрю на комплексные углы ее собственных векторов вдоль параметризованной окружности в этой области. Пока рассматриваемый мной путь является гладким, я ожидаю, что комплексные углы компонентов каждого собственного вектора будут гладкими. Однако в некоторых случаях это не относится к Python (хотя это относится к другим языкам программирования). Для параметра M=0 (некоторый аргумент в моей матрице, который появляется на его диагонали) у меня есть компоненты, которые выглядят так:

введите описание изображения здесь  введите описание изображения здесь

когда они должны в идеале выглядеть так (M=0.1):

введите здесь описание изображения  введите описание изображения здесь

Что я пробовал:

  • Я проверил, что в обоих случаях матрицы эрмитовы.
  • Когда я использую linalg.eigh, M=0.1 становится прерывистым, а M=0 иногда становится непрерывным.
  • Использование np.unwrap ничего не дало.
  • Разница между фазами компонентов (т.е. np.angle(v1-v2) для собственного вектора v=[[v1],[v2]]) плавная / непрерывная, но это не то, что я хочу.
  • Исправление семени NumPy перед решением ничего не дало для разных значений семени. Например: np.random.seed(1).

Что еще я могу сделать? Я пытаюсь использовать Sympy eigenvects только потому, что у меня заканчиваются варианты, и я задал еще один вопрос, касающийся другого потенциального подхода здесь: Как заставить первый компонент собственных векторов NumPy быть действительным?. Но я не знаю, что еще я могу попробовать.

Вот минимальный рабочий пример, который отлично работает в записной книжке Jupyter:

import numpy as np
from numpy import linalg as LA
import matplotlib.pyplot as plt

M = 0.01; # nonzero M is okay
M = 0.0; # M=0 causes problems

def matrix_generator(kx,ky,M):
    a = 2.46;    t = 1;    k = np.array((kx,ky));
    d1 = (a/2)*np.array((1,np.sqrt(3)));d2 = (a/2)*np.array((1,-np.sqrt(3)));d3 = -a*np.array((1,0));
    sx = np.matrix([[0,1],[1,0]]);sy = np.matrix([[0,-1j],[1j,0]]);sz = np.matrix([[1,0],[0,-1]]);
    hx = np.cos(k@d1)+np.cos(k@d2)+np.cos(k@d3);hy = np.sin(k@d1)+np.sin(k@d2)+np.sin(k@d3);
    return -t*(hx*sx - hy*sy + M*sz)

n_segs = 200; #number of segments in (kx,ky) loop
evecs_along_loop = np.zeros((n_segs,2,2),dtype=float)
# parameterize circular loop
kx0 = 0.5; ky0 = 1; r1=0.2; r2=0.2; 
a = np.linspace(0.0, 2*np.pi, num=n_segs+2)
kloop=np.zeros((n_segs+2,2))
for i in range(n_segs+2):
    kloop[i,:]=np.array([kx0 + r1*np.cos(a[i]), ky0 + r2*np.sin(a[i])]) 
    
# assign eigenvector complex angles
for j in np.arange(n_segs):
    np.random.seed(2)
    H = matrix_generator(kloop[j][0],kloop[j][1],M)
    eval0, psi0 = LA.eig(H)
    evecs_along_loop[j,:,:] = np.angle(psi0)
    
# plot eigenvector complex angles
for p in np.arange(2):
    for q in np.arange(2):
        print(f"Phase for eigenvector element {p},{q}:")
        fig = plt.figure()
        ax = plt.axes()
        ax.plot((evecs_along_loop[:,p,q]))
        plt.show()

Пояснение к комментарию anon01:  введите здесь описание изображения Для M=0 примерная матрица с некоторым значением (kx,ky) будет выглядеть так:

a = np.matrix([[0.+0.j, 0.99286437+1.03026667j],
 [0.99286437-1.03026667j, 0.+0.j]])

Для M =/= 0 диагональ будет отличной от нуля (но реальной).


person TribalChief    schedule 21.05.2021    source источник
comment
можешь уточнить, как выглядят твои матрицы? Я не знаю, как интерпретировать это утверждение: square matrices are a function of a 2D domain   -  person anon01    schedule 21.05.2021
comment
Вы хотите сказать, что индексы элементов, например m[j,k] <> f(x=j, y=k)?   -  person anon01    schedule 21.05.2021
comment
@ anon01 извините за недоразумение. Я имел в виду, что у меня есть функция H(kx,ky,M), которая возвращает матрицу для аргументов (kx,ky,M). kx,ky не являются индексами. Вместо этого они являются «координатами» в некотором домене (например, [-1,1]x[2,3], что означает, что kx может принимать любое значение от -1 до 1, а ky между 2 и 3. Итак, я выбираю набор матриц для (kx,ky), которые создают плавный цикл на его 2D Это проблема физики.   -  person TribalChief    schedule 21.05.2021
comment
@ anon01 Я просто добавил картинку и образец матрицы в конце своего вопроса. Спасибо!   -  person TribalChief    schedule 21.05.2021


Ответы (1)


Я считаю, что в целом это сложная проблема. Основная проблема заключается в том, что собственные векторы (в отличие от собственных значений) не определены однозначно. Собственный вектор v матрицы M с собственным значением c - это любой ненулевой вектор, для которого

M*v = c*v

В частности, для любого ненулевого скаляра s умножение собственного вектора на s дает собственный вектор, и даже если вы потребуете (как обычно), чтобы собственные векторы имели длину 1, мы все равно можем умножить на любой скаляр с абсолютным значением 1. Еще хуже, если v1, .. vd - ортогональные собственные векторы для c, то любая ненулевая линейная комбинация v также является собственным вектором для c.

Таким образом, разные процедуры разложения на собственные числа могут давать очень разные собственные векторы и при этом выполнять свою работу. Более того, некоторые процедуры могут создавать собственные векторы, которые находятся далеко друг от друга, для близких друг к другу матриц.

Простой управляемый случай - это когда вы знаете, что все ваши собственные значения невырождены (т.е. каждое собственное подпространство имеет размерность 1), и вы знаете, что для определенного i i-й компонент каждого собственного вектора будет отличным от нуля. Затем вы можете умножить собственный вектор v на скаляр с абсолютным значением 1, выбранный так, чтобы после умножения v [i] было положительным вещественным числом. В C

s = conj(v[i])/cabs(v[i])
where 
conj(z) is the complex conjugate of the complex number z, 
and cabs(z) is the absolute value of the complex number z

Обратите внимание, что вышеизложенное предполагает, что мы используем один и тот же индекс для каждого собственного вектора, хотя коэффициент s изменяется от собственного вектора к собственному вектору.

Это наложило бы уникальность на собственные векторы и, можно было бы надеяться, означало бы, что они постоянно менялись с параметрами вашей матрицы.

person dmuir    schedule 22.05.2021
comment
Спасибо за ответ. Не могли бы вы уточнить, откуда взялись эти требования (и решение s = conj(v[i])/cabs(v[i]))? Я хотел бы больше узнать об этом, а также рассмотреть альтернативные случаи, когда собственное подпространство вырождено. - person TribalChief; 22.05.2021
comment
Кроме того, cabs() опечатка? В противном случае не могли бы вы уточнить, из какого пакета он поступил? Простой поиск в Google ничего не дал. Спасибо! Однако я попробовал ваше предложение, но оно, похоже, ничего не меняет. Может, есть еще какой-то фактор ...? - person TribalChief; 22.05.2021
comment
это неправда: Even worse, if v1,..vd are orthogonal eigenvectors for c, then any linear combination of the v's is also an eigenvector for c - person anon01; 22.05.2021
comment
@ anon21 Я немного растерялся, не исключив случай 0, но в остальном утверждение верно. Обратите внимание, что под «for c» я имел в виду, что каждый vi был собственным вектором с тем же собственным значением c. - person dmuir; 22.05.2021
comment
@dmuir за разъяснения. Есть ли у вас какие-либо ссылки, которые могли бы помочь мне разобраться в случае, когда собственные значения вырождены только в точке, где-то не в / в цикле? Кажется, что случай M=0 - это всего лишь случай, но, тем не менее, вызывает проблемы. - person TribalChief; 24.05.2021