/**
  * Convert if possible a supplied argument to a rational
  *
  * @param int|float|string|NumericTypeInterface $value
  *
  * @return \Chippyash\Math\Matrix\RationalNumber
  *
  * @throws \Chippyash\Matrix\Exceptions\MatrixException
  * @throws \Exception
  */
 protected function convertNumberToRational($value)
 {
     if ($value instanceof NumericTypeInterface) {
         return $value->asRational();
     }
     switch (gettype($value)) {
         case 'integer':
             return RationalTypeFactory::create($value, 1);
         case 'double':
             return RationalTypeFactory::fromFloat($value);
         case 'string':
             try {
                 return RationalTypeFactory::fromString($value);
             } catch (\Exception $e) {
                 try {
                     return ComplexTypeFactory::fromString($value)->asRational();
                 } catch (\Exception $ex) {
                     throw new MatrixException('The string representation of the number is invalid for a rational');
                 }
             }
         case 'NULL':
             return RationalTypeFactory::create(0, 1);
         case 'boolean':
             return RationalTypeFactory::create($value ? 1 : 0, 1);
         default:
             throw new MatrixException('Rational expects int, float, string, Rational or NumericTypeInterface ');
     }
 }
Exemplo n.º 2
0
 public function testIntPowReturnsRationalOrIntOrComplexTypes()
 {
     $base = new IntType(5);
     $exp = new IntType(3);
     $this->assertInstanceOf('\\Chippyash\\Type\\Number\\IntType', $this->object->intPow($base, $exp));
     $this->assertEquals(125, $this->object->intPow($base, $exp)->get());
     $exp2 = new FloatType(3.5);
     $this->assertInstanceOf('\\Chippyash\\Type\\Number\\Rational\\RationalType', $this->object->intPow($base, $exp2));
     $this->assertEquals('332922571/1191100', (string) $this->object->intPow($base, $exp2));
     $exp3 = RationalTypeFactory::fromFloat(3.5);
     $this->assertInstanceOf('\\Chippyash\\Type\\Number\\Rational\\RationalType', $this->object->intPow($base, $exp3));
     $this->assertEquals('332922571/1191100', (string) $this->object->intPow($base, $exp3));
     $base2 = new IntType(4);
     $exp4 = ComplexTypeFactory::fromString('5+3i');
     $pow = $this->object->intPow($base2, $exp4);
     $this->assertInstanceOf('\\Chippyash\\Type\\Number\\Complex\\ComplexType', $pow);
     $this->assertEquals('-778299179/1445876', (string) $pow->r());
     $this->assertEquals('-861158767/988584', (string) $pow->i());
     $exp5 = ComplexTypeFactory::fromString('0+3i');
     $pow = $this->object->intPow($base2, $exp5);
     $this->assertInstanceOf('\\Chippyash\\Type\\Number\\Complex\\ComplexType', $pow);
     $this->assertEquals('-1722722/3277175', (string) $pow->r());
     $this->assertEquals('-20905959/24575389', (string) $pow->i());
     $exp6 = ComplexTypeFactory::fromString('5+0i');
     $pow = $this->object->intPow($base2, $exp6);
     $this->assertInstanceOf('\\Chippyash\\Type\\Number\\Rational\\RationalType', $pow);
     $this->assertEquals(1024, $pow->get());
 }
 public function testPowWithRationalBaseReturnsRationalType()
 {
     $r = RationalTypeFactory::fromFloat(2.5);
     $p = $this->object->pow($r, new IntType(3));
     $this->assertInstanceOf('Chippyash\\Type\\Number\\Rational\\RationalType', $p);
     $this->assertEquals('125/8', (string) $p);
     $p1 = $this->object->pow($r, new FloatType(3.2));
     $this->assertInstanceOf('Chippyash\\Type\\Number\\Rational\\RationalType', $p1);
     $this->assertEquals('9893770810229553/527173799766761', (string) $p1);
 }
Exemplo n.º 4
0
 private function toStrongType(array $values, $expectedType)
 {
     $ns = '\\Chippyash\\Type\\Number\\';
     $class = $ns . $expectedType;
     $ret = [];
     foreach ($values as $r => $row) {
         foreach ($row as $c => $item) {
             if ($expectedType == 'Rational\\RationalType') {
                 $ret[$r][$c] = RationalTypeFactory::fromFloat($item);
             } else {
                 $ret[$r][$c] = new $class($item);
             }
         }
     }
     return $ret;
 }
Exemplo n.º 5
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');
     }
 }
Exemplo n.º 6
0
 /**
  * Create and return a rational number matrix
  * $data elements are either:
  *  - a RationalType
  *  - string representations of rational number
  *  - a PHP float
  *  - a 2 item array representing numerator & denominator e.g. [2,-4] = '-2/4'
  *
  * @param array $data
  *
  * @return \Chippyash\Math\Matrix\RationalMatrix
  *
  * @throws \Chippyash\Math\Matrix\Exceptions\MathMatrixException
  */
 public static function createRational(array $data)
 {
     foreach ($data as &$row) {
         foreach ($row as &$item) {
             if (!$item instanceof RationalType) {
                 if (is_array($item) && count($item) == 2) {
                     $item = RationalTypeFactory::create($item[0], $item[1]);
                 } elseif (is_string($item)) {
                     try {
                         $item = RationalTypeFactory::fromString($item);
                     } catch (\InvalidArgumentException $e) {
                         throw new MathMatrixException('Invalid item type for Rational Matrix');
                     }
                 } elseif (is_float($item)) {
                     $item = RationalTypeFactory::fromFloat($item);
                 } else {
                     throw new MathMatrixException('Invalid item type for Rational Matrix');
                 }
             }
         }
     }
     return new RationalMatrix($data);
 }
