c++ - 超定线性代数方程的最小二乘解Ax = By

标签 c++ linear-algebra eigen

我有一个 Ax=By 形式的线性代数方程。其中 A 是 6x5 的矩阵,x 是大小为 5 的 vector ,B 是 6x6y 大小为 6 的 vector 。ABy 是已知变量,它们的值是实时访问的从传感器。 x 未知,必须找到。一种解决方案是找到 Least Square Estimation,即 x = [(A^T*A)^-1]*(A^T)B*y。这是线性代数方程的常规解。我使用 Eigen QR Decomposition 来解决这个问题,如下所示

matrixA = getMatrixA();
matrixB = getMatrixB();
vectorY = getVectorY();
//LSE Solution
Eigen::ColPivHouseholderQR<Eigen::MatrixXd> dec1(matrixA);
vectorX = dec1.solve(matrixB*vectorY);//

到目前为止一切都很好。但是当我检查错误e = Ax-By 时,它总是不为零。误差不是很大,但也不容忽视。还有其他更可靠的分解类型吗?我浏览了其中一页,但无法理解其含义或如何实现。以下是如何解决问题的引用线。有人可以建议我如何实现吗?

此类方程的解 Ax = By 是通过形成误差 vector e = Ax-By 并找到未知 vector x 获得的> 最小化加权误差 (e^T*W*e),其中 W 是加权矩阵。为简单起见,选择此加权矩阵的形式为 W = K*S,其中 S 是常数对角缩放矩阵,而 K 是标量权重。因此方程的解变为

x = [(A^T*W*A)^-1]*(A^T)*W*B*y

我不明白如何形成矩阵W

最佳答案

你的陈述“但是当我检查错误 e = Ax-By 时,它总是不为零。”几乎总是正确的,无论你的技术如何,或者你选择什么权重。当您有一个过度描述的系统时,您基本上是在尝试将直线拟合到一系列点。除非碰巧所有的点都可以精确地放在一条完美的直线上,否则会有一些错误。因此,无论您使用什么技术来选择线(权重等),如果点不共线,您总会有一些错误。另一种方法是使用某种样条,或者在更高的维度上允许翘曲。在这些情况下,您可以选择将所有点精确地拟合到更复杂的形状,从而得到 0 错误的结果。

enter image description here

因此,权重矩阵的选择只是通过为每个点赋予略微不同的权重来改变您将使用的直线。所以它永远不会完全消除错误。但是,如果您有几个比其他点更关心的特定点,则可以在选择最小二乘误差拟合时为这些点的误差赋予更高的权重。

样条拟合见:

http://en.wikipedia.org/wiki/Spline_interpolation

对于真正最好的样条曲线插值,您可以使用 Centripital Catmull-Rom,它除了找到适合所有点的曲线外,还将防止在数据方向突然变化时有时会出现的不必要的循环和自相交.

Catmull-rom curve with no cusps and no self-intersections

关于c++ - 超定线性代数方程的最小二乘解Ax = By,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22718737/

相关文章:

arrays - 正向替换打包数组

c++ - cmake Eigen find_package提示

c++ - 将特征向量的绝对值存储到变量中

使用 vector 推回和迭代器时出现 C++ 运行时错误

python - 计算 scipy.sparse 矩阵的伪逆矩阵的列子集的最快方法

c++ - 为什么我不能在成对的优先级队列中简单地覆盖 < ?

c++ - 泊松方程的 Eigen 共轭梯度与 SimplicialLLT

eigen - 将 coeffRef 与 const CwiseUnaryView 结合使用 - 两个 CWiseUnaryView 相乘时失败

c++ - 类(class)(员工)存放在哪个内存段(代码/数据段)?

c++ - 为什么 OpenMP 程序只在一个线程中运行