/** * 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; }
/** * @param InputInterface $input * @param OutputInterface $output * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ protected function execute(InputInterface $input, OutputInterface $output) { $matrixA = new NumArray([[1, 6, 1], [2, 3, 2], [4, 2, 1]]); $output->writeln('<comment>Matrix A:</comment>'); $output->writeln($matrixA->__toString()); $output->writeln('<info>LU decomposition</info>'); $time = microtime(true); list($matrixP, $matrixL, $matrixU) = LinAlg::lud($matrixA); $timeDiff = microtime(true) - $time; $output->writeln('<comment>Matrix P:</comment>'); $output->writeln($matrixP->__toString()); $output->writeln('<comment>Matrix L:</comment>'); $output->writeln($matrixL->__toString()); $output->writeln('<comment>Matrix U:</comment>'); $output->writeln($matrixU->__toString()); $output->writeln('<info>Time for calculation: ' . $timeDiff . ' sec</info>'); }
/** * Tests cache of LinAlg::lud */ public function testLUDecompositionCache() { $numArray = new NumArray(5); $numArray->setCache(LUDecomposition::CACHE_KEY_LU_DECOMPOSITION, 8); $this->assertSame(8, LinAlg::lud($numArray)); }