/** * 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; }
/** * 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; }
/** * Solve system of linear equation using a right hand vector, the lu decomposition and the permutation vector of the lu decomposition. * * @param vector right hand */ public function solve($b) { new Assertion($this->_matrix->rows() == $b->size(), 'Right hand vector does not have correct size.'); $x = $b->copy(); for ($i = 0; $i < $x->size(); $i++) { $x->swapEntries($i, $this->_permutation->get($i)); } // First solve L*y = b. for ($i = 0; $i < $this->_matrix->rows(); $i++) { for ($j = $i - 1; $j >= 0; $j--) { $x->set($i, $x->get($i) - $x->get($j) * $this->_matrix->get($i, $j)); } } // Now solve R*x =y. for ($i = $this->_matrix->rows() - 1; $i >= 0; $i--) { for ($j = $this->_matrix->columns() - 1; $j > $i; $j--) { $x->set($i, $x->get($i) - $x->get($j) * $this->_matrix->get($i, $j)); } $x->set($i, $x->get($i) / $this->_matrix->get($i, $i)); } return $x; }
/** * Add to matrices. * * @param matrix $a * @param matrix $b * @return matrix $a + $b */ public static function add($a, $b) { 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->rows() == $b->rows(), 'Given dimensions are not compatible.'); new Assertion($a->columns() == $b->columns(), 'Given dimensions are not compatible.'); $rows = $a->rows(); $columns = $a->columns(); $matrix = $a->copy(); for ($i = 0; $i < $rows; $i++) { for ($j = 0; $j < $columns; $j++) { $matrix->set($i, $j, $matrix->get($i, $j) + $b->get($i, $j)); } } return $matrix; }