public function evaluate(array $params) { $m = $this->m; $n = $this->n; $R = []; for ($i = 0; $i < $m; $i++) { for ($j = 0; $j < $n; $j++) { $func = $this->A[$i][$j]; $R[$i][$j] = $func($params); } } return MatrixFactory::create($R); }
/** * LU Decomposition (Doolittle decomposition) with pivoting via permutation matrix * * 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] * * @return array [ * L: Lower triangular matrix * U: Upper triangular matrix * P: Permutation matrix * A: Original square matrix * ] * * @throws MatrixException if matrix is not square */ 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)]; }
/** * Outer product (A⨂B) * https://en.wikipedia.org/wiki/Outer_product * * @param Vector $B * * @return Matrix */ public function outerProduct(Vector $B) : Matrix { $m = $this->n; $n = $B->getN(); $R = []; for ($i = 0; $i < $m; $i++) { for ($j = 0; $j < $n; $j++) { $R[$i][$j] = $this->A[$i] * $B[$j]; } } return MatrixFactory::create($R); }