/**
  * Calculates lower triangular matrix L of given symmetric positive definite matrix
  *
  * @param  NumArray $squareMatrix symmetric positive definite matrix
  *
  * @return NumArray
  *
  * @throws InvalidArgumentException   will be thrown, when `$squareMatrix` is not positive definite
  * @throws NoSquareMatrixException    will be thrown, when `$squareMatrix` is not square
  * @throws NoSymmetricMatrixException will be thrown, when `$squareMatrix` is not symmetric
  *
  * @since 1.0.2
  */
 public static function cholesky(NumArray $squareMatrix)
 {
     if (!Helper::isSquareMatrix($squareMatrix)) {
         throw new NoSquareMatrixException(sprintf("Matrix with shape (%s) given, matrix has to be square", implode(', ', $squareMatrix->getShape())));
     }
     $shape = $squareMatrix->getShape();
     $size = $shape[0];
     $aMatrix = clone $squareMatrix;
     $lMatrix = NumPHP::zerosLike($aMatrix);
     for ($k = 0; $k < $size; $k++) {
         $diaElem = $aMatrix->get($k, $k)->getData();
         if ($diaElem <= 0) {
             throw new InvalidArgumentException("Matrix is not positive definite");
         }
         $diaElem = sqrt($diaElem);
         $lMatrix->set($k, $k, $diaElem);
         for ($i = $k + 1; $i < $size; $i++) {
             if ($squareMatrix->get($i, $k) != $squareMatrix->get($k, $i)) {
                 throw new NoSymmetricMatrixException("Matrix is not symmetric");
             }
             $lMatrix->set($i, $k, $aMatrix->get($i, $k)->div($diaElem));
             for ($j = $k + 1; $j <= $i; $j++) {
                 $aMatrix->set($i, $j, $aMatrix->get($i, $j)->sub($lMatrix->get($i, $k)->mult($lMatrix->get($j, $k))));
             }
         }
     }
     return $lMatrix;
 }
Exemple #2
0
 /**
  * Calculates the determinant of a matrix
  *
  * @param mixed $matrix matrix
  *
  * @throws NoSquareMatrixException will be thrown, if given array is no square matrix
  *
  * @api
  * @since 1.0.0
  *
  * @return float
  */
 public static function det($matrix)
 {
     if (!$matrix instanceof NumArray) {
         $matrix = new NumArray($matrix);
     } elseif ($matrix->inCache(self::CACHE_KEY_DETERMINANT)) {
         return $matrix->getCache(self::CACHE_KEY_DETERMINANT);
     }
     if (!Helper::isSquareMatrix($matrix)) {
         throw new NoSquareMatrixException(sprintf("Matrix with shape (%s) given, matrix has to be square", implode(', ', $matrix->getShape())));
     }
     $shape = $matrix->getShape();
     $lud = self::lud($matrix);
     /**
      * Upper triangular matrix
      *
      * @var NumArray $uMatrix
      */
     $uMatrix = $lud[2];
     $det = 1;
     for ($i = 0; $i < $shape[0]; $i++) {
         $det *= $uMatrix->get($i, $i)->getData();
     }
     $matrix->setCache(self::CACHE_KEY_DETERMINANT, $det);
     return $det;
 }
Exemple #3
0
 /**
  * Tests if Helper::isSquareMatrix works with invalid square matrix
  */
 public function testCheckSquareMatrixInvalid()
 {
     $numArray = NumPHP::ones(2, 3);
     $this->assertFalse(Helper::isSquareMatrix($numArray));
 }