Exemple #1
0
 /**
  * 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;
 }
 /**
  * Factors a matrix into a pivot matrix, a lower and upper triangular matrix
  *
  * @param NumArray $array matrix
  *
  * @throws NoMatrixException will be thrown, if `array` is no matrix
  *
  * @return array
  *
  * @since 1.0.0
  */
 public static function lud(NumArray $array)
 {
     if (!Helper::isMatrix($array)) {
         throw new NoMatrixException(sprintf("NumArray with dimension %d given, NumArray should have 2 dimensions", $array->getNDim()));
     }
     $numArray = clone $array;
     $shape = $numArray->getShape();
     $mAxis = $shape[0];
     $nAxis = $shape[1];
     $size = min($mAxis, $nAxis);
     $pArray = range(0, $mAxis - 1);
     $lMatrix = NumPHP::zeros($mAxis, $size);
     for ($i = 0; $i < $size; $i++) {
         // pivoting
         $maxIndex = self::getPivotIndex($numArray, $i);
         if ($maxIndex !== $i) {
             $temp = $numArray->get($i);
             $numArray->set($i, $numArray->get($maxIndex));
             $numArray->set($maxIndex, $temp);
             $temp = $lMatrix->get($i);
             $lMatrix->set($i, $lMatrix->get($maxIndex));
             $lMatrix->set($maxIndex, $temp);
             $temp = $pArray[$i];
             $pArray[$i] = $pArray[$maxIndex];
             $pArray[$maxIndex] = $temp;
         }
         // elimination
         for ($j = $i + 1; $j < $mAxis; $j++) {
             $fac = 0;
             $facNumerator = $numArray->get($j, $i)->getData();
             $facDenominator = $numArray->get($i, $i)->getData();
             if ($facDenominator) {
                 $fac = $facNumerator / $facDenominator;
             }
             $lMatrix->set($j, $i, $fac);
             $slice = sprintf("%d:", $i + 1);
             $numArray->set($j, $slice, $numArray->get($j, $slice)->sub($numArray->get($i, $slice)->mult($fac)));
         }
     }
     return [self::buildPivotMatrix($pArray), self::buildLMatrix($lMatrix), self::buildUMatrix($numArray)];
 }
Exemple #3
0
 /**
  * Tests if Helper::isMatrix works with invalid matrix
  */
 public function testCheckMatrixInvalid()
 {
     $numArray = NumPHP::ones(3);
     $this->assertFalse(Helper::isMatrix($numArray));
 }