Example #1
0
        // 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);
        }