/** * plus * A + B * @param mixed $B Matrix/Array * @return Matrix Sum */ function plus() { if (func_num_args() > 0) { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); switch ($match) { case 'object': $M = is_a($args[0], 'Matrix') ? $args[0] : trigger_error(ArgumentTypeException, ERROR); //$this->checkMatrixDimensions($M); for ($i = 0; $i < $this->m; $i++) { for ($j = 0; $j < $this->n; $j++) { $M->set($i, $j, $M->get($i, $j) + $this->A[$i][$j]); } } return $M; break; case 'array': $M = new Matrix($args[0]); //$this->checkMatrixDimensions($M); for ($i = 0; $i < $this->m; $i++) { for ($j = 0; $j < $this->n; $j++) { $M->set($i, $j, $M->get($i, $j) + $this->A[$i][$j]); } } return $M; break; default: trigger_error(PolymorphicArgumentException, ERROR); break; } } else { trigger_error(PolymorphicArgumentException, ERROR); } }
/** * Multiply the given matrices. * * @param matrix left matrix * @param matrix right matrix * @return matrix product matrix $a*$b */ public static function multiply($a, $b) { // First check dimensions. new Assertion($a instanceof Matrix, 'Given first matrix not of class Matrix.'); new Assertion($b instanceof Matrix, 'Given second matrix not of class Matrix.'); new Assertion($a->columns() == $b->rows(), 'Given dimensions are not compatible.'); $c = new Matrix($a->rows(), $b->columns()); $c->setAll(0.0); for ($i = 0; $i < $a->rows(); $i++) { for ($j = 0; $j < $b->columns(); $j++) { for ($k = 0; $k < $a->columns(); $k++) { $c->set($i, $j, $c->get($i, $j) + $a->get($i, $k) * $b->get($k, $j)); } } } return $c; }
/** * transpose * * Tranpose matrix * @return Matrix Transposed matrix */ public function transpose() { $R = new Matrix($this->n, $this->m); for ($i = 0; $i < $this->m; ++$i) { for ($j = 0; $j < $this->n; ++$j) { $R->set($j, $i, $this->A[$i][$j]); } } return $R; }
/** * Create a matrix from an array of doubles. * * @param * sourceMatrix * An array of doubles. */ public static function matrixFromDoubles(array $sourceMatrix) { $out = new Matrix(count($sourceMatrix), count($sourceMatrix[0])); for ($r = 0; $r < $out->getRows(); ++$r) { for ($c = 0; $c < $out->getCols(); ++$c) { $out->set($r, $c, $sourceMatrix[$r][$c]); } } return $out; }
/** * Assembles Q using the single givens rotations. * * @return matrix Q */ public function getQ() { // Q is an mxm matrix if m is the maximum of the number of rows and thenumber of columns. $m = max($this->_matrix->columns(), $this->_matrix->rows()); $Q = new Matrix($m, $m); $Q->setAll(0.0); // Begin with the identity matrix. for ($i = 0; $i < $Q->rows(); $i++) { $Q->set($i, $i, 1.0); } for ($j = $this->_matrix->columns() - 1; $j >= 0; $j--) { for ($i = $this->_matrix->rows() - 1; $i > $j; $i--) { // Get c and s which are stored in the i-th row, j-th column. $aij = $this->_matrix->get($i, $j); $c = 0; $s = 0; if ($aij == 0) { $c = 0.0; $s = 1.0; } else { if (abs($aij) < 1) { $s = 2.0 * abs($aij); $c = sqrt(1 - pow($s, 2)); if ($aij < 0) { $c = -$c; } } else { $c = 2.0 / $aij; $s = sqrt(1 - pow($c, 2)); } } for ($k = 0; $k < $this->_matrix->columns(); $k++) { $jk = $Q->get($j, $k); $ik = $Q->get($i, $k); $Q->set($j, $k, $c * $jk - $s * $ik); $Q->set($i, $k, $s * $jk + $c * $ik); } } } return $Q; }
/** * Get D - the diagonal matrix. * * @return matrix D */ public function getD() { $D = new Matrix($this->_matrix->rows(), $this->_matrix->columns()); for ($i = 0; $i < $D->rows(); $i++) { $D->set($i, $i, $this->_matrix->get($i, $i)); } return $D; }
/** * Assembles Q using the single givens rotations. * * @return matrix Q */ public function getQ() { // Q is an m x m matrix if m is the maximum of the number of rows and thenumber of columns. $m = max($this->_matrix->columns(), $this->_matrix->rows()); $Q = new Matrix($m, $m); $Q->setAll(0.0); // Begin with the identity matrix. for ($i = 0; $i < min($Q->rows(), $Q->columns()); $i++) { $Q->set($i, $i, 1.0); } // Got backwards through all householder transformations and apply them on for ($k = $this->_matrix->columns() - 1; $k >= 0; $k--) { for ($j = $k; $j < $Q->columns(); $j++) { // First compute w^T(j) = v^T * Q(j) where Q(j) is the j-th column of Q. $w = $Q->get($k, $j) * 1.0; for ($i = $k + 1; $i < $Q->rows(); $i++) { $w += $this->_matrix->get($i, $k) * $Q->get($i, $j); } // Now : Q(i,j) = Q(i,j) - tau(k)*v(i)*w(j). $Q->set($k, $j, $Q->get($k, $j) - $this->_tau->get($k) * 1.0 * $w); for ($i = $k + 1; $i < $Q->rows(); $i++) { $Q->set($i, $j, $Q->get($i, $j) - $this->_tau->get($k) * $this->_matrix->get($i, $k) * $w); } } } return $Q; }