/**
  * Find the derivative
  *
  * @param NumericMatrix $mA
  * @param IntType $extra The current row to find the next weighted random row from
  *
  * @throws MathMatrixException
  * @throws NotMarkovException
  *
  * @return IntType
  */
 public function derive(NumericMatrix $mA, $extra = null)
 {
     if (!$mA->is('Markov')) {
         throw new NotMarkovException();
     }
     if (!$extra instanceof IntType) {
         throw new MathMatrixException('The extra parameter is not an IntType');
     }
     $this->comp = new Comparator();
     $this->calc = new Calculator();
     $this->zero = TypeFactory::createInt(0);
     return $this->nextWeightedRandom($mA, $extra);
 }
 public function testDecomposeCanSolveLinearEquation()
 {
     //solve
     //x + y + z = 5
     //2x + 3y + 5z = 8
     //4x + 5z = 2
     $mA = new NumericMatrix([[1, 1, 1], [2, 3, 5], [4, 0, 5]]);
     $mB = new NumericMatrix([[5], [8], [2]]);
     $ret = $this->object->decompose($mA, $mB);
     $expected = new NumericMatrix([[3], [4], [-2]]);
     //z
     $this->assertTrue($expected->equality($ret->right, false));
 }
Beispiel #3
0
 /**
  * Find tr(M)
  *
  * @param NumericMatrix $mA
  * @param mixed $extra
  * @return numeric
  *
  * @throws Chippyash/Math/Matrix/Exceptions/UndefinedComputationException
  */
 public function derive(NumericMatrix $mA, $extra = null)
 {
     if ($mA->is('singleitem')) {
         return $mA->get(1, 1);
     }
     $this->assertMatrixIsNotEmpty($mA, 'No trace for empty matrix')->assertMatrixIsSquare($mA, 'No trace for non-square matrix');
     $tr = new FloatType(0);
     $size = $mA->rows();
     $data = $mA->toArray();
     $calc = new Calculator();
     for ($x = 0; $x < $size; $x++) {
         $tr = $calc->add($tr, $data[$x][$x]);
     }
     return $tr;
 }
Beispiel #4
0
 /**
  * Divide a mtix by another
  *
  * @param NumericMatrix $mA First matrix operand - required
  * @param NumericMatrix $extra Second Matrix operand - required
  *
  * @return NumericMatrix
  */
 public function compute(NumericMatrix $mA, $extra = null)
 {
     $this->assertParameterIsMatrix($extra, 'Parameter is not a matrix');
     if ($mA->is('empty')) {
         $mA = $this->createCorrectMatrixType($mA, [1]);
     }
     if ($extra->is('empty')) {
         $extra = $this->createCorrectMatrixType($extra, [1]);
     }
     $this->assertMatrixColumnsAreEqual($mA, $extra)->assertMatrixRowsAreEqual($mA, $extra);
     $fI = new Invert();
     $mI = $fI->transform($extra);
     $mul = new MM();
     return $mul($mA, $mI);
 }
Beispiel #5
0
 /**
  * @inheritDoc
  */
 public function derive(NumericMatrix $mA, $extra = null)
 {
     if ($mA->is('empty')) {
         return TypeFactory::createInt(0);
     }
     if ($mA->is('singleitem')) {
         return $mA->get(1, 1);
     }
     $calc = new Calculator();
     return array_reduce($mA->toArray(), function ($c1, $row) use($calc) {
         return array_reduce($row, function ($carry, $item) use($calc) {
             return $calc->add($item, $carry);
         }, $c1);
     }, TypeFactory::createInt(0));
 }
 /**
  * Construct a complete Matrix with all entries set to a complex number
  * Takes a source matrix or array (which can be incomplete and converts each
  * entry to complex number type, setting a default value if entry does not exist.
  *
  * If a Matrix is supplied as $source, the data is cloned into the ComplexMatrix
  * converting to complex number values, with no further checks, although you
  * may get exceptions thrown if conversion is not possible.
  *
  * If you don't supply a default value, then 0+0i will be used
  *
  * @param Matrix|array $source Array to initialise the matrix with
  * @param ComplexType $normalizeDefault Value to set missing vertices
  *
  */
 public function __construct($source, ComplexType $normalizeDefault = null)
 {
     if (is_null($normalizeDefault)) {
         $ri = RationalTypeFactory::create(0, 1);
         $normalizeDefault = ComplexTypeFactory::create($ri, clone $ri);
     }
     parent::__construct($source, $normalizeDefault);
 }
