Как сделать так, чтобы собственные значения и собственные векторы оставались действительными, а не комплексными?

Я пытаюсь диагонализовать n*100*100 3D-матрицу K на numpy.linalg.eig и получить собственные значения w и собственные векторы v. Матрица 100*100, но я хочу сделать это с трансляцией, и это номер n, который я установил. И матрица не эрмитова.

w,v=np.linalg.eig(K)

Сначала я попробовал n=1000, я получил реальные собственные значения и собственные векторы, то есть xxxxxxxxxe+xx, но когда я попробовал n=2000, элементы w и v показывают xxxxxxxxxe+xx+0.j. Из-за +0.j он давал комплексные числа при использовании w и v для дальнейших вычислений.

  1. Я думал, что это из-за ошибки алгоритма расчета числа с плавающей запятой, но почему?
  2. Использует ли numpy.linalg LAPACK? Возможна ли ошибка от LAPACK?
  3. Как мне избавиться от +0.j?

person kinder chen    schedule 08.02.2018    source источник
comment
Матрица симметрична / эрмитова? Как узнать, что у него есть настоящие собственные значения?   -  person    schedule 09.02.2018
comment
хороший вопрос, тоже пытаюсь разобраться. Это не эрмитово, но без широковещательной передачи, только диагонализация одной 100*100 матрицы всегда дает действительные собственные значения и векторы. Если я одновременно диагонализирую 2000 100*100 матриц, он показывает +0.j мнимую часть.   -  person kinder chen    schedule 09.02.2018
comment
Если мнимая часть равна нулю, почему бы вам не использовать output.real?   -  person Ubdus Samad    schedule 09.02.2018
comment
+0.j означает, что мнимая часть собственных значений равна 0? Или это просто означает, что это комплексные числа?   -  person kinder chen    schedule 09.02.2018
comment
Вы можете попробовать переключить точность печати с помощью numpy.set_printoptions (). Из-за конечной точности double за 0.j могла быть спрятана очень маленькая, не значимая мнимая часть. Вы можете избавиться от него, используя numpy.real. Чтобы убедиться, что отбрасывание сложной части не повреждает собственный вектор v и собственное значение w, вы можете вычислить норму невязки ||w v - K.v|| и сравнить ее с нормой ||v||.   -  person francis    schedule 09.02.2018
comment
Спасибо, да, мнимая часть ничтожно мала, но я не понимаю, почему, когда я пробую большой n, она начинает показывать мнимую часть. Форма ошибки LAPACK?   -  person kinder chen    schedule 09.02.2018


Ответы (1)


Согласно документации, numpy.linalg.eig использует (для реальных аргументов) подпрограмму LAPACK DGEEV, который не делает никаких предположений относительно входной матрицы (кроме того, что она реальна). Если матрица достаточно симметрична в пределах точности с плавающей запятой, комплексная часть возвращаемых собственных значений будет равна нулю (выходной аргумент WI из DGEEV). Однако из-за конечной точности может случиться так, что вы получите ложные сложные детали.

РЕДАКТИРОВАТЬ:

  1. Если вы уверены, что ваши матрицы имеют только реальные собственные значения, вы можете разделить сложную часть с помощью _ 4_ или используйте _ 5_ специализируется на симметричных матрицах.

  2. Что касается numpy.linalg.eig, соответствующая часть в numpy/linalg/linalg.py:

    w, vt = _umath_linalg.eig(a, signature=signature, extobj=extobj)
    
    if not isComplexType(t) and all(w.imag == 0.0):
        w = w.real
        vt = vt.real
        result_t = _realType(result_t)
    else:
        result_t = _complexType(result_t)
    

Таким образом, тест представляет собой строгое сравнение all(w.imag == 0.0), и только после этого собственные значения преобразуются в реальные с w = w.real.

person ewcz    schedule 08.02.2018
comment
спасибо, я решаю матричное дифференциальное уравнение. +0.j означает, что мнимая часть собственных значений равна 0? - person kinder chen; 09.02.2018