public function testMagicCallReturnsResultForKnownMethod() { $one = new IntType(1); $c = new Comparator(); //use default engine $this->assertEquals(true, $c->eq($one, $one)); }
/** * Perform Guass Jordan Elimination on the two supplied matrices * * @param NumericMatrix $mA First matrix to act on - required * @param NumericMatrix $extra Second matrix to act upon - required * * @return \Chippyash\Math\Matrix\DecompositionAbstractDecomposition Fluent Interface * * @throws \Chippyash\Math\Matrix\Exceptions\SingularMatrixException */ public function decompose(NumericMatrix $mA, $extra = null) { $this->assertParameterIsMatrix($extra, 'Parameter extra is not a matrix')->assertMatrixIsNumeric($extra, 'Parameter extra is not a numeric matrix')->assertMatrixIsSquare($mA, 'Parameter mA is not a square matrix')->assertMatrixRowsAreEqual($mA, $extra, 'mA->rows != extra->rows'); $rows = $mA->rows(); $dA = $mA->toArray(); $dB = $extra->toArray(); $zero = function () { return RationalTypeFactory::create(0, 1); }; $one = function () { return RationalTypeFactory::create(1, 1); }; $calc = new Calculator(); $comp = new Comparator(); $ipiv = array_fill(0, $rows, $zero()); $indxr = array_fill(0, $rows, 0); $indxc = array_fill(0, $rows, 0); // find the pivot element by searching the entire matrix for its largest value, but excluding columns already reduced. $irow = $icol = 0; for ($i = 0; $i < $rows; $i++) { $big = $zero(); for ($j = 0; $j < $rows; $j++) { if ($comp->neq($ipiv[$j], $one())) { for ($k = 0; $k < $rows; $k++) { if ($comp->eq($ipiv[$k], $zero())) { $absVal = $dA[$j][$k]->abs(); if ($comp->gt($absVal, $big)) { unset($big); $big = clone $absVal; $irow = $j; $icol = $k; } } elseif ($comp->gt($ipiv[$k], $one())) { throw new SingularMatrixException('GaussJordanElimination'); } } } } //Now interchange row to move the pivot element to a diagonal $ipiv[$icol] = $calc->add($ipiv[$icol], $one()); if ($irow != $icol) { $this->swapRows($dA, $irow, $icol); $this->swapRows($dB, $irow, $icol); } // Remember permutations to later $indxr[$i] = $irow; $indxc[$i] = $icol; if ($comp->eq($dA[$icol][$icol], $zero())) { throw new SingularMatrixException('GaussJordanElimination'); } // Now divide the found row to make the pivot element 1 // To maintain arithmetic integrity we use the reciprocal to multiply by $pivinv = $calc->reciprocal($dA[$icol][$icol]); $this->multRow($dA, $icol, $pivinv, $calc); $this->multRow($dB, $icol, $pivinv, $calc); // And reduce all other rows but the pivoted row with the value of the pivot row for ($ll = 0; $ll < $rows; $ll++) { if ($ll != $icol) { $multiplier = clone $dA[$ll][$icol]; $multiplier->negate(); $this->addMultipleOfOtherRowToRow($dA, $multiplier, $icol, $ll, $calc); $this->addMultipleOfOtherRowToRow($dB, $multiplier, $icol, $ll, $calc); } } } $this->set('left', $this->createCorrectMatrixType($mA, $dA)); $this->set('right', $this->createCorrectMatrixType($extra, $dB)); return clone $this; }
/** * Complex Pow - raise number to the exponent * Will return a ComplexType * Exponent must be non complex * * @param ComplexType $a operand * @param NI $exp Exponent * * @return ComplexType * * @throws \InvalidArgumentException If exponent is complex */ public function complexPow(ComplexType $a, NI $exp) { if ($exp instanceof ComplexType) { $comp = new Comparator(); $zero = new IntType(0); $real = 0; $imaginary = 0; if (!($comp->eq($a->r(), $zero) && $comp->eq($a->i(), $zero))) { list($real, $imaginary) = $this->getPowExponentPartsFromPolar($a, $exp); } return new ComplexType(RationalTypeFactory::fromFloat($real), RationalTypeFactory::fromFloat($imaginary)); } //non complex //de moivres theorum //z^n = r^n(cos(n.theta) + sin(n.theta)i) //where z is a complex number, r is the radius $n = $exp(); $nTheta = $n * $a->theta()->get(); $pow = pow($a->modulus()->get(), $n); $real = cos($nTheta) * $pow; $imaginary = sin($nTheta) * $pow; return new ComplexType(RationalTypeFactory::fromFloat($real), RationalTypeFactory::fromFloat($imaginary)); }