Отличающиеся результаты процедур собственных векторов в Си и Python
Итак, я заметил, что я получаю разные ответы для собственного разложения матрицы 4x4 всех 1 с.
В Python с помощью numpy.linalg.eig:
matrix = numpy.ones((M,M), dtype=float);
values, vectors = numpy.linalg.eig(matrix);
Результат Python:
V1: [-0.866025 +0.288675 +0.288675 +0.288675]
V2: [+0.500000 +0.500000 +0.500000 +0.500000]
V3: [+0.391955 +0.597433 -0.494694 -0.494694]
V4: [+0.866025 -0.288675 -0.288675 -0.288675]
В С использованием LAPACK DSYEV:
#define NN 4
#define LDA NN
void main(){
int n = NN, lda = LDA, lwork=NN*NN*NN*NN*NN, info;
char both = 'V';
char uplo = 'U';
double w[NN*NN];
double work[NN*NN*NN*NN*NN];
double a[LDA*NN] = {
1, 1, 1, 1,
1, 1, 1, 1,
1, 1, 1, 1,
1, 1, 1, 1
};
dsyev_(&both, &uplo, &n, a, &lda, w, work, &lwork, &info);
return;
}
C DSYEV Результат:
V1: +0.000596 +0.000596 -0.707702 +0.706510
V2: +0.500000 +0.500000 -0.499157 -0.500842
V3: +0.707107 -0.707107 -0.000000 +0.000000
V4: +0.500000 +0.500000 +0.500000 +0.500000
В С использованием LAPACK DGEEV:
#define NN 4
#define LDA NN
#define LDVL NN
#define LDVR NN
void main() {
char compute_left = 'V';
char compute_right = 'V';
int n = NN, lda = LDA, ldvl = LDVL, ldvr = LDVR, info, lwork=2*NN*NN;
double work[2*NN*NN];
double wr[NN], wi[NN], vl[LDVL*NN], vr[LDVR*NN];
double a[LDA*NN] = {
1, 1, 1, 1,
1, 1, 1, 1,
1, 1, 1, 1,
1, 1, 1, 1
};
dgeev_( &compute_left, &compute_right, &n, a, &lda, wr, wi, vl, &ldvl, vr, &ldvr, work, &lwork, &info );
return;
}
C ДГЕЕВ Результат:
V1: -0.866025 +0.288675 +0.288675 +0.288675
V2: -0.500000 -0.500000 -0.500000 -0.500000
V3: -0.000000 -0.816497 +0.408248 +0.408248
V4: -0.000000 -0.000000 -0.707107 +0.707107
Результаты все разные!
Итак, у меня есть два основных вопроса:
- Зачем? Это связано с вырождением в матрице 1?
- Как я могу повторить результаты Python In C?
Любое понимание будет оценено.
2 ответа
Все верно. Ваша матрица имеет два собственных значения, 4 и 0. Пространство собственных значений для 4 - это строка, натянутая на [1,1,1,1], кратное число которой отображается во всех списках. Собственное пространство для 0- это 3-пространство x_1 + x_2 + x_3 + x_4 = 0. Каждый из трех методов дал вам различную основу для этого подпространства - за исключением numpy, который давал только векторы, охватывающие двумерное подпространство, для некоторых причина.
На мой взгляд, результаты DGEEV являются лучшими из тех, о которых вы сообщаете, поскольку они дают ортонормированную основу для 0-собственного пространства в разумной форме лестничной формы.
Три из четырех собственных значений равны 0 (попробуйте распечатать values
в вашем скрипте Python). Поскольку все элементы матрицы идентичны (единицы), любой вектор, в котором элементы добавляют к нулю, будет действительным собственным вектором, соответствующим нулевому собственному значению. Как именно выбран этот вектор, не важно, поэтому тот факт, что разные программы находят разные собственные векторы для нулевых собственных значений, не важен. Вы должны подтвердить, что эти собственные векторы действительно имеют элементы, которые в сумме составляют 0.
Последнее собственное значение равно 4 (ненулевое), что означает, что соответствующий собственный вектор должен иметь идентичные (ненулевые) элементы. Точное значение этих элементов зависит от нормализации собственных векторов, которые в ваших примерах также различаются.
В общем, все действительно хорошо, просто собственные векторы вашей матрицы очень неуникальны. Другое решение, которое я нахожу более приятным, найдено Wolfram Alpha.
Обновить
Как правило, M
от M
матрица имеет M
собственные значения. Если два (или более) из них идентичны, существует бесконечное число возможных реализаций соответствующих собственных векторов, потому что из двух (назовите их v1
а также v2
), мы можем построить новый v3 = a*v1 + b*v2
, где a
а также b
произвольные постоянные.