Beispiel #7
0
 /**
  * Multiply each member of the matrix by single scalar value and return result
  * Boolean values are converted to 0 (false) and 1 (true).  Use the logical
  * computations if required.
  * String values must conform to the requirements of a rational string number
  * i.e. '2/3', else an exception will be thrown
  *
  * @param Matrix $mA First matrix to act on - required
  * @param scalar $extra value to add
  *
  * @return Matrix
  *
  * @throws Chippyash/Matrix/Exceptions/ComputationException
  */
 public function compute(NumericMatrix $mA, $extra = null)
 {
     if ($mA->is('empty')) {
         return $this->createCorrectMatrixType($mA);
     }
     $scalar = $this->createCorrectScalarType($mA, $extra);
     $data = $mA->toArray();
     $lx = $mA->columns();
     $ly = $mA->rows();
     $calc = new Calculator();
     for ($row = 0; $row < $ly; $row++) {
         for ($col = 0; $col < $lx; $col++) {
             $data[$row][$col] = $calc->mul($data[$row][$col], $scalar);
         }
     }
     return $this->createCorrectMatrixType($mA, $data);
 }
 public function testYouCanShiftAnotherMatrixByMultiplyingWithAShiftMatrix()
 {
     $uShift = new ShiftMatrix(new IntType(5), new StringType(ShiftMatrix::SM_TYPE_UPPER), new IntType(IdentityMatrix::IDM_TYPE_INT));
     $mA = new NumericMatrix([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20], [21, 22, 23, 24, 25]]);
     $uTest = new NumericMatrix([[0, 1, 2, 3, 4], [0, 6, 7, 8, 9], [0, 11, 12, 13, 14], [0, 16, 17, 18, 19], [0, 21, 22, 23, 24]]);
     $mB = $mA('Mul\\Matrix', $uShift);
     $this->assertEquals($uTest->setFormatter(new AsciiNumeric())->display(['outputType' => AsciiNumeric::TP_INT]), $mB->setFormatter(new AsciiNumeric())->display(['outputType' => AsciiNumeric::TP_INT]));
     $lShift = new ShiftMatrix(new IntType(5), new StringType(ShiftMatrix::SM_TYPE_LOWER), new IntType(IdentityMatrix::IDM_TYPE_INT));
     $lTest = new NumericMatrix([[2, 3, 4, 5, 0], [7, 8, 9, 10, 0], [12, 13, 14, 15, 0], [17, 18, 19, 20, 0], [22, 23, 24, 25, 0]]);
     $mB = $mA('Mul\\Matrix', $lShift);
     $this->assertEquals($lTest->setFormatter(new AsciiNumeric())->display(['outputType' => AsciiNumeric::TP_INT]), $mB->setFormatter(new AsciiNumeric())->display(['outputType' => AsciiNumeric::TP_INT]));
     $uTest2 = new NumericMatrix([[6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20], [21, 22, 23, 24, 25], [0, 0, 0, 0, 0]]);
     $mB = $uShift('Mul\\Matrix', $mA);
     $this->assertEquals($uTest2->setFormatter(new AsciiNumeric())->display(['outputType' => AsciiNumeric::TP_INT]), $mB->setFormatter(new AsciiNumeric())->display(['outputType' => AsciiNumeric::TP_INT]));
     $lTest2 = new NumericMatrix([[0, 0, 0, 0, 0], [1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20]]);
     $mB = $lShift('Mul\\Matrix', $mA);
     $this->assertEquals($lTest2->setFormatter(new AsciiNumeric())->display(['outputType' => AsciiNumeric::TP_INT]), $mB->setFormatter(new AsciiNumeric())->display(['outputType' => AsciiNumeric::TP_INT]));
 }
 /**
  * @inheritDoc
  */
 public function compute(NumericMatrix $mA, $extra = null)
 {
     $this->assertParameterIsMatrix($extra, 'Parameter is not a matrix');
     if ($mA->is('empty') || $extra->is('empty')) {
         return $this->createCorrectMatrixType($mA, []);
     }
     $this->assertMatrixColumnsAreEqual($mA, $extra)->assertMatrixRowsAreEqual($mA, $extra);
     $data = (new ZMatrix())->create([$mA->rows(), $mA->columns()])->toArray();
     $dA = $mA->toArray();
     $dB = $extra->toArray();
     $cols = $mA->columns();
     $rows = $mA->rows();
     $calc = new Calculator();
     for ($row = 0; $row < $rows; $row++) {
         for ($col = 0; $col < $cols; $col++) {
             $data[$row][$col] = $this->doCompute($dA[$row][$col], $dB[$row][$col], $calc);
         }
     }
     return $this->createCorrectMatrixType($mA, $data);
 }
Beispiel #10
0
 /**
  * Construct a complete Matrix with all entries set to Chippyash/Type
  * Takes a source matrix or array (which can be incomplete and converts each
  * entry to Chippyash/Type), setting a default value if entry does not exist.
  *
  * If a NumericMatrix is supplied as $source, the data is cloned into the Matrix
  * with no further checks.
  *
  * @param NumericMatrix|array $source Array to initialise the matrix with
  * @param mixed $normalizeDefault Value to set missing vertices
  * @throws \Chippyash\Math\Matrix\Exceptions\MathMatrixException
  */
 public function __construct($source, $normalizeDefault = 0)
 {
     if ($source instanceof self) {
         $this->store($source->toArray());
         return;
     }
     if (is_array($source)) {
         if (is_int($normalizeDefault)) {
             $default = TypeFactory::createInt($normalizeDefault);
         } elseif (is_float($normalizeDefault)) {
             $default = RationalTypeFactory::fromFloat($normalizeDefault);
         } elseif (!$normalizeDefault instanceof NumericTypeInterface) {
             throw new MathMatrixException('NumericMatrix expects numeric default value');
         } else {
             $default = $normalizeDefault;
         }
         parent::__construct($source, false, true, $default);
     } else {
         throw new MathMatrixException('NumericMatrix expects NumericMatrix or array as source data');
     }
 }
