Skip to content

Commit

Permalink
Finishing Complex Arithmetic tests
Browse files Browse the repository at this point in the history
Signed-off-by: Jordan LeDoux <jordan.ledoux@gmail.com>
  • Loading branch information
JordanRL committed Oct 25, 2022
1 parent a01fb5d commit a222a02
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 34 deletions.
27 changes: 6 additions & 21 deletions src/Samsara/Fermat/Complex/Types/ComplexNumber.php
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,6 @@ public function asReal(): ImmutableDecimal|ImmutableFraction
* @param string|int|float|Number $value
*
* @return bool
* @throws IncompatibleObjectState
* @throws IntegrityConstraint
* @throws OptionalExit
*/
public function isEqual(string|int|float|Number $value): bool
{
Expand All @@ -171,28 +168,16 @@ public function isEqual(string|int|float|Number $value): bool

if (is_string($value) && !str_contains($value, 'i')) {
return false;
} else {
$value = ComplexNumbers::make(ComplexNumbers::IMMUTABLE_COMPLEX, $value);
}

if ($value instanceof Number && !$value->isComplex()) {
return false;
}

if (!($value instanceof Number)) {
if (is_string($value)) {
try {
$value = static::makeFromString($value);
} catch (IntegrityConstraint) {
return false;
}
} elseif (is_array($value)) {
try {
$value = static::makeFromArray($value);
} catch (IntegrityConstraint) {
return false;
}
} else {
try {
$value = static::makeFromString($value);
} catch (\Exception) {
return false;
}
}
Expand Down Expand Up @@ -303,9 +288,9 @@ public static function makeFromArray(array $number, $scale = null, NumberBase $b
public static function makeFromString(string $expression, $scale = null, NumberBase $base = NumberBase::Ten): static
{
if (str_contains($expression, '+')) {
[$part1, $part2] = explode('+', $expression);
$parts = explode('+', $expression);
} elseif (str_contains($expression, '-')) {
[$part1, $part2] = explode('-', $expression);
$parts = explode('-', $expression);
} else {
throw new IntegrityConstraint(
'To make a complex number from a string, it must have both a real part and a complex part.',
Expand All @@ -314,7 +299,7 @@ public static function makeFromString(string $expression, $scale = null, NumberB
);
}

return static::makeFromArray([$part1, $part2], $scale, $base);
return static::makeFromArray($parts, $scale, $base);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,30 +171,25 @@ protected function helperPowPolar(
/**
* @param ImmutableComplexNumber|ImmutableDecimal|ImmutableFraction $thisNum
* @param ImmutableDecimal $rotation
* @param int $scale
* @return ImmutableDecimal[]
* @throws IntegrityConstraint
*/
protected function helperPowPolarRotate(
ImmutableComplexNumber|ImmutableDecimal|ImmutableFraction $thisNum,
ImmutableDecimal $rotation,
int $scale
ImmutableDecimal $rotation
): array
{
$rho = $thisNum->getDistanceFromOrigin();
$theta = $thisNum->getPolarAngle();

if (!$rho->isEqual(0)) {
$rho = ArithmeticProvider::squareRoot($rho->getAsBaseTenRealNumber(), $scale);
}

$rho = $rho->pow($rotation);
$theta = $theta->multiply($rotation);

$newPolar = new PolarCoordinate($rho, $theta);
$newCartesian = $newPolar->asCartesian();

$newRealPart = $newCartesian->getAxis('x');
$newImaginaryPart = $newCartesian->getAxis('y');
$newImaginaryPart = $newCartesian->getAxis('y')->multiply('1i');
return [$newRealPart, $newImaginaryPart];
}

Expand All @@ -214,13 +209,13 @@ protected function helperRootsPolarRotate(
int $scale
): array
{
$intScale = $scale + 2;
$intScale = $scale + $roots->asInt();

$rho = $thisNum->getDistanceFromOrigin();
$theta = $thisNum->getPolarAngle();

if (!$rho->isEqual(0)) {
$rho = ArithmeticProvider::squareRoot($rho->getAsBaseTenRealNumber(), $intScale);
$rho = $rho->pow((new ImmutableDecimal('1', $intScale))->setMode($this->getMode())->divide(3));
}

$theta = $theta->divide($roots, $intScale);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ public function pow(
[$thatRealPart, $thatImaginaryPart] = self::partSelector($thatNum, $thisNum, 0, $this->getMode(), $internalScale);

if ($thatNum->isReal() && $thatNum->isNatural() && $thatNum->isPositive()) {
[$newRealPart, $newImaginaryPart] = $this->helperPowPolarRotate($thisNum, $thatNum, $scale);
[$newRealPart, $newImaginaryPart] = $this->helperPowPolarRotate($thisNum, $thatNum);
} else {
[$newRealPart, $newImaginaryPart] = $this->helperPowPolar($thatRealPart, $thatImaginaryPart, $internalScale);
}
Expand Down Expand Up @@ -208,7 +208,7 @@ public function sqrt(
* @throws IntegrityConstraint
* @throws OptionalExit
*/
public function nthRoots(int|ImmutableDecimal $root, ?int $scale): array
public function nthRoots(int|ImmutableDecimal $root, ?int $scale = null): array
{

[$thisNum, $root] = $this->translateToObjects($root);
Expand All @@ -226,7 +226,7 @@ public function nthRoots(int|ImmutableDecimal $root, ?int $scale): array
for ($i=0;$root->isGreaterThan($i);$i++) {
[$newRealPart, $newImaginaryPart] = $this->helperRootsPolarRotate($thisNum, $root, $i, $scale);

$roots[] = (new ImmutableComplexNumber($newRealPart, $newImaginaryPart))->setMode($this->getMode());
$roots[] = (new ImmutableComplexNumber($newRealPart, $newImaginaryPart))->setMode($this->getMode())->roundToScale($scale);
}

return $roots;
Expand Down
69 changes: 69 additions & 0 deletions tests/Samsara/Fermat/Complex/Values/ArithmeticAutoTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,8 @@ public function powerImmutableComplexMediumProvider(): array
'IComplex (3+3i)^(0)' => [$a, $zero, '1', ImmutableDecimal::class],
'IComplex (3+3i)^(3i)' => [$a, $threeI, '-0.0348768474-0.088129998i', ImmutableComplexNumber::class],
'IComplex (3i)^(3+3i)' => [$threeI, $a, '-0.0372635883+0.2396692999i', ImmutableComplexNumber::class],
'IComplex (3+3i)^(3)' => [$a, $three, '-54+54i', ImmutableComplexNumber::class],
'IComplex (3)^(3+3i)' => [$three, $a, '-26.6794540328-4.1480998674i', ImmutableComplexNumber::class],
'IComplex (1+0.0000000001i)^(3+3i)' => [$g, $a, '0.9999999997+0.0000000003i', ImmutableComplexNumber::class],
'IComplex (0.0000000001+1i)^(3+3i)' => [$h, $a, '-0.008983291i', ImmutableDecimal::class],
'IComplex (1+0.000000000001i)^(3+3i)' => [$i, $a, '0.999999999997+0.000000000003i', ImmutableComplexNumber::class],
Expand Down Expand Up @@ -688,4 +690,71 @@ public function testSqrtLarge(ComplexNumber|Decimal $a, string $expected, ?strin
}
}



/*
* nthRoot()
*/

public function nthRootImmutableComplexMediumProvider(): array
{
$three = new ImmutableDecimal('3');
$threeI = new ImmutableDecimal('3i');
$negThree = new ImmutableDecimal('-3');
$negThreeI = new ImmutableDecimal('-3i');
$zero = new ImmutableDecimal('0');
$zeroI = new ImmutableDecimal('0i');
$one = new ImmutableDecimal('1');
$oneI = new ImmutableDecimal('1i');
$tenScale = new ImmutableDecimal('0.0000000001');
$tenScaleI = new ImmutableDecimal('0.0000000001i');
$twelveScale = new ImmutableDecimal('0.000000000001');
$twelveScaleI = new ImmutableDecimal('0.000000000001i');

$a = new ImmutableComplexNumber($three, $threeI);
$b = new ImmutableComplexNumber($negThree, $negThreeI);
$c = new ImmutableComplexNumber($three, $negThreeI);
$d = new ImmutableComplexNumber($negThree, $threeI);
$g = new ImmutableComplexNumber($one, $tenScaleI);
$h = new ImmutableComplexNumber($tenScale, $oneI);
$i = new ImmutableComplexNumber($one, $twelveScaleI);
$j = new ImmutableComplexNumber($twelveScale, $oneI);
$k = new ImmutableComplexNumber($one, $zeroI);
$l = new ImmutableComplexNumber($zero, $oneI);

return [
'IComplex (3+3i)^(1/3)' => [
$a,
$three,
[
'1.5637087354+0.4189944928i',
'-1.1447142426+1.1447142426i',
'-0.4189944928-1.5637087354i',
]
],
//'IComplex (-3-3i)^(1/3)' => [$b, $three, '0.7882387605-1.902976706i', ImmutableComplexNumber::class],
//'IComplex (3-3i)^(1/3)' => [$c, $three, '1.902976706-0.7882387605i', ImmutableComplexNumber::class],
// 'IComplex (-3+3i)^(1/3)' => [$d, $three, '0.7882387605+1.902976706i', ImmutableComplexNumber::class],
// 'IComplex (1+0.0000000001i)^(1/3)' => [$g, $three, '1', ImmutableDecimal::class],
// 'IComplex (0.0000000001+1i)^(1/3)' => [$h, $three, '0.7071067812+0.7071067812i', ImmutableComplexNumber::class],
// 'IComplex (1+0.000000000001i)^(1/3)' => [$i, $three, '1', ImmutableDecimal::class],
// 'IComplex (0.000000000001+1i)^(1/3)' => [$j, $three, '0.707106781187+0.707106781186i', ImmutableComplexNumber::class],
// 'IComplex (1+0i)^(1/3)' => [$k, $three, '1', ImmutableDecimal::class],
// 'IComplex (0+1i)^(1/3)' => [$l, $three, '0.7071067812+0.7071067812i', ImmutableComplexNumber::class],
];
}

/**
* @medium
* @dataProvider nthRootImmutableComplexMediumProvider
*/
public function testNthRoots(ComplexNumber $a, ImmutableDecimal $b, array $expected)
{
$answers = $a->nthRoots($b);

foreach ($answers as $i => $answer) {
$this->assertEquals($expected[$i], $answer->getValue());
}
}

}
77 changes: 77 additions & 0 deletions tests/Samsara/Fermat/Complex/Values/ImmutableComplexNumberTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
namespace Samsara\Fermat\Complex\Values;

use PHPUnit\Framework\TestCase;
use Samsara\Exceptions\SystemError\LogicalError\IncompatibleObjectState;
use Samsara\Fermat\Coordinates\Values\PolarCoordinate;
use Samsara\Fermat\Core\Values\ImmutableDecimal;

/**
Expand Down Expand Up @@ -78,4 +80,79 @@ public function testAbsValue()

}

public function testAsPolar()
{

$complex = self::$complexOneTwo;

$this->assertEquals(PolarCoordinate::class, get_class($complex->asPolar()));
$this->assertEquals('2.23606797749979', $complex->asPolar()->getDistanceFromOrigin()->getValue());
$this->assertEquals('1.107148717794', $complex->asPolar()->getPolarAngle()->getValue());

}

public function testGetAsBaseTenRealNumber()
{
$complex = self::$complexOneTwo;

$this->assertEquals('2.23606797749979', $complex->getAsBaseTenRealNumber());
}

public function testIsFunctions()
{
$complex = self::$complexOneTwo;

// isImaginary
$this->assertFalse($complex->isImaginary());

// isEqual
$this->assertFalse($complex->isEqual('1'));
$this->assertFalse($complex->isEqual(new ImmutableDecimal(1)));
$this->assertFalse($complex->isEqual('1+3i'));
$this->assertFalse($complex->isEqual('1+3i+6'));
$this->assertFalse($complex->isEqual('2i'));
$this->assertFalse($complex->isEqual('2i+4i'));
$this->assertTrue($complex->isEqual('1+2i'));
$this->assertTrue($complex->isEqual(self::$complexOneTwo));
}

public function testExceptionInequality1()
{
$complex = self::$complexOneTwo;

$this->expectException(IncompatibleObjectState::class);
$complex->isGreaterThan('1');
}

public function testExceptionInequality2()
{
$complex = self::$complexOneTwo;

$this->expectException(IncompatibleObjectState::class);
$complex->isGreaterThanOrEqualTo('1');
}

public function testExceptionInequality3()
{
$complex = self::$complexOneTwo;

$this->expectException(IncompatibleObjectState::class);
$complex->isLessThan('1');
}

public function testExceptionInequality4()
{
$complex = self::$complexOneTwo;

$this->expectException(IncompatibleObjectState::class);
$complex->isLessThanOrEqualTo('1');
}

public function testAsComplex()
{
$complex = self::$complexOneTwo;

$this->assertEquals(ImmutableComplexNumber::class, get_class($complex->asComplex()));
}

}

0 comments on commit a222a02

Please sign in to comment.