/** * Return LUP-factorization P*A=L*U * * @see http://en.wikipedia.org/wiki/LUP_decomposition * @see Introduction to Algorithms by Thomas H. Cormen and other * @static * @param Matrix $A * @return array($C, $P, $singular, $even) - C = L + U - E, $singular === true for singular matrix, $even - for det */ public static function LUP($A) { if (!Matrix::isMatrix($A)) { throw new InvalidArgumentException('Matrix needed. Given' . gettype($A)); } if (!$A->isSquare()) { throw new InvalidArgumentException("Matrix must be square"); } $size = $A->getRowsCount(); $C = clone $A; $P = array(); for ($i = 0; $i < $size; $i++) { $P[$i] = $i; } $singular = false; $even = true; for ($i = 0; $i < $size; $i++) { //поиск опорного элемента $pivotValue = 0; $pivot = -1; for ($row = $i; $row < $size; $row++) { if (abs($C->getElem($row, $i)) > $pivotValue) { $pivotValue = abs($C->getElem($row, $i)); $pivot = $row; } } if ($pivotValue == 0) { $singular = true; break; } //меняем местами i-ю строку и строку с опорным элементом if ($pivot !== $i) { list($P[$i], $P[$pivot]) = array($P[$pivot], $P[$i]); $C->swapRows($pivot, $i); $even = !$even; } for ($j = $i + 1; $j < $size; $j++) { $temp = $C->getElem($j, $i) / $C->getElem($i, $i); $C->setElem($j, $i, $temp); for ($k = $i + 1; $k < $size; $k++) { $temp = $C->getElem($j, $k) - $C->getElem($j, $i) * $C->getElem($i, $k); $C->setElem($j, $k, $temp); } } } return array($C, $P, $singular, $even); }
public function testIsMatrix() { $matrix = MatrixFactory::identityMatrix(3); $this->assertTrue(Matrix::isMatrix($matrix)); $not_matrix = array(1, 2, 3); $this->assertTrue(!Matrix::isMatrix($not_matrix)); $not_matrix = new stdClass(); $this->assertTrue(!Matrix::isMatrix($not_matrix)); }
/** * Return true if matrices is equals * * @param Matrix $matrix * @param float $eps * @return bool * @throws InvalidArgumentException */ public function equals($matrix, $eps = 0.0) { if (!Matrix::isMatrix($matrix)) { throw new InvalidArgumentException('Matrix needed. Given' . gettype($matrix)); } if ($eps === 0) { return $this->getArray() == $matrix->getArray(); } else { $sub = $this->sub($matrix); return $sub->EuclideanNorm() < $eps; } }