Talking about the realization and simple application of Gaussian elimination

First, the principle of Gaussian elimination

For a system of equations composed of m linear equations of n elements, we record it in the form of a matrix:

a11 a12 a13 ...... a1n b1
a21 a22 a23 ...... a2n b2
...
...
...
an1 an2 an3 ...... ann bn

Then perform elementary row-column transformation, try to construct an upper triangular matrix, and gradually reduce the items whose coefficients are not zero;

When there is only one coefficient that is not zero at the end, back-substitution is performed, and the known solution is gradually obtained. (Consult the primary school teacher for the detailed explanation process)

Second, the realization of Gaussian elimination

See other people's blogs for the honest return code. Here is a more toxic non-return violent elimination method:

1.Process

For each equation, select a pivot element according to certain rules (later), record the number of equations corresponding to the pivot element, and then use elementary row-column transformation to eliminate all other coefficients of the element;

In the end, what we get is a ghost matrix with only one non-zero number in each row and one non-zero number in each column (your own brain fill)

At this time, the number corresponding to the ans vector is taken out of the non-zero coefficient of the row, which is the solution corresponding to the element.

2.Code

Let the c array be an array of recorded coefficients (see above for the format), then c should be n rows and n+1 columns, and the last column represents the constant term of the equation;

Let the w array record the pivot element of each equation, and the v array record the answer;

Output "Multiple solutions" when there are multiple solutions, and output "No solution" when there are no solutions;


double c[max_n][max_n+1],v[max_n];

int w[max_n]; 

void gauss(){
    double eps=1e-6;
    for(int i=1;i<=n;++i){    //Enumerate the equation;
        int p=0;                //Record the position of the largest number; 
        double mx=0;        //Recording the largest number;
        for(j=1;j<=n;++j)
            if(fabs(a[i][j]-eps)>mx){
                mx=fabs(a[i][j]);p=j;    //fabs() returns the absolute value of float; 
            }
        if(!p){
            if(fabs(a[i][n+1]<eps))printf("Multiple solutions");
            else printf("No solution");
            return; 
        }
        w[i]=p;
        for(int j=1;j<=n;++j)
            if(i!=j){       //other equations
                double t=a[j][p]/a[i][p];
                for(int k=1;k<=n+1;++k)    //n+1 is important
                    a[j][k]-=a[i][k]*t;
            }
    }
    for(i=1;i<=n;++i) v[w[i]]=a[i][n+1]/a[i][where[i]];
} 

3.notice

(1) Accuracy setting

It is well known that floating-point numbers have precision loss. In Gaussian elimination, the choice of precision depends on the topic. Too low precision will cause numbers with small coefficients to be mistaken for zero coefficients, and too high precision may also lead to errors. If it is greater than the precision, the item that should have the coefficient eliminated as 0 will be mistakenly considered that the coefficient is not zero. Therefore, the choice of precision is a very philosophical issue, which should be paid attention to.

Recommended range: 1e-4 to 1e-10

(2) Selection principle of pivot

Then (1), we know that there is a loss of precision when using floating-point numbers, so it is conceivable that dividing a larger number by a very small number has a large error, so we want to get the accuracy allowed. The pivot with the largest coefficient, so for each equation, we should choose the element with the largest coefficient as the pivot.

(3) Gaussian elimination in the sense of modulo 2

For details, please refer to the explanation of the third example in the related application;

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325269275&siteId=291194637