5

MATLAB プログラムを C++ に移植しようとしています。Aそして、行列と列ベクトルの間の左行列除算を実装したいと思いますB

Aは次と等しくないm-by-n行列で、成分を持つ列ベクトルです。mnBm

そして、その結果X = A\Bが過決定または過決定の方程式系に対する最小二乗法での解であることを望みAX = Bます。つまり、ベクトルの長さをX最小化します。つまり、MATLAB と同じ結果が得られるようにする必要があります。norm(A*X - B)AX - BA\B

この機能を GSL-GNU (GNU Science Library) に実装したいのですが、数学、最小二乗法、行列演算についてあまり知りません。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の例が明らかになりました.1つはQR分解を使用し、もう1つはLU分解を使用しています。

線形システムを解くことができる他の数値ライブラリが存在します (すべての線形代数ライブラリの基本機能)。1 つは、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;
}

もう 1 つの優れたライブラリは、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 コードを自動的に C++ に変換するMATLAB Coderの使用を検討することをお勧めします。

于 2011-10-31T01:54:40.057 に答える