5

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

A是一个不等于的m-by-n矩阵,并且是一个带有分量的列向量。mnBm

我希望结果X = A\B是对方程组的欠定或超定系统的最小二乘解AX = B。换句话说,X最小化norm(A*X - B),向量的长度AX - BA\B这意味着我希望它具有与MATLAB中相同的结果。

我想在 GSL-GNU(GNU 科学图书馆)中实现这个功能,但我对数学、最小二乘拟合或矩阵运算知之甚少,有人能告诉我如何在 GSL 中做到这一点吗?或者如果在 GSL 中实现它们太复杂,有人可以建议我一个提供上述矩阵运算的开源 C/C++ 库吗?


好的,在又花了 5 个小时后,我终于自己弄清楚了。但仍然感谢您对我的问题提出的建议。

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

A = [1 0           
     1 0
     0 1
     1 1
     1 1] 

和一个向量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;
 }
4

2 回答 2

4

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

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

#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;
}

另一个不错的是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;
}

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

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

于 2011-10-31T17:39:38.463 回答
1

我不确定我是否理解您的问题,但如果您已经使用 MATLAB 找到了解决方案,您可能需要考虑使用MATLAB Coder,它会自动将您的 MATLAB 代码转换为 C++。

于 2011-10-31T01:54:40.057 回答