C / C ++中的最小二乘算法

时间:2015-03-22 18:40:32

标签: c++ line regression least-squares

给定一组点P,我需要找到最接近这些点的线L.我试图使用GNU科学库中的函数gsl_fit_linear。但是,我的数据集通常包含具有未定义斜率(x = c)的最佳拟合线的点,因此gsl_fit_linear返回NaN。我的理解是,最好对这类事物使用总最小二乘法,因为它快速,稳健,并且它给出了r和theta方程(因此x = c仍然可以表示)。我似乎无法找到目前针对此问题的任何C / C ++代码。有谁知道我可以使用的库或其他东西?我已经阅读了一些关于此问题的研究论文,但这个话题仍然有点不知所措,所以我不自信地实现自己的。

更新

我首次尝试使用this维基百科页面上的给定代码使用armadillo编写自己的编程。唉,到目前为止我没有成功。

这是我到目前为止所做的:

void pointsToLine(vector<Point> P)
{
    Row<double> x(P.size());
    Row<double> y(P.size());

    for (int i = 0; i < P.size(); i++)
    {
         x << P[i].x;
         y << P[i].y;
    }

    int m = P.size();
    int n = x.n_cols;

    mat Z = join_rows(x, y);

    mat U;
    vec s;
    mat V;
    svd(U, s, V, Z);

    mat VXY = V(span(0, (n-1)), span(n, (V.n_cols-1)));
    mat VYY = V(span(n, (V.n_rows-1)) , span(n, (V.n_cols-1)));

    mat B = (-1*VXY) / VYY;
    cout << B << endl;
}

B的输出始终为0.5504,即使我的数据集发生变化。我认为输出应该是两个值,所以我确实做了一些非常错误的事情。

谢谢!

1 个答案:

答案 0 :(得分:0)

要找到最小化线的(正交)距离平方和的线,您可以按以下步骤操作:

该线是点p + r * t的集合,其中p和t是要找到的向量,并且r沿着线变化。我们将t限制为单位长度。虽然在二维中有另一个更简单的描述,但这个描述适用于任何维度。

步骤

1 /计算点的平均值

2 /累积协方差矩阵C

    C = Sum{ i | (q[i]-p)*(q[i]-p)' } / N

(你有N分,&#39;表示转置)

3 /对角线C并取对应于最大特征值的特征向量。

所有这一切都可以证明,从点q与上面表示的线的(正交)距离平方开始,这是

d2(q) = q'*q - ((q-p)'*t)^2