Skip to content

Commit

Permalink
Merge pull request #109 from JordanRL/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
JordanRL committed Jun 30, 2021
2 parents c37debe + 5759faa commit 876446a
Show file tree
Hide file tree
Showing 9 changed files with 770 additions and 47 deletions.
1 change: 0 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
],
"license": "GPL-2.0-or-later",
"require": {
"ircmaxell/random-lib": "^1.1",
"riimu/kit-baseconversion": "^1",
"samsara/common": "^1",
"php-ds/php-ds": "^1.1",
Expand Down
31 changes: 0 additions & 31 deletions src/Samsara/Fermat/Provider/PolyfillProvider.php

This file was deleted.

431 changes: 431 additions & 0 deletions src/Samsara/Fermat/Provider/RandomProvider.php

Large diffs are not rendered by default.

10 changes: 7 additions & 3 deletions src/Samsara/Fermat/Types/Decimal.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ protected function translateValue(string $value)
$this->sign = false;
}

if (strpos($value, '.') !== false) {
if (str_contains($value, '.')) {
if (strpos($value, 'E')) {
[$baseNum, $exp] = explode('E', $value);
[$left, $right] = explode('.', $baseNum);
Expand Down Expand Up @@ -182,7 +182,11 @@ public function getAsBaseTenRealNumber(): string

public function getValue($base = null): string // TODO: Check usages to see if it should be replaced with rawString()
{
$value = $this->convertObject();
if (is_null($base)) {
$value = $this->convertObject();
} else {
$value = $this->convertValue($this->getAsBaseTenRealNumber(), 10, $base);
}

if ($this->isImaginary()) {
$value .= 'i';
Expand Down Expand Up @@ -222,7 +226,7 @@ public function compare($value): int
*/
public function convertToBase($base)
{
return $this->setValue($this->getValue($base), null, $base);
return $this->setValue($this->getValue(10), null, $base);
}

/**
Expand Down
17 changes: 13 additions & 4 deletions src/Samsara/Fermat/Types/NumberCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
use Samsara\Fermat\Provider\Distribution\Exponential;
use Samsara\Fermat\Provider\Distribution\Normal;
use Samsara\Fermat\Provider\Distribution\Poisson;
use Samsara\Fermat\Provider\PolyfillProvider;
use Samsara\Fermat\Provider\RandomProvider;
use Samsara\Fermat\Types\Base\Interfaces\Groups\NumberCollectionInterface;
use Samsara\Fermat\Types\Base\Interfaces\Numbers\DecimalInterface;
use Samsara\Fermat\Types\Base\Interfaces\Numbers\NumberInterface;
use Ds\Vector;
use Samsara\Fermat\Values\Algebra\PolynomialFunction;
Expand Down Expand Up @@ -294,7 +295,7 @@ public function getRandom(): NumberInterface
{
$maxKey = $this->getCollection()->count() - 1;

$key = PolyfillProvider::randomInt(0, $maxKey);
$key = RandomProvider::randomInt(0, $maxKey, RandomProvider::MODE_SPEED)->asInt();

return $this->get($key);
}
Expand All @@ -314,13 +315,21 @@ public function sum(): NumberInterface
}

/**
* @return NumberInterface
* @return DecimalInterface
*/
public function mean(): NumberInterface
public function mean(): DecimalInterface
{
return $this->sum()->divide($this->getCollection()->count());
}

/**
* @return DecimalInterface
*/
public function average(): DecimalInterface
{
return $this->mean();
}

/**
* @return Normal
* @throws IntegrityConstraint|MissingPackage
Expand Down
10 changes: 5 additions & 5 deletions src/Samsara/Fermat/Types/Traits/Decimal/TrigonometryTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -293,9 +293,9 @@ public function sinh($scale = null, $round = true): DecimalInterface

$this->scale = $scale;

$num = Numbers::makeOrDont(Numbers::IMMUTABLE, $this, $scale);
$num = Numbers::makeOrDont(Numbers::IMMUTABLE, $this, $scale+2);

$answer = $num->multiply(2)->exp()->subtract(1)->divide($two->multiply($num->exp()));
$answer = $num->multiply(2)->exp($scale+2)->subtract(1)->divide($two->multiply($num->exp($scale+2)), $scale+2);

if ($round) {
$answer = $answer->roundToScale($scale);
Expand Down Expand Up @@ -354,9 +354,9 @@ public function coth($scale = null, $round = true): DecimalInterface

$scale = $scale ?? $this->getScale();

$num = Numbers::makeOrDont(Numbers::IMMUTABLE, $this, $scale);
$num = Numbers::makeOrDont(Numbers::IMMUTABLE, $this, $scale+2);

$answer = $num->cosh($scale+1, false)->divide($num->sinh($scale+1, false));
$answer = $num->cosh($scale+1, false)->divide($num->sinh($scale+1, false), $scale+2);

if ($round) {
$answer = $answer->roundToScale($scale);
Expand All @@ -376,7 +376,7 @@ public function sech($scale = null, $round = true): DecimalInterface
$one = Numbers::makeOne();
$num = Numbers::makeOrDont(Numbers::IMMUTABLE, $this, $scale);

$answer = $one->divide($num->cosh($scale+1, false));
$answer = $one->divide($num->cosh($scale+2, false), $scale+2);

if ($round) {
$answer = $answer->roundToScale($scale);
Expand Down
8 changes: 5 additions & 3 deletions src/Samsara/Fermat/Values/ImmutableDecimal.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public function continuousModulo($mod): DecimalInterface
* @return ImmutableDecimal
* @throws IntegrityConstraint
*/
protected function setValue(string $value, int $scale = null, int $base = 10)
protected function setValue(string $value, int $scale = null, int $base = null)
{
$imaginary = false;

Expand All @@ -59,11 +59,13 @@ protected function setValue(string $value, int $scale = null, int $base = 10)
$imaginary = true;
}

if ($base !== 10 || $this->getBase() !== 10) {
$base = $base === 10 ? $this->getBase() : $base;
if (!is_null($base) || $this->getBase() !== 10) {
$base = is_null($base) ? $this->getBase() : $base;
$value = $this->convertValue($value, 10, $base);
}

$base = $base ?? 10;

if ($imaginary) {
$value .= 'i';
}
Expand Down
195 changes: 195 additions & 0 deletions tests/Samsara/Fermat/Provider/RandomProviderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
<?php

namespace Samsara\Fermat\Provider;

use PHPUnit\Framework\TestCase;
use Samsara\Fermat\Values\ImmutableDecimal;

/**
* @runTestsInSeparateProcesses
* @preserveGlobalState disabled
*/
class RandomProviderTest extends TestCase
{

/**
* @medium
*/
public function testRandomIntLargeNumbers()
{

$num1 = new ImmutableDecimal(PHP_INT_MAX);
$num2 = $num1->add($num1);

for ($i=0;$i<20;$i++) {
$rand = RandomProvider::randomInt($num1, $num2);
$this->assertTrue($num1->isLessThanOrEqualTo($rand));
$this->assertTrue($num2->isGreaterThanOrEqualTo($rand));
}

}

/**
* @medium
*/
public function testRandomIntSmallNumbers()
{

$num1 = new ImmutableDecimal('0');
$num2 = new ImmutableDecimal('100');

for ($i=0;$i<20;$i++) {
$rand = RandomProvider::randomInt($num1, $num2);
$this->assertTrue($num1->isLessThanOrEqualTo($rand));
$this->assertTrue($num2->isGreaterThanOrEqualTo($rand));
}

$num1 = 0;
$num2 = 100;

for ($i=0;$i<20;$i++) {
$rand = RandomProvider::randomInt($num1, $num2);
$this->assertGreaterThanOrEqual(0, $rand->asInt());
$this->assertLessThanOrEqual(100, $rand->asInt());
}

$num1 = new ImmutableDecimal('0');
$num2 = new ImmutableDecimal('100');

for ($i=0;$i<20;$i++) {
$rand = RandomProvider::randomInt($num1, $num2, RandomProvider::MODE_SPEED);
$this->assertTrue($num1->isLessThanOrEqualTo($rand));
$this->assertTrue($num2->isGreaterThanOrEqualTo($rand));
}

}

public function testRandomIntNegativeNumbers()
{

$num1 = new ImmutableDecimal('-100');
$num2 = new ImmutableDecimal('-50');

for ($i=0;$i<20;$i++) {
$rand = RandomProvider::randomInt($num1, $num2);
$this->assertTrue($num1->isLessThanOrEqualTo($rand));
$this->assertTrue($num2->isGreaterThanOrEqualTo($rand));
}

}

public function testRandomIntPosNegNumbers()
{

$num1 = new ImmutableDecimal('-100');
$num2 = new ImmutableDecimal('100');

for ($i=0;$i<20;$i++) {
$rand = RandomProvider::randomInt($num1, $num2);
$this->assertTrue($num1->isLessThanOrEqualTo($rand));
$this->assertTrue($num2->isGreaterThanOrEqualTo($rand));
}

}

public function testRandomIntEqualInput()
{

$num1 = new ImmutableDecimal('100');
$num2 = new ImmutableDecimal('100');

$this->expectWarning();
$this->expectWarningMessage('Attempted to get a random value for a range of no size, with minimum of 100 and maximum of 100');
$this->assertEquals('100', RandomProvider::randomInt($num1, $num2)->getValue());

}

public function testRandomDecimal()
{

$num1 = new ImmutableDecimal('0');
$num2 = new ImmutableDecimal('1');

for ($i=0;$i<20;$i++) {
$rand = RandomProvider::randomDecimal(3);
$this->assertTrue($num1->isLessThanOrEqualTo($rand));
$this->assertTrue($num2->isGreaterThanOrEqualTo($rand));
}

$num1 = new ImmutableDecimal('0');
$num2 = new ImmutableDecimal('1');

for ($i=0;$i<20;$i++) {
$rand = RandomProvider::randomDecimal(3, RandomProvider::MODE_SPEED);
$this->assertTrue($num1->isLessThanOrEqualTo($rand));
$this->assertTrue($num2->isGreaterThanOrEqualTo($rand));
}

}

public function testRandomRealStraddle()
{

$num1 = new ImmutableDecimal('0.9');
$num2 = new ImmutableDecimal('1.1');

for ($i=0;$i<20;$i++) {
$rand = RandomProvider::randomReal($num1, $num2, 3);
$this->assertTrue($num1->isLessThanOrEqualTo($rand));
$this->assertTrue($num2->isGreaterThanOrEqualTo($rand));
$this->assertLessThanOrEqual(5, strlen($rand->getValue()));
}

$num1 = new ImmutableDecimal('0.9');
$num2 = new ImmutableDecimal('1.1');

for ($i=0;$i<20;$i++) {
$rand = RandomProvider::randomReal($num1, $num2, 8);
$this->assertTrue($num1->isLessThanOrEqualTo($rand));
$this->assertTrue($num2->isGreaterThanOrEqualTo($rand));
$this->assertLessThanOrEqual(10, strlen($rand->getValue()));
}

}

public function testRandomRealBounded()
{

$num1 = new ImmutableDecimal('0.4');
$num2 = new ImmutableDecimal('0.5');

for ($i=0;$i<20;$i++) {
$rand = RandomProvider::randomReal($num1, $num2, 3);
$this->assertTrue($num1->isLessThanOrEqualTo($rand));
$this->assertTrue($num2->isGreaterThanOrEqualTo($rand));
$this->assertLessThanOrEqual(5, strlen($rand->getValue()));
}

$num1 = new ImmutableDecimal('4.04');
$num2 = new ImmutableDecimal('4.05');

for ($i=0;$i<20;$i++) {
$rand = RandomProvider::randomReal($num1, $num2, 8);
$this->assertTrue($num1->isLessThanOrEqualTo($rand));
$this->assertTrue($num2->isGreaterThanOrEqualTo($rand));
$this->assertLessThanOrEqual(10, strlen($rand->getValue()));
}

}

public function testRandomRealRange()
{

$num1 = new ImmutableDecimal('0.4');
$num2 = new ImmutableDecimal('2.6');

for ($i=0;$i<20;$i++) {
$rand = RandomProvider::randomReal($num1, $num2, 3);
$this->assertTrue($num1->isLessThanOrEqualTo($rand));
$this->assertTrue($num2->isGreaterThanOrEqualTo($rand));
$this->assertLessThanOrEqual(5, strlen($rand->getValue()));
}

}

}
Loading

0 comments on commit 876446a

Please sign in to comment.