Esempio n. 1
0
 /**
  * Compute inverse using determinants method
  * We are expecting a non singular, square matrix (complete, n=m, n>1)
  *
  * @param \Chippyash\Matrix\Matrix $mA
  * @return Matrix
  */
 public function invert(NumericMatrix $mA)
 {
     $rows = $mA->rows();
     $cols = $mA->columns();
     $work = array();
     $fDet = new Det();
     $fCof = new Cofactor();
     for ($row = 0; $row < $rows; $row++) {
         for ($col = 0; $col < $cols; $col++) {
             $t = $fDet($fCof($mA, [$row + 1, $col + 1]));
             if (fmod($row + $col, 2) == 0) {
                 $work[$row][$col] = $t;
             } else {
                 $work[$row][$col] = $t->negate();
             }
             $r = $row + 1;
             $c = $col + 1;
         }
     }
     $fTr = new Transpose();
     $fDiv = new Scalar();
     return $fTr($fDiv($this->createCorrectMatrixType($mA, $work), $fDet($mA)));
 }
Esempio n. 2
0
 /**
  * Compute determinant using a strategy
  *
  * @param \Chippyash\Math\Matrix\NumericMatrix $mA
  * @return numeric
  * @throws UndefinedComputationException
  *
  * @todo put back in LU determinant strategy once figured out what is wrong with it
  */
 protected function getDeterminant(NumericMatrix $mA)
 {
     switch ($this->method) {
         case self::METHOD_AUTO:
             if ($mA->rows() <= self::$luLimit) {
                 $strategy = new Lu();
             } else {
                 throw new UndefinedComputationException('No available strategy found to determine the determinant');
             }
             break;
         case self::METHOD_LAPLACE:
             $strategy = new Laplace();
             break;
         case self::METHOD_LU:
             $strategy = new Lu();
             break;
         default:
             throw new UndefinedComputationException('Unknown determinant computation method');
     }
     return $strategy->determinant($mA);
 }
Esempio n. 3
0
 /**
  * Massage where mA is rectangle
  * @param \Chippyash\Math\Matrix\NumericMatrix $mA
  * @param \Chippyash\Math\Matrix\NumericMatrix $mB
  * @param array $product
  * @return \Chippyash\Math\Matrix\NumericMatrix
  */
 protected function massageRectangle(NumericMatrix $mA, NumericMatrix $mB, array $product)
 {
     if ($mB->is('rectangle') && $mA->rows() < $mB->rows()) {
         return $this->createCorrectMatrixType($mA, [[$product[0][0], $product[0][1]], [$product[1][0], $product[1][1]]]);
     }
     return $this->createCorrectMatrixType($mA, $product);
 }
Esempio n. 4
0
 /**
  * Recursive determinant function
  *
  * @param \Chippyash\Math\Matrix\NumericMatrix $mA
  * @return \Chippyash\Type\Interfaces\NumericTypeInterface
  */
 protected function det(NumericMatrix $mA)
 {
     $rowCount = $mA->rows();
     if ($rowCount == 0) {
         return $this->createCorrectScalarType($mA, 1);
     }
     if ($rowCount == 1) {
         return $mA->get(1, 1);
     }
     $possAnswer = $this->checkInCache($mA);
     if ($possAnswer !== false) {
         return $possAnswer;
     }
     if ($rowCount == 2) {
         //2X2 matrix
         $det = $this->det2($mA);
     } else {
         //nXn matrix
         $det = $this->detN($mA);
     }
     $this->storeInCache($mA, $det);
     return $det;
 }
Esempio n. 5
0
 /**
  * Set upper triangular factor.
  */
 protected function setUpperProduct(NumericMatrix $mA)
 {
     $n = $this->LU->columns();
     $LU = $this->LU->toArray();
     $rcFactor = $this->cols - $this->rows;
     $this->set('U', function () use($n, $LU, $rcFactor, $mA) {
         $U = [];
         for ($i = 0; $i < $n; $i++) {
             for ($j = 0; $j < $n; $j++) {
                 if ($i <= $j) {
                     $U[$i][$j] = isset($LU[$i][$j]) ? $LU[$i][$j] : $this->createCorrectScalarType($mA, 0);
                 } else {
                     $U[$i][$j] = $this->createCorrectScalarType($mA, 0);
                 }
             }
         }
         //remove extra rows for non square matrices
         if ($rcFactor > 0) {
             $mUU = new NumericMatrix($U);
             return $this->createCorrectMatrixType($mA, $mUU('Rowslice', array(1, $mUU->rows() - $rcFactor))->toArray());
         } else {
             return $this->createCorrectMatrixType($mA, $U);
         }
     });
 }