Suppose you have a system of n∈N≥1 linear equations and variables x1,x2,…,xn∈R:
a1,1⋅x1+a1,2x2+⋯+a1,n⋅xn=b1 a2,1⋅x1+a2,2x2+⋯+a2,n⋅xn=b2 ⋮=⋮ an,1⋅x1+an,2x2+⋯+an,n⋅xn=bn
All factors ai,j∈R for i,j∈1,…,n can be written in one matrix A∈Rn×n and all bi can be written as a vector b. You combine all xi in the same way to a vector x.
So you can write the system of equations as:
A⋅x=b
How Gaussian elimination works ¶
First, you write A and b in an augmented matrix (A|b):
On this matrix you may make exactly three operations:
- Swap rows
- Add one row onto another
- Multiply every factor of one row with a constant
You want to get a triangular matrix. So you subsequently eliminate one variable from the system of equations until you have a matrix like this:
It's actually quite simple to get this form:

C++ Code ¶
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
void print(vector< vector<double> > A) {
int n = A.size();
for (int i=0; i<n; i++) {
for (int j=0; j<n+1; j++) {
cout << A[i][j] << "\t";
if (j == n-1) {
cout << "| ";
}
}
cout << "\n";
}
cout << endl;
}
vector<double> gauss(vector< vector<double> > A) {
int n = A.size();
for (int i=0; i<n; i++) {
// Search for maximum in this column
double maxEl = abs(A[i][i]);
int maxRow = i;
for (int k=i+1; k<n; k++) {
if (abs(A[k][i]) > maxEl) {
maxEl = abs(A[k][i]);
maxRow = k;
}
}
// Swap maximum row with current row (column by column)
for (int k=i; k<n+1;k++) {
double tmp = A[maxRow][k];
A[maxRow][k] = A[i][k];
A[i][k] = tmp;
}
// Make all rows below this one 0 in current column
for (int k=i+1; k<n; k++) {
double c = -A[k][i]/A[i][i];
for (int j=i; j<n+1; j++) {
if (i==j) {
A[k][j] = 0;
} else {
A[k][j] += c * A[i][j];
}
}
}
}
// Solve equation Ax=b for an upper triangular matrix A
vector<double> x(n);
for (int i=n-1; i>=0; i--) {
x[i] = A[i][n]/A[i][i];
for (int k=i-1;k>=0; k--) {
A[k][n] -= A[k][i] * x[i];
}
}
return x;
}
int main() {
int n;
cin >> n;
vector<double> line(n+1,0);
vector< vector<double> > A(n,line);
// Read input data
for (int i=0; i<n; i++) {
for (int j=0; j<n; j++) {
cin >> A[i][j];
}
}
for (int i=0; i<n; i++) {
cin >> A[i][n];
}
// Print input
print(A);
// Calculate solution
vector<double> x(n);
x = gauss(A);
// Print result
cout << "Result:\t";
for (int i=0; i<n; i++) {
cout << x[i] << " ";
}
cout << endl;
}
You can call it like this:
./gauss.out < 3x3.in
1 2 3 | 1
4 5 6 | 1
1 0 1 | 1
Result: 0 -1 1
Python code ¶
#!/usr/bin/env python
# -*- coding: utf-8 -*-
def pprint(A):
n = len(A)
for i in range(0, n):
line = ""
for j in range(0, n + 1):
line += str(A[i][j]) + "\t"
if j == n - 1:
line += "| "
print(line)
print("")
def gauss(A):
n = len(A)
for i in range(0, n):
# Search for maximum in this column
maxEl = abs(A[i][i])
maxRow = i
for k in range(i + 1, n):
if abs(A[k][i]) > maxEl:
maxEl = abs(A[k][i])
maxRow = k
# Swap maximum row with current row (column by column)
for k in range(i, n + 1):
tmp = A[maxRow][k]
A[maxRow][k] = A[i][k]
A[i][k] = tmp
# Make all rows below this one 0 in current column
for k in range(i + 1, n):
c = -A[k][i] / A[i][i]
for j in range(i, n + 1):
if i == j:
A[k][j] = 0
else:
A[k][j] += c * A[i][j]
# Solve equation Ax=b for an upper triangular matrix A
x = [0 for i in range(n)]
for i in range(n - 1, -1, -1):
x[i] = A[i][n] / A[i][i]
for k in range(i - 1, -1, -1):
A[k][n] -= A[k][i] * x[i]
return x
if __name__ == "__main__":
from fractions import Fraction
n = input()
A = [[0 for j in range(n + 1)] for i in range(n)]
# Read input data
for i in range(0, n):
line = map(Fraction, raw_input().split(" "))
for j, el in enumerate(line):
A[i][j] = el
raw_input()
line = raw_input().split(" ")
lastLine = map(Fraction, line)
for i in range(0, n):
A[i][n] = lastLine[i]
# Print input
pprint(A)
# Calculate solution
x = gauss(A)
# Print result
line = "Result:\t"
for i in range(0, n):
line += str(x[i]) + "\t"
print(line)
JavaScript code ¶
/** Solve a linear system of equations given by a n×n matrix
with a result vector n×1. */
function gauss(A) {
var n = A.length;
for (var i=0; i<n; i++) {
// Search for maximum in this column
var maxEl = Math.abs(A[i][i]);
var maxRow = i;
for(var k=i+1; k<n; k++) {
if (Math.abs(A[k][i]) > maxEl) {
maxEl = Math.abs(A[k][i]);
maxRow = k;
}
}
// Swap maximum row with current row (column by column)
for (var k=i; k<n+1; k++) {
var tmp = A[maxRow][k];
A[maxRow][k] = A[i][k];
A[i][k] = tmp;
}
// Make all rows below this one 0 in current column
for (k=i+1; k<n; k++) {
var c = -A[k][i]/A[i][i];
for(var j=i; j<n+1; j++) {
if (i==j) {
A[k][j] = 0;
} else {
A[k][j] += c * A[i][j];
}
}
}
}
// Solve equation Ax=b for an upper triangular matrix A
var x= new Array(n);
for (var i=n-1; i>-1; i--) {
x[i] = A[i][n]/A[i][i];
for (var k=i-1; k>-1; k--) {
A[k][n] -= A[k][i] * x[i];
}
}
return x;
}
PHP ¶
<?php
/**
* Gaussian elimination
* @param array $A matrix
* @param array $x vector
* @return array solution vector
*/
function gauss($A, $x) {
# Just make a single matrix
for ($i=0; $i < count($A); $i++) {
$A[$i][] = $x[$i];
}
$n = count($A);
for ($i=0; $i < $n; $i++) {
# Search for maximum in this column
$maxEl = abs($A[$i][$i]);
$maxRow = $i;
for ($k=$i+1; $k < $n; $k++) {
if (abs($A[$k][$i]) > $maxEl) {
$maxEl = abs($A[$k][$i]);
$maxRow = $k;
}
}
# Swap maximum row with current row (column by column)
for ($k=$i; $k < $n+1; $k++) {
$tmp = $A[$maxRow][$k];
$A[$maxRow][$k] = $A[$i][$k];
$A[$i][$k] = $tmp;
}
# Make all rows below this one 0 in current column
for ($k=$i+1; $k < $n; $k++) {
$c = -$A[$k][$i]/$A[$i][$i];
for ($j=$i; $j < $n+1; $j++) {
if ($i==$j) {
$A[$k][$j] = 0;
} else {
$A[$k][$j] += $c * $A[$i][$j];
}
}
}
}
# Solve equation Ax=b for an upper triangular matrix $A
$x = array_fill(0, $n, 0);
for ($i=$n-1; $i > -1; $i--) {
$x[$i] = $A[$i][$n]/$A[$i][$i];
for ($k=$i-1; $k > -1; $k--) {
$A[$k][$n] -= $A[$k][$i] * $x[$i];
}
}
return $x;
}
?>
And some tiny tests:
<?php
$A = array(array(7));
$x = array(3);
$result = gauss($A, $x);
var_dump($result);
### array (size=1)
### 0 => float 0.42857142857143 = 3 / 7
$A = array(array(7));
$x = array(0);
$result = gauss($A, $x);
var_dump($result);
### array (size=1)
### 0 => int 0
?>
Test equations with two variables (see Wolfram|Alpha):
<?php
$A = array(array(7, 1), array(5, 3));
$x = array(1, 3);
$result = gauss($A, $x);
var_dump($result);
### array (size=2)
### 0 => float 0
### 1 => float 1
?>
Test equations with two variables (see Wolfram|Alpha):
<?php
$A = array(array(7, 1), array(5, 3));
$x = array(1, 1);
$result = gauss($A, $x);
var_dump($result);
### array (size=2)
### 0 => float 0.125
### 1 => float 0.125
?>
Complexity ¶
Time complexity ¶
Time complexity is in O(n3) (lines 44 - 53):
Operations=n−1∑i=0n−1∑k=i+1n∑j=i1 =n−1∑i=0n−1∑k=i+1(n−i+1) =(n−1∑i=0n−1∑k=i+1(n+1))−(n−1∑i=0n−1∑k=i+1i) =… =16⋅n⋅(2n2+3n−5) =13⋅n3+O(n2)
Space complexity ¶
Space complexity of this implementation is in O(n), but you can
easily come down to O(1) when you use A[n]
for
storing x
.