Поиск обобщенных собственных векторов численно в Matlab

У меня есть такая матрица, как этот пример (мои фактические матрицы могут быть намного больше)

A = [-1 -2   -0.5;
      0  0.5  0;
      0  0   -1];

который имеет только два линейно-независимых собственных значения (повторяется собственное значение -1). Я хотел бы получить полную основу с обобщенные собственные векторы. Один из способов, которым я знаю, это сделать с помощью функции Matlab jordan в панели инструментов Symbolic Math, но я бы предпочел что-то, предназначенное для числовых входы (на самом деле, с двумя выходами jordan не работает для больших матриц: "Ошибка в команде MuPAD: слишком большая матрица подобия" ). Мне не нужна иорданская каноническая форма, которая, как известно, неустойчива в числовых контекстах, просто матрица обобщенных собственных векторов. Есть ли функция или комбинация функций, которые автоматизируют это с численным стабильностью или должны использовать общий ручной метод (насколько стабильной является такая процедура)?

ПРИМЕЧАНИЕ. Под "обобщенным собственным вектором" подразумевается ненулевой вектор, который можно использовать для дополнения неполного базиса так называемого дефектная матрица. Я не имею в виду собственные векторы, которые соответствуют собственным значениям, полученным при решении <обобщенной задачи собственного значения мой ответ здесь о том, как символически получить обобщенные собственные векторы для матриц, больших 82 на 82 (предел для моей тестовой матрицы в этом вопросе).

Меня все еще интересуют числовые схемы (или как такие схемы могут быть нестабильными, если все они связаны с вычислением формы Жордана). Я не хочу слепо реализовывать метод линейной алгебры 101, который был отмечен как дубликат этого вопроса, поскольку он не является числовым алгоритмом, а скорее карандашом и бумажным методом, используемым для оценки студентов (я полагаю, что он может быть реализован символически, однако). Если кто-нибудь может указать мне на реализацию этой схемы или на ее численный анализ, мне было бы интересно.

ОБНОВЛЕНИЕ 2 - Февраль 2015: все вышеописанное все еще верно, как было протестировано в R2014b.

Ответ 1

Как упоминалось в моих комментариях, если ваша матрица повреждена, но вы знаете, какие пары собственных/собственных значений, которые вы хотите считать идентичными с учетом вашего допуска, вы можете продолжить, как в следующем примере:

% example matrix A:
A = [1 0 0 0 0; 
     3 1 0 0 0; 
     6 3 2 0 0; 
     10 6 3 2 0;
     15 10 6 3 2]
% Produce eigenvalues and eigenvectors (not generalized ones)
[vecs,vals] = eig(A)

Это должно выводить:

vecs =

     0         0         0         0    0.0000
     0         0         0    0.2236   -0.2236
     0         0    0.0000   -0.6708    0.6708
     0    0.0000   -0.0000    0.6708   -0.6708
1.0000   -1.0000    1.0000   -0.2236    0.2236


vals =

 2     0     0     0     0
 0     2     0     0     0
 0     0     2     0     0
 0     0     0     1     0
 0     0     0     0     1

Где мы видим, что первые три собственных вектора почти идентичны рабочей точности, как и две последние. Здесь вы должны знать структуру своей проблемы и идентифицировать идентичные собственные векторы одинаковых собственных значений. Здесь собственные значения точно идентичны, поэтому мы знаем, какие из них следует учитывать, и будем считать, что соответствующие векторы 1-2-3 идентичны и векторы 4-5. (На практике вы, скорее всего, проверите норму различий в собственных векторах и сравните ее с вашим доходом)

Теперь перейдем к вычислению обобщенных собственных векторов, но это плохо обусловлено, чтобы решить просто с помощью matlab \, потому что, очевидно, (A - lambda*I) не является полным рангом. Поэтому мы используем псевдоинверсы:

genvec21 = pinv(A - vals(1,1)*eye(size(A)))*vecs(:,1);
genvec22 = pinv(A - vals(1,1)*eye(size(A)))*genvec21;
genvec1 = pinv(A - vals(4,4)*eye(size(A)))*vecs(:,4);

Что должно дать:

genvec21 =

   -0.0000
    0.0000
   -0.0000
    0.3333
         0

genvec22 =

    0.0000
   -0.0000
    0.1111
   -0.2222
         0

genvec1 =

    0.0745
   -0.8832
    1.5317
    0.6298
   -3.5889

Каковы наши другие обобщенные собственные векторы. Если мы теперь проверим их, чтобы получить нормальную форму иордана следующим образом:

jordanJ = [vecs(:,1) genvec21 genvec22 vecs(:,4) genvec1];
jordanJ^-1*A*jordanJ

Получаем:

ans =

2.0000    1.0000    0.0000   -0.0000   -0.0000
     0    2.0000    1.0000   -0.0000   -0.0000
     0    0.0000    2.0000    0.0000   -0.0000
     0    0.0000    0.0000    1.0000    1.0000
     0    0.0000    0.0000   -0.0000    1.0000

Это нормальная форма Джордана (с ошибками рабочей точности).