// PLUDecomposition (PLU): Returns the Permutation Matrix, Lower Triangular Matrix, and Upper Triangular Matrix decomposition of a given Matrix as a tuple public static (Matrix, Matrix, Matrix) PLUDecomposition(Matrix matrix) { Matrix PermutationMatrix = Identity(matrix.rows); Matrix LowerTriangularMatrix; if (matrix.rows > matrix.columns) { LowerTriangularMatrix = new Matrix(matrix.rows, matrix.columns); } else { LowerTriangularMatrix = new Matrix(matrix.rows, matrix.rows); } Matrix UpperTriangularMatrix = Copy(matrix); for (uint colIndex = 0; colIndex < LowerTriangularMatrix.columns; colIndex++) { uint pivotIndex = colIndex; double pivotValue = UpperTriangularMatrix.values[colIndex, colIndex]; if (pivotValue < 0) { pivotValue = pivotValue * -1; } for (uint rowIndex = colIndex + 1; rowIndex < LowerTriangularMatrix.rows; rowIndex++) { double rowValue = UpperTriangularMatrix.values[rowIndex, colIndex]; if (rowValue < 0) { rowValue = rowValue * -1; } if (pivotValue < rowValue) { pivotIndex = rowIndex; pivotValue = rowValue; } } if (pivotIndex != colIndex) { PermutationMatrix.SwapRows(colIndex, pivotIndex); LowerTriangularMatrix.SwapRows(colIndex, pivotIndex); UpperTriangularMatrix.SwapRows(colIndex, pivotIndex); } LowerTriangularMatrix.values[colIndex, colIndex] = 1; if (UpperTriangularMatrix.values[colIndex, colIndex] == 0) { continue; } for (uint rowIndex = colIndex + 1; rowIndex < LowerTriangularMatrix.rows; rowIndex++) { double operation = -(UpperTriangularMatrix.values[rowIndex, colIndex] / UpperTriangularMatrix.values[colIndex, colIndex]); LowerTriangularMatrix.values[rowIndex, colIndex] = -operation; UpperTriangularMatrix.SwapRows(rowIndex, AddArrays(MultiplyArray(UpperTriangularMatrix.RowValues(colIndex), operation), UpperTriangularMatrix.RowValues(rowIndex))); } } for (uint rowIndex = (uint)matrix.columns; rowIndex < matrix.rows; rowIndex++) { UpperTriangularMatrix.RemoveRow((uint)matrix.columns); } PermutationMatrix = Transpose(PermutationMatrix); return(PermutationMatrix, LowerTriangularMatrix, UpperTriangularMatrix); }