如何使用gsl在C++上实现左矩阵除法

Dan*_*Gao 5 c++ math matlab linear-algebra gsl

我正在尝试将MATLAB程序移植到C++.我想在矩阵A和列向量之间实现左矩阵除法B.

A是一个m-by-n具有矩阵m不等于nB是与列矢量m分量.

并且我希望结果X = A\B是最小二乘意义上的解决方案对于欠定或超定方程组AX = B.换句话说,X最小化norm(A*X - B)矢量的长度AX - B.这意味着我希望它与A\BMATLAB中的结果相同.

我想在GSL-GNU(GNU Science Library)中实现这个功能,我不太了解数学,最小二乘拟合或矩阵运算,有人能告诉我如何在GSL中做到这一点吗?或者如果在GSL中实现它们太复杂了,有人可以建议我提供一个好的开源C/C++库来提供上面的矩阵操作吗?


好吧,在我花了5个小时后,我终于弄明白了.但是仍然感谢我对我的问题的建议.

假设我们有一个5*2矩阵

A = [1 0           
     1 0
     0 1
     1 1
     1 1] 
Run Code Online (Sandbox Code Playgroud)

和一个矢量 b = [1.8388,2.5595,0.0462,2.1410,0.6750]

A \ b将是的解决方案

 #include <stdio.h>
 #include <gsl/gsl_linalg.h>

 int
 main (void)
 {
   double a_data[] = {1.0, 0.0,1.0, 0.0, 0.0,1.0,1.0,1.0,1.0,1.0};

   double b_data[] = {1.8388,2.5595,0.0462,2.1410,0.6750};

   gsl_matrix_view m
     = gsl_matrix_view_array (a_data, 5, 2);

   gsl_vector_view b
     = gsl_vector_view_array (b_data, 5);

   gsl_vector *x = gsl_vector_alloc (2); // size equal to n
   gsl_vector *residual = gsl_vector_alloc (5); // size equal to m
   gsl_vector *tau = gsl_vector_alloc (2); //size equal to min(m,n)
   gsl_linalg_QR_decomp (&m.matrix, tau); // 
   gsl_linalg_QR_lssolve(&m.matrix, tau, &b.vector, x, residual);

   printf ("x = \n");
   gsl_vector_fprintf (stdout, x, "%g");
   gsl_vector_free (x);
   gsl_vector_free (tau);
   gsl_vector_free (residual);
   return 0;
 }
Run Code Online (Sandbox Code Playgroud)

Amr*_*mro 4

除了您给出的之外,快速搜索还发现了其他GSL 示例,一个使用QR 分解,另一个使用LU 分解

还存在其他能够求解线性系统的数值库(每个线性代数库的基本功能)。首先,Armadillo提供了一个漂亮且可读的界面:

#include <iostream>
#include <armadillo>
using namespace std;
using namespace arma;

int main()
{
    mat A = randu<mat>(5,2);
    vec b = randu<vec>(5);

    vec x = solve(A, b);
    cout << x << endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

另一个好的库是Eigen库:

#include <iostream>
#include <Eigen/Dense>
using namespace std;
using namespace Eigen;

int main()
{
    Matrix3f A;
    Vector3f b;
    A << 1,2,3,  4,5,6,  7,8,10;
    b << 3, 3, 4;

    Vector3f x = A.colPivHouseholderQr().solve(b);
    cout << "The solution is:\n" << x << endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

现在,要记住的一件事是MLDIVIDE是一个超级功能,并且具有多个执行路径。如果系数矩阵 A 具有某种特殊结构,则可以利用它来获得更快或更准确的结果(可以选择替换算法、LU 和 QR 分解,..)

MATLAB 还具有PINV,它返回最小范数最小二乘解,此外还有许多其他用于求解线性方程组的迭代方法。