/** * Constructor: Get the qr decomposition of the given matrix using householder transformations. * The single householder matrizes are stores within the matrix. * * @param matrix matrix to get the composition of */ public function __construct(&$matrix) { new Assertion($matrix instanceof Matrix, 'Given matrix not of class Matrix.'); $this->_tau = new Vector($matrix->columns()); $this->_matrix = $matrix->copy(); for ($j = 0; $j < $this->_matrix->columns(); $j++) { $norm = 0.0; for ($i = $j; $i < $this->_matrix->rows(); $i++) { $norm += pow($this->_matrix->get($i, $j), 2); } $norm = sqrt($norm); $sign = 1.0; if ($this->_matrix->get($j, $j) < 0) { $sign = -1.0; } $v1 = $this->_matrix->get($j, $j) + $sign * $norm; $scalar = 1; for ($i = $j + 1; $i < $this->_matrix->rows(); $i++) { $this->_matrix->set($i, $j, $this->_matrix->get($i, $j) / $v1); $scalar += pow($this->_matrix->get($i, $j), 2); } $this->_tau->set($j, 2.0 / $scalar); $w = new Vector($this->_matrix->columns()); $w->setAll(0.0); // First calculate w = v_j^T * A. for ($i = $j; $i < $this->_matrix->columns(); $i++) { $w->set($i, $this->_matrix->get($j, $i)); for ($k = $j + 1; $k < $this->_matrix->rows(); $k++) { if ($i == $j) { $w->set($i, $w->get($i) + $this->_matrix->get($k, $j) * $this->_matrix->get($k, $i) * $v1); } else { $w->set($i, $w->get($i) + $this->_matrix->get($k, $j) * $this->_matrix->get($k, $i)); } } $this->_matrix->set($j, $i, $this->_matrix->get($j, $i) - $this->_tau->get($j) * $w->get($i)); for ($k = $j + 1; $k < $this->_matrix->rows(); $k++) { if ($i > $j) { $this->_matrix->set($k, $i, $this->_matrix->get($k, $i) - $this->_tau->get($j) * $this->_matrix->get($k, $j) * $w->get($i)); } } } } }
/** * Constructor: Generate cholesky deocmposition of given matrix. * * @param matrix */ public function __construct(&$matrix) { new Assertion($matrix instanceof Matrix, 'Given matrix not of class Matrix.'); new Assertion($matrix->isSquare(), 'Given matrix is not square.'); $this->_matrix = $matrix->copy(); for ($j = 0; $j < $this->_matrix->columns(); $j++) { $d = $this->_matrix->get($j, $j); for ($k = 0; $k < $j; $k++) { $d -= pow($this->_matrix->get($j, $k), 2) * $this->_matrix->get($k, $k); } // Test if symmetric and positive definite can be guaranteed. new Assertion($d > Cholesky::TOLERANCE * (double) $this->_matrix->get($j, $j), 'Symmetric and positive definite can not be guaranteed: ' . $d . ' > ' . Cholesky::TOLERANCE * (double) $this->_matrix->get($j, $j)); $this->_matrix->set($j, $j, $d); for ($i = $j + 1; $i < $this->_matrix->rows(); $i++) { $this->_matrix->set($i, $j, $this->_matrix->get($i, $j)); for ($k = 0; $k < $j; $k++) { $this->_matrix->set($i, $j, $this->_matrix->get($i, $j) - $this->_matrix->get($i, $k) * $this->_matrix->get($k, $k) * $this->_matrix->get($j, $k)); } $this->_matrix->set($i, $j, $this->_matrix->get($i, $j) / (double) $this->_matrix->get($j, $j)); } } }
/** * Constructor: Generate LU decomposition of the matrix. * * @param matrix matrix to get the lu decomposition of * @return vector permutation */ public function __construct(&$matrix) { new Assertion($matrix instanceof Matrix, 'Given matrix not of class Matrix.'); new Assertion($matrix->isSquare(), 'Matrix is not quadratic.'); $this->_permutation = new Vector($matrix->rows()); $this->_matrix = $matrix->copy(); for ($j = 0; $j < $this->_matrix->rows(); $j++) { $pivot = $j; for ($i = $j + 1; $i < $this->_matrix->rows(); $i++) { if (abs($this->_matrix->get($i, $j)) > abs($this->_matrix->get($pivot, $j))) { $pivot = $i; } } $this->_permutation->set($j, $pivot); $this->_matrix->swapRows($j, $pivot); for ($i = $j + 1; $i < $this->_matrix->columns(); $i++) { $this->_matrix->set($i, $j, $this->_matrix->get($i, $j) / $this->_matrix->get($j, $j)); for ($k = $j + 1; $k < $this->_matrix->columns(); $k++) { $this->_matrix->set($i, $k, $this->_matrix->get($i, $k) - $this->_matrix->get($i, $j) * $this->_matrix->get($j, $k)); } } } }
/** * Constructor: Get the qr decomposition of the given matrix using givens rotations. * The single givens rotations are stored within the matrix. * * @param matrix matrix to get the qr decomposition of */ public function __construct(&$matrix) { new Assertion($matrix instanceof Matrix, 'Given matrix not of class Matrix.'); $this->_matrix = $matrix->copy(); // Check in all columns except the n-th one for entries to eliminate. for ($j = 0; $j < $this->_matrix->columns() - 1; $j++) { for ($i = $j + 1; $i < $this->_matrix->rows(); $i++) { // If the entry is zero it can be skipped. if ($this->_matrix->get($i, $j) != 0) { $r = sqrt(pow($this->_matrix->get($j, $j), 2) + pow($this->_matrix->get($i, $j), 2)); if ($this->_matrix->get($i, $j) < 0) { $r = -$r; } $s = $this->_matrix->get($i, $j) / $r; $c = $this->_matrix->get($j, $j) / $r; // Apply the givens rotation: for ($k = $j; $k < $this->_matrix->columns(); $k++) { $jk = $this->_matrix->get($j, $k); $ik = $this->_matrix->get($i, $k); $this->_matrix->set($j, $k, $c * $jk + $s * $ik); $this->_matrix->set($i, $k, -$s * $jk + $c * $ik); } // c and s can be stored in one matrix entry: if ($c == 0) { $this->_matrix->set($i, $j, 1); } else { if (abs($s) < abs($c)) { if ($c < 0) { $this->_matrix->set($i, $j, -0.5 * $s); } else { $this->_matrix->set($i, $j, 0.5 * $s); } } else { $this->_matrix->set($i, $j, 2.0 / $c); } } } } } }