我开始使用Eigen库实现算法。我需要计算矩阵的零空间(内核)。我尝试过使用立方体矩阵,
0, 0, 1,
0, 1, 0,
1, 0, 0,
-1, 0, 0,
0, 0, -1,
0, -1, 0
然后,我打电话给its source
A.transposeInPlace();
std::cout << "and after being transposed:\n" << A << std::endl;
FullPivLU<MatrixXf> lu(A);
MatrixXf A_null_space = lu.kernel();
std::cout << "Null space:\n" << A_null_space << std::endl;
A_null_space.transposeInPlace();
std::cout << "Null space Transposed_A:\n" << A_null_space;
我获得了,
0.5 0 -1 1 0 0 0 0 0 0.5
-0.5 0 -0 0 1 0 0 0 0 -0.5
0.5 0 -0 0 0 1 0 0 0 -0.5
0.5 0 -0 0 0 0 1 0 0 0.5
-1 0 1 0 0 0 0 1 0 -1
-0.5 0 1 0 0 0 0 0 1 -0.5
-0.5 1 -0 0 0 0 0 0 0 0.5
但是,后来我意识到它的正确内核和左内核是相同的,似乎代码片段计算左内核。代码在另一个测试用例上得到了疯狂的输出。那么,如何计算正确的内核呢? The link也是为了显示左右内核与示例的区别。但是,如果我删除第一行,则输出为0 0 0
显然,案件的问题是,
MatrixXf A{10, 3};
A <<
1, 0, 1 ,
1, 0, 0 ,
0, 1, 1 ,
0, 1, 0 ,
0, 0, 1 ,
-1, 0, 0 ,
0, 0, -1 ,
0, -1, 1 ,
0, -1, 0 ,
-1, 0, 1;
其输出预期为,
1 0 0 0 0 0 0 -2 2 1
0 1 0 0 0 0 0 -1 1 1
0 0 1 0 0 0 0 -1 2 0
0 0 0 1 0 0 0 0 1 0
0 0 0 0 1 0 0 -1 1 0
0 0 0 0 0 1 0 1 -1 -1
0 0 0 0 0 0 1 1 -1 0
QR分解,
HouseholderQR<MatrixXf> qr(A);
cout << "\nQR matrix to compare \n" << qr.matrixQR().transpose();
然后我明白了,
-1.41421 0 0.414214
-0.707107 -0.707107 -1
-0.707107 0.707107 1
0 0 1
-0.707107 0.707107 0
0.707107 0.707107 0
0.707107 -0.707107 0
-0.707107 0.707107 -1
0 0 -1
1.19209e-07 1.41421 5.96046e-08
@Edit 2, Eigen是否计算错误?
@Edit 3,
我真的很困惑,因为这两个矩阵似乎都是正确的!怎么来的?
答案 0 :(得分:0)
正如您所观察到的,两个矩阵都是有效的正确内核。这是因为它们对应于相同子空间的两个不同基础。要检查它,您可以将两个矩阵缩减为缩减行梯形形式(matlab中的rref函数,或参见此online calculator)。此转换是唯一的,不会更改矩阵定义的范围。您的参考内核基础已经是这种形式。因此,您所要做的就是减少Eigen返回的那个,并看到它为您提供与参考矩阵相同的矩阵。