/** * Solves a linear system * * @param NumArray $squareMatrix matrix of size n*n * @param NumArray $numArray vector of size n or matrix of size n*m * * @throws \NumPHP\LinAlg\Exception\SingularMatrixException will be thrown, if * `$squareMatrix` is singular * @throws \NumPHP\LinAlg\Exception\InvalidArgumentException will be thrown, if * linear system of `$squareMatrix` and `$numArray` can not be solved * * @return NumArray * * @since 1.0.0 */ public static function solve(NumArray $squareMatrix, NumArray $numArray) { if (!Helper::isNotSingularMatrix($squareMatrix)) { throw new SingularMatrixException(sprintf("First Argument has to be a not singular square matrix")); } if (!Helper::isVector($numArray) && !Helper::isMatrix($numArray)) { throw new InvalidArgumentException(sprintf("Second argument has to be a vector or a matrix, NumArray with dimension %d given", $numArray->getNDim())); } $shape1 = $squareMatrix->getShape(); $shape2 = $numArray->getShape(); if ($shape1[0] !== $shape2[0]) { throw new InvalidArgumentException(sprintf("Can not solve a linear system with matrix (%s) and matrix (%s)", implode(', ', $shape1), implode(', ', $shape2))); } /** * The result of LinAlg::lud is a array with three NumArrays * * @var NumArray $pMatrix * @var NumArray $lMatrix * @var NumArray $uMatrix */ list($pMatrix, $lMatrix, $uMatrix) = LinAlg::lud($squareMatrix); $yNumArray = self::forwardSubstitution($lMatrix, $pMatrix->getTranspose()->dot($numArray)); $zNumArray = self::backSubstitution($uMatrix, $yNumArray); return $zNumArray; }
/** * Tests if Helper::isNotSingularMatrix works with invalid not singular matrix */ public function testCheckNotSingularMatrixInvalid() { $numArray = NumPHP::identity(4); $numArray->set(2, 2, 0); $this->assertFalse(Helper::isNotSingularMatrix($numArray)); }
/** * Calculates the inverse of a not singular square matrix * * @param mixed $squareMatrix not singular matrix * * @throws SingularMatrixException will be thrown, when `$squareMatrix` is singular * * @api * @since 1.0.0 * * @return NumArray */ public static function inv($squareMatrix) { if (!$squareMatrix instanceof NumArray) { $squareMatrix = new NumArray($squareMatrix); } elseif ($squareMatrix->inCache(self::CACHE_KEY_INVERSE)) { return $squareMatrix->getCache(self::CACHE_KEY_INVERSE); } if (!Helper::isNotSingularMatrix($squareMatrix)) { throw new SingularMatrixException("Matrix is singular"); } $shape = $squareMatrix->getShape(); $inv = self::solve($squareMatrix, NumPHP::identity($shape[0])); $squareMatrix->setCache(self::CACHE_KEY_INVERSE, $inv); return self::inv($squareMatrix); }