Exemplo n.º 7
0
 /**
  * Convert to RationalType
  *
  * @param mixed $original
  *
  * @return \Chippyash\Type\Number\Rational\RationalType|\Chippyash\Type\Number\Rational\GMPRationalType
  *
  * @throws InvalidTypeException
  */
 protected static function convertType($original)
 {
     if ($original instanceof AbstractRationalType) {
         return RationalTypeFactory::create($original->numerator()->get(), $original->denominator()->get());
     }
     if (is_numeric($original)) {
         if (is_int($original)) {
             return RationalTypeFactory::create($original, 1);
         }
         //default - convert to float
         return RationalTypeFactory::fromFloat(floatval($original));
     }
     if ($original instanceof FloatType) {
         return RationalTypeFactory::fromFloat($original());
     }
     if ($original instanceof IntType) {
         return RationalTypeFactory::create($original, 1);
     }
     if (is_string($original)) {
         try {
             return RationalTypeFactory::fromString($original);
         } catch (\InvalidArgumentException $e) {
             throw new InvalidTypeException("{$original} for Complex type construction");
         }
     }
     $type = gettype($original);
     throw new InvalidTypeException("{$type} for Complex type construction");
 }
 /**
  * @runInSeparateProcess
  */
 public function testSetDefaultFromFloatToleranceIsStatic()
 {
     RationalTypeFactory::setDefaultFromFloatTolerance(1.0E-5);
     $this->assertEquals('113/355', (string) RationalTypeFactory::fromFloat(M_1_PI));
     RationalTypeFactory::setDefaultFromFloatTolerance(1.0E-15);
     $this->assertEquals('25510582/80143857', (string) RationalTypeFactory::fromFloat(M_1_PI));
 }
Exemplo n.º 9
0
 /**
  * Return the angle (sometimes known as the argument) of the number
  * when expressed in polar notation
  *
  * The return value is a rational expressing theta as radians
  *
  * @return \Chippyash\Type\Number\Rational\RationalType
  */
 public function theta()
 {
     return RationalTypeFactory::fromFloat(atan2($this->value['imaginary']->asFloatType()->get(), $this->value['real']->asFloatType()->get()));
 }
Exemplo n.º 10
0
 /**
  * Create complex power from natural base and complex exponent
  *
  * @param int|float $base base
  * @param ComplexType $exp exponent
  *
  * @return NI|ComplexType
  */
 private function complexExponent($base, ComplexType $exp)
 {
     if ($exp->isReal()) {
         return $this->rationalPow(RationalTypeFactory::fromFloat($base), $exp->r());
     }
     //do the imaginary part
     //n^bi = cos(b.lg(n)) + i.sin(b.lg(n))
     $b = $exp->i()->get();
     $n = log($base);
     $r = cos($b * $n);
     $i = sin($b * $n);
     //no real part
     if ($exp->r()->get() == 0) {
         return new ComplexType(RationalTypeFactory::fromFloat($r), RationalTypeFactory::fromFloat($i));
     }
     //real and imaginary part
     //n^a+bi = n^a(cos(b.lg(n)) + i.sin(b.lg(n)))
     $na = pow($base, $exp->r()->get());
     $rr = $na * $r;
     $ii = $na * $i;
     return new ComplexType(RationalTypeFactory::fromFloat($rr), RationalTypeFactory::fromFloat($ii));
 }
Exemplo n.º 11
0
 public function mixedMatrices()
 {
     return [[[[1, 2, 3]], TypeFactory::createInt(6)], [[[1], [2], [3]], TypeFactory::createInt(6)], [[[1, 2, 3], [1, 2, 3]], TypeFactory::createInt(12)], [[[1.1, 2, 3], [1, 2.2, 3]], RationalTypeFactory::fromFloat(12.3)], [[[0.5, 0.5]], RationalTypeFactory::create(1)]];
 }
Exemplo n.º 12
0
 public function testMagicInvokeReturnsFloatForRealFloatComplexNumber()
 {
     $c = new ComplexType(RationalTypeFactory::fromFloat(2.5), $this->createRationalType(0));
     $this->assertInternalType('float', $c());
     $this->assertEquals(2.5, $c());
 }
Exemplo n.º 13
0
 protected function toRational(array $dA)
 {
     foreach ($dA as &$row) {
         foreach ($row as &$entry) {
             if ($entry instanceof NumericTypeInterface) {
                 $entry = $entry->asRational();
             } elseif (is_numeric($entry)) {
                 $entry = RationalTypeFactory::fromFloat(floatval($entry));
             } else {
                 $entry = $entry;
             }
         }
     }
     return new Matrix($dA);
 }
Exemplo n.º 14
0
 /**
  * Return number as Rational number.
  * NB, numerator and denominator will be caste as IntTypes
  *
  * @return \Chippyash\Type\Number\Rational\RationalType
  */
 public function asRational()
 {
     return RationalTypeFactory::fromFloat($this->value);
 }
Exemplo n.º 15
0
 /**
  * Compare int and float types
  *
  * @param  NI $a
  * @param  NI $b
  * @return int
  */
 protected function intFloatCompare(NI $a, NI $b)
 {
     return $this->rationalCompare(RationalTypeFactory::fromFloat($a->asFloatType()), RationalTypeFactory::fromFloat($b->asFloatType()));
 }