/** * @param self $value * @return self * @throws MatrixException */ public function multiplyMatrix(self $value) : self { if ($this->getColumnCount() !== $value->getRowCount()) { throw new MatrixException('Cannot multiply matrices of these sizes.'); } $literal = []; for ($i = 0, $rows = $this->getRowCount(); $i < $rows; $i++) { $row = []; for ($j = 0, $valueColumns = $value->getColumnCount(); $j < $valueColumns; $j++) { $sum = 0; for ($k = 0, $columns = $this->getColumnCount(); $k < $columns; $k++) { $sum += $this->get($i, $k) * $value->get($k, $j); } $row[] = $sum; } $literal[] = $row; } return new static($literal); }
/** * @param Observations $observations * @return array * @throws InvalidArgumentException */ public function regress(Observations $observations) : array { $design = new Matrix($observations->getFeatures()); $observed = (new Matrix([$observations->getOutcomes()]))->transpose(); if ($design->getRowCount() < $design->getColumnCount()) { throw new InvalidArgumentException('Not enough observations to perform regression. You need to have more observations than explanatory variables.'); } $designTranspose = $design->transpose(); $prediction = $designTranspose->multiplyMatrix($design)->inverse()->multiplyMatrix($designTranspose->multiplyMatrix($observed)); return $prediction->transpose()->toArray()[0]; }