Beispiel #11
0
 /**
  * ShiftMatrix constructor.
  * 
  * @param IntType $size Number of required rows and columns
  * @param StringType $shiftType SM_TYPE_UPPER|SM_TYPE_LOWER
  * @param IntType|null $identityType Type of identity entries: default == IdentityType::IDM_TYPE_INT
  * 
  */
 public function __construct(IntType $size, StringType $shiftType, IntType $identityType = null)
 {
     $mA = (new Identity())->create([$size()]);
     $new = TypeFactory::createInt(0);
     $fS = new Shift();
     if ($shiftType() == self::SM_TYPE_UPPER) {
         $mB = $fS($mA, [1, $new]);
     }
     if ($shiftType() == self::SM_TYPE_LOWER) {
         $mB = $fS($mA, [-1, $new]);
     }
     parent::__construct($mB);
 }
Beispiel #12
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)));
 }
 /**
  * Construct a complete matrix whose entries are a result of a function
  *
  * The function must accept two parameters
  *  e.g. $function($row, $col) {return $row - $col;}
  *
  * $row and $col are 1 based
  *
  * @param callable $function
  * @param IntType $rows Number of required rows
  * @param IntType $cols Number or required columns
  *
  * @throws \InvalidArgumentException
  */
 public function __construct(callable $function, IntType $rows, IntType $cols)
 {
     if ($rows() < 1) {
         throw new \InvalidArgumentException('$rows must be >= 1');
     }
     if ($cols() < 1) {
         throw new \InvalidArgumentException('$cols must be >= 1');
     }
     $source = array();
     $rc = $rows();
     $cc = $cols();
     for ($r = 0; $r < $rc; $r++) {
         for ($c = 0; $c < $cc; $c++) {
             $source[$r][$c] = $function($r + 1, $c + 1);
         }
     }
     parent::__construct($source);
 }
Beispiel #14
0
 /**
  * Set determinant of original matrix if it is square
  */
 protected function setDeterminant(NumericMatrix $mA)
 {
     if (!$mA->is('square')) {
         //determinant undefined for non square matrix
         $this->set('Det', null);
         return;
     }
     if ($mA->is('empty')) {
         $this->set('Det', $this->createCorrectScalarType($mA, 1));
         return;
     }
     $det = $this->createCorrectScalarType($mA, $this->pivsign);
     $LU = $this->LU->toArray();
     $calc = new Calculator();
     $this->set('Det', function () use($det, $LU, $calc) {
         $c = count($LU);
         for ($j = 0; $j < $c; $j++) {
             $det = $calc->mul($det, $LU[$j][$j]);
         }
         return $det;
     });
 }
 public function testEqualityWithLooseSettingReturnsFalseForDifferentClassAndDifferentContent()
 {
     $mN = new NumericMatrix([[2]]);
     $mR = new RationalMatrix([[12]]);
     $this->assertFalse($mN->equality($mR, false));
 }
Beispiel #16
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);
 }
Beispiel #17
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);
 }
Beispiel #18
0
 /**
  * Return determinant of a 2X2 matrix
  * @link http://en.wikipedia.org/wiki/Matrix_determinant#2.C2.A0.C3.97.C2.A02_matrices
  * [[a, b]
  *  [c, d]]
  * ad - bc
  *
  * @param \Chippyash\Math\Matrix\NumericMatrix $mA
  */
 protected function det2(NumericMatrix $mA)
 {
     $c = $this->calc();
     return $c->sub($c->mul($mA->get(1, 1), $mA->get(2, 2)), $c->mul($mA->get(1, 2), $mA->get(2, 1)));
 }
 /**
  * Construct a complete Matrix with all entries set to a rational number
  * Takes a source matrix or array (which can be incomplete and converts each
  * entry to rational number, setting a default value if entry does not exist.
  *
  * If a Matrix is supplied as $source, the data is cloned into the RationalMatrix
  * converting to rational number values, with no further checks, although you
  * may get exceptions thrown if conversion is not possible.
  *
  * @param Matrix|array $source Array to initialise the matrix with
  * @param mixed $normalizeDefault Value to set missing vertices
  *
  */
 public function __construct($source, $normalizeDefault = 0)
 {
     $default = $this->convertNumberToRational($normalizeDefault);
     parent::__construct($source, $default);
 }