Agree with orlp's answer, which correctly discusses the complete pivoting asked about in the question. This answer shows a common variant, partial pivoting, which only swaps rows (and not columns). This approach is often more efficient, but complete pivoting can offer more reliable results.
The problem
The mathematical method that you're referring to, i.e. pivoting in Gauss-Jordan elimination, requires swapping rows in a matrix.
Naively, rows can be swapped by swapping each of their values one-at-a-time:
// Swap rows 1 and 3
int row_0 = 1;
int row_1 = 3;
for (int i=0; i < rowLength; ++i)
{
var temp = matrix[row_0, i];
matrix[row_0, i] = matrix[row_1, i];
matrix[row_1, i] = temp;
}
This gets you from
matrix[,] = { 1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16 }
to
matrix[,] = { 1 2 3 4
13 14 15 16
9 10 11 12
5 6 7 8 }
But, as you've said, that requires looping over each element in the rows to swap them, and you want something more efficient.
The solution: Indirection
Instead of using a multi-dimensional array like matrix[,]
, you can use an array-of-arrays (also called a jagged array) like matrix[][]
.
row_0[] = { 1 2 3 4 }
row_1[] = { 5 6 7 8 }
row_2[] = { 9 10 11 12 }
row_3[] = { 13 14 15 16 }
matrix[] = { row_0
row_1
row_2
row_3 }
You can still access the array in pretty much the same manner as before; the notation just changes slightly:
// Before, with multi-dimensional array:
matrix[2, 3] == 7
// After, with array-of-arrays:
matrix[2][3] == 7
However swapping rows is a lot easier since you have an array that's literally just a collection of row indices. By swapping those row indices, you effectively swap those rows.
// Swap rows 1 and 3
int row_0 = 1;
int row_1 = 3;
var temp = matrix[row_0];
matrix[row_0] = matrix[row_1];
matrix[row_1] = temp;
This gives you the same switch without having to loop over each element in the row.
row_0[] = { 1 2 3 4 }
row_1[] = { 5 6 7 8 }
row_2[] = { 9 10 11 12 }
row_3[] = { 13 14 15 16 }
matrix[] = { row_0
row_3
row_2
row_1 }
Performance
This change from a multi-dimensional array to array-of-arrays has a few effects on performance and implementation:
A few bloggers have noted that arrays-of-arrays can be more performant in C#. This can be counter-intuitive as they're more general structures than multi-dimensional arrays, but apparently real-world implementations can have arrays-of-arrays be faster even when their extra functionality isn't used.