NxM矩阵的高斯消除

use*_*332 1 c++ algorithm gaussian

/* Program to demonstrate gaussian <strong class="highlight">elimination</strong>
   on a set of linear simultaneous equations
 */

#include <iostream>
#include <cmath>
#include <vector>

using namespace std;

const double eps = 1.e-15;

/*Preliminary pivoting strategy
  Pivoting function
 */
double pivot(vector<vector<double> > &a, vector<double> &b, int i)
 {
     int n = a.size();
     int j=i;
     double t=0;

     for(int k=i; k<n; k+=1)
     {
         double aki = fabs(a[k][i]);
         if(aki>t)
         {
             t=aki;
             j=k;
         }
     }
     if(j>i)
     {
         double dummy;
         for(int L=0; L<n; L+=1)
         {
             dummy = a[i][L];
             a[i][L]= a[j][L];
             a[j][L]= dummy;
         }
         double temp = b[j];
         b[i]=b[j];
         b[j]=temp;
     }
     return a[i][i];
 }        



/* Forward <strong class="highlight">elimination</strong> */
void triang(vector<vector<double> > &a, vector<double> &b) 
{
    int n = a.size();
    for(int i=0; i<n-1; i+=1)
    {
        double diag = pivot(a,b,i);
        if(fabs(diag)<eps)
        {
            cout<<"zero det"<<endl;
            return;
        }
        for(int j=i+1; j<n; j+=1)
        {
            double mult = a[j][i]/diag;
            for(int k = i+1; k<n; k+=1)
            {
                a[j][k]-=mult*a[i][k];
            }
            b[j]-=mult*b[i];
        }
    }
}

/*
DOT PRODUCT OF TWO VECTORS
*/
double dotProd(vector<double> &u, vector<double> &v, int k1,int k2)
{
  double sum = 0;
  for(int i = k1; i <= k2; i += 1)
  {
     sum += u[i] * v[i];
  }
  return sum;
}

/*
BACK SUBSTITUTION STEP
*/
void backSubst(vector<vector<double> > &a, vector<double> &b, vector<double> &x)
{
    int n = a.size();
  for(int i =  n-1; i >= 0; i -= 1)
  {
    x[i] = (b[i] - dotProd(a[i], x, i + 1,  n-1))/ a[i][i];
  }
}
/*
REFINED GAUSSIAN <strong class="highlight">ELIMINATION</strong> PROCEDURE
*/
void gauss(vector<vector<double> > &a, vector<double> &b, vector<double> &x)
{
   triang(a, b);
   backSubst(a, b, x);
}                               

// EXAMPLE MAIN PROGRAM
int main()
{
    int n;
    cin >> n;
    vector<vector<double> > a;
    vector<double> x;
    vector<double> b;
    for (int i = 0; i < n; i++) {
        vector<double> temp;
        for (int j = 0; j < n; j++) {
            int no;
            cin >> no;
            temp.push_back(no);
        }
        a.push_back(temp);
        b.push_back(0);
        x.push_back(0);
    }
    /* 
    for (int i = 0; i < n; i++) {
        int no;
        cin >> no;
        b.push_back(no);
        x.push_back(0);
    }
    */

  gauss(a, b, x);
  for (size_t i = 0; i < x.size(); i++) {
      cout << x[i] << endl;
  }
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

上述高斯消除算法在NxN矩阵上工作正常.但我需要它来处理NxM矩阵.任何人都可以帮我做吗?我不擅长数学.我在一些网站上得到了这个代码而且我坚持了下来.

Ale*_* C. 17

  1. (可选)理解这一点.在纸上做一些例子.
  2. 不要自己编写高斯消除代码.没有一点小心,天真的高斯旋转是不稳定的.你必须缩放线和照顾与最大元素旋转的,出发点是.请注意,此建议适用于大多数线性代数算法.
  3. 如果你想解决方程组,LU分解,QR分解(比LU稳定,但更慢),Cholesky分解(在系统是对称的情况下)或SVD(在系统不是方形的情况下)几乎总是更好选择.然而,高斯消除对于计算决定因素是最佳的.
  4. 使用LAPACK中的算法来解决需要高斯消除的问题(例如求解系统或计算行列式).真.不要自己动手.既然你正在做C++,你可能会对Armadillo感兴趣,它会为你处理很多事情.
  5. 如果您出于教学原因必须自己动手,请先看一下Numerical Recipes,第3版.如果您的预算不足/无法访问图书馆,可以在线免费找到第2版.
  6. 作为一般建议,不要编码您不理解的算法.

  • 要点6:对我来说,在大学里,为了理解它,我们尝试编写算法有很多帮助. (8认同)
  • 是的,对于生产代码,6适用.但对于学习,它可能会有所帮助.铌.6需要免责声明.否则,+1. (2认同)