MathPHP\LinearAlgebra\Matrix::LUDecomposition PHP Method

LUDecomposition() public method

A matrix has an LU-factorization if it can be expressed as the product of a lower-triangular matrix L and an upper-triangular matrix U. If A is a nonsingular matrix, then we can find a permutation matrix P so that PA will have an LU decomposition: PA = LU https://en.wikipedia.org/wiki/LU_decomposition https://en.wikipedia.org/wiki/LU_decomposition#Doolittle_algorithm L: Lower triangular matrix--all entries above the main diagonal are zero. The main diagonal will be all ones. U: Upper tirangular matrix--all entries below the main diagonal are zero. P: Permutation matrix--Identity matrix with possible rows interchanged. Example: [1 3 5] A = [2 4 7] [1 1 0] Create permutation matrix P: [0 1 0] P = [1 0 1] [0 0 1] Pivot A to be PA: [0 1 0][1 3 5] [2 4 7] PA = [1 0 1][2 4 7] = [1 3 5] [0 0 1][1 1 0] [1 1 0] Calculate L and U [1 0 0] [2 4 7] L = [0.5 1 0] U = [0 1 1.5] [0.5 -1 1] [0 0 -2]
public LUDecomposition ( ) : array
return array [ L: Lower triangular matrix U: Upper triangular matrix P: Permutation matrix A: Original square matrix ]
    public function LUDecomposition() : array
    {
        if (!$this->isSquare()) {
            throw new Exception\MatrixException('LU decomposition only works on square matrices');
        }
        $n = $this->n;
        // Initialize L as diagonal ones matrix, and U as zero matrix
        $L = (new DiagonalMatrix(array_fill(0, $n, 1)))->getMatrix();
        $U = MatrixFactory::zero($n, $n)->getMatrix();
        // Create permutation matrix P and pivoted PA
        $P = $this->pivotize();
        $PA = $P->multiply($this);
        // Fill out L and U
        for ($i = 0; $i < $n; $i++) {
            // Calculate Uⱼᵢ
            for ($j = 0; $j <= $i; $j++) {
                $sum = 0;
                for ($k = 0; $k < $j; $k++) {
                    $sum += $U[$k][$i] * $L[$j][$k];
                }
                $U[$j][$i] = $PA[$j][$i] - $sum;
            }
            // Calculate Lⱼᵢ
            for ($j = $i; $j < $n; $j++) {
                $sum = 0;
                for ($k = 0; $k < $i; $k++) {
                    $sum += $U[$k][$i] * $L[$j][$k];
                }
                $L[$j][$i] = $U[$i][$i] == 0 ? \NAN : ($PA[$j][$i] - $sum) / $U[$i][$i];
            }
        }
        // Assemble return array items: [L, U, P, A]
        $this->L = MatrixFactory::create($L);
        $this->U = MatrixFactory::create($U);
        $this->P = $P;
        return ['L' => $this->L, 'U' => $this->U, 'P' => $this->P, 'A' => MatrixFactory::create($this->A)];
    }