Вычисление нулевого пространства с использованием Eigen неверно?

Я использую библиотеку Eigen (http://eigen.tuxfamily.org) для вычисления нулевого пространства с использованием функция СВД. Я сравнил вывод с функцией «Null» в Matlab и получил разные результаты. Пройдясь по нему с помощью отладчика и посмотрев на матрицу V, созданную Эйгеном, по сравнению с матрицей V из Matlab, вы обнаружите странную разницу.

Левосингулярные векторы (левые 3 столбца в приведенном ниже примере) в матрице V почти одинаковы, но знаки поменялись местами. Правые сингулярные векторы (нулевое пространство; правые 3 столбца ниже) совсем не похожи.

Любая идея, что может вызвать это? Я неправильно использую функцию SVD? Код и пример результатов ниже.

Вот код: «вход» — это обычный массив C++:

/* Create a matrix with the nessecary size */
MatrixXf A(inRows, inCols);

/* Populate the matrix from the input */
for (int i=0; i < inRows; i++)
{
  for(int j=0; j < inCols; j++)
  {
    A(i,j) = input[i*inCols + j];
  }
}

/* Do a singular value decomposition on the matrix */
JacobiSVD<MatrixXf> svd(A, Eigen::ComputeFullV);

/* Get the V matrix */
MatrixXf V((int)svd.matrixV().rows(), (int)svd.matrixV().cols());
V = svd.matrixV();

Вот несколько примеров результатов:

А (вход) =

-0.5059    -0.0075   -0.0121   -0.3526   -0.3528   -0.0128
-0.0067     0.4915    0.0235   -0.3503    0.3559    0.0211
 0.0027     0.0010   -0.5015    0.0021   -0.0031   -0.4999

V(Матлаб) =

 0.3120    0.6304    0.1115   -0.5031   -0.4895   -0.0027
 0.3628   -0.2761    0.5333    0.4955   -0.5121   -0.0018
 0.5180   -0.1804   -0.4480   -0.0002    0.0000   -0.7060
-0.0353    0.6404   -0.2953    0.7081    0.0074   -0.0023
 0.4859    0.2283    0.4623    0.0032    0.7057    0.0048
 0.5151   -0.1775   -0.4489    0.0014   -0.0080    0.7082

V (собственный) =

-0.3120   -0.6304   -0.1115   -0.5040   -0.4886   -0.0038
-0.3628    0.2761   -0.5333    0.4638   -0.4832    0.2432
-0.5180    0.1804    0.4480    0.1693   -0.1736   -0.6630
 0.0353   -0.6404    0.2953    0.6878    0.0257    0.1666
-0.4859   -0.2283   -0.4623    0.0258    0.6851   -0.1677
-0.5151    0.1775    0.4489   -0.1689    0.1665    0.6674

Спасибо вам за вашу помощь!


person npulaski    schedule 29.03.2013    source источник


Ответы (1)


Во-первых, существует несколько способов формирования ортонормированного базиса пространства. (Например, [1 0; 0 1] и 1/sqrt(2) * [ 1 -1; 1 1 ] оба описывают одно и то же двумерное евклидово пространство). Таким образом, мы не обязательно ожидаем, что две альтернативные реализации будут выбирать один и тот же базисный набор.

Если мы возьмем правые три столбца в каждом случае, мы узнаем следующее:

> Vmat = Vmat(:,4:end);
> Veig = Veig(:,4:end);
> Vmat' * V_mat

ans =

 1.0000e+00   8.8800e-06  -1.4120e-05
 8.8800e-06   9.9999e-01  -5.1830e-05
-1.4120e-05  -5.1830e-05   1.0000e+00

> Veig' * Veig

ans = 

 1.0001e+00  -1.4050e-05   2.4200e-06
-1.4050e-05   1.0001e+00  -4.8310e-05
 2.4200e-06  -4.8310e-05   1.0000e+00

> A * Vmat

ans =

 7.7612e-17   7.8916e-17   0.0000e+00
-4.1193e-17   4.8139e-17   0.0000e+00
 6.6136e-18  -6.0715e-18   1.1102e-16

> A * Veig

ans = 

-1.2030e-05   1.1000e-05  -6.0000e-07
-4.8600e-06   3.8750e-05   1.5490e-05
-3.4400e-06  -4.5210e-05  -3.6090e-05

Итак, это оба ортонормированных базиса, и оба они в основном являются нулевыми пространствами. Однако уровень ошибки в случае Эйгена, по-видимому, соответствует тому факту, что это было сделано с одинарной точностью. Попробуйте еще раз с двойной точностью и посмотрите, как результаты сравниваются на этот раз (я не утверждаю, что это определенно поможет, просто это одно очевидное отличие от Matlab).

person Oliver Charlesworth    schedule 29.03.2013
comment
Разве нулевое пространство не должно быть уникальным для любой заданной матрицы, поскольку это набор векторов x, для которых Ax=0? - person npulaski; 30.03.2013
comment
@ user2221699: пустое пространство уникально. Но есть несколько способов описать это. - person Oliver Charlesworth; 30.03.2013
comment
Спасибо, я не ожидал, что одинарная и двойная точность так сильно изменит результат. Я изменю код, чтобы использовать двойную точность, и посмотрю, как это изменит результат. - person npulaski; 30.03.2013
comment
Привет, нпуласки, я хотел бы спросить, что произошло после того, как вы перешли на двойную точность? - person PaulYang; 06.04.2015
comment
Здравствуйте, Павел, извините за долгий ответ. Прошло некоторое время с тех пор, как я сделал это, но у меня все получилось, поэтому я считаю, что результат был правильным, когда я переключился на двойную точность. - person npulaski; 01.11.2016