/** * Matrix multiplication * https://en.wikipedia.org/wiki/Matrix_multiplication#Matrix_product_.28two_matrices.29 * * @param Matrix/Vector $B Matrix or Vector to multiply * * @return Matrix * * @throws IncorrectTypeException if parameter B is not a Matrix or Vector * @throws MatrixException if matrix dimensions do not match */ public function multiply($B) : Matrix { if (!$B instanceof Matrix && !$B instanceof Vector) { throw new Exception\IncorrectTypeException('Can only do matrix multiplication with a Matrix or Vector'); } if ($B instanceof Vector) { $B = $B->asColumnMatrix(); } if ($B->getM() !== $this->n) { throw new Exception\MatrixException("Matrix dimensions do not match"); } $n = $B->getN(); $m = $this->m; $R = []; for ($i = 0; $i < $m; $i++) { for ($j = 0; $j < $n; $j++) { $VA = new Vector($this->getRow($i)); $VB = new Vector($B->getColumn($j)); $R[$i][$j] = $VA->dotProduct($VB); } } return MatrixFactory::create($R); }
/** * Perpendicular of A on B * https://en.wikipedia.org/wiki/Vector_projection#Vector_projection * * A⋅B⊥ * perpᵇA = ---- B⊥ * |B|² * * @param Vector $B * * @return Vector */ public function perp(Vector $B) : Vector { $A⋅B⊥ = $B->perpDotProduct($this); $│B│² = $B->l2norm() ** 2; $B⊥ = $B->perpendicular(); return $B⊥->scalarMultiply($A⋅B⊥ / $│B│²); }