123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729 |
- <?php
- namespace MathPHP\Tests\Expression;
- use MathPHP\Expression\Polynomial;
- /**
- * Tests of polynomial axioms
- * These tests don't test specific functions,
- * but rather polynomial axioms which in term make use of multiple functions.
- * If all the polynomial math is implemented properly, these tests should
- * all work out according to the axioms.
- *
- * Axioms tested:
- * - Commutativity
- * - a + b = b + a
- * - ab = bc
- * - Associativity
- * - a + (b + c) = (a + b) + c
- * - a(bc) = (ab)c
- * - Distributed Law
- * - a ✕ (b + c) = a ✕ b + a ✕ c
- * - a + (b ✕ c) = a ✕ c + b ✕ c
- * - Identity
- * - a + 0 = 0 + a = a
- * - a ✕ 0 = 0 ✕ a = 0
- * - Negate
- * - -a = a * -1
- * - Arithmetic
- * - Sum of two polynomials is a polynomial
- * - Product of two polynomials is a polynomial
- * - Derivative of a polynomial is a polynomial
- * - Integral of a polynomial is a polynomial
- */
- class PolynomialAxiomsTest extends \PHPUnit\Framework\TestCase
- {
- /**
- * @test Axiom: a + b = b + a
- * Commutativity of addition.
- * @dataProvider dataProviderForTwoPolynomials
- * @param array $a
- * @param array $b
- * @throws \Exception
- */
- public function testCommutativityOfAddition(array $a, array $b)
- {
- // Given
- $a = new Polynomial($a);
- $b = new Polynomial($b);
- // When
- $a+b = $a->add($b);
- $b+a = $b->add($a);
- // Then
- $this->assertEquals($a+b->getDegree(), $b+a->getDegree());
- $this->assertEquals($a+b->getCoefficients(), $b+a->getCoefficients());
- }
- /**
- * @test Axiom: ab = bc
- * Commutativity of multiplication.
- * @dataProvider dataProviderForTwoPolynomials
- * @param array $a
- * @param array $b
- * @throws \Exception
- */
- public function testCommutativityOfMultiplication(array $a, array $b)
- {
- // Given
- $a = new Polynomial($a);
- $b = new Polynomial($b);
- // When
- $ab = $a->multiply($b);
- $ba = $b->multiply($a);
- // Then
- $this->assertEquals($ab->getDegree(), $ba->getDegree());
- $this->assertEquals($ab->getCoefficients(), $ba->getCoefficients());
- }
- /**
- * @test Axiom: a + (b + c) = (a + b) + c
- * Associativity of addition.
- * @dataProvider dataProviderForThreePolynomials
- * @param array $a
- * @param array $b
- * @param array $c
- * @throws \Exception
- */
- public function testAssociativityOfAddition(array $a, array $b, array $c)
- {
- // Given
- $a = new Polynomial($a);
- $b = new Polynomial($b);
- $c = new Polynomial($c);
- // When
- $a + ⟮b + c⟯ = $a->add($b->add($c));
- $⟮a + b⟯ + c = ($a->add($b))->add($c);
- // Then
- $this->assertEquals($a + ⟮b + c⟯->getDegree(), $⟮a + b⟯ + c->getDegree());
- $this->assertEquals($a + ⟮b + c⟯->getCoefficients(), $⟮a + b⟯ + c->getCoefficients());
- }
- /**
- * @test Axiom: a(bc) = (ab)c
- * Associativity of multiplication.
- * @dataProvider dataProviderForThreePolynomials
- * @param array $a
- * @param array $b
- * @param array $c
- * @throws \Exception
- */
- public function testAssociativityOfMultiplication(array $a, array $b, array $c)
- {
- // Given
- $a = new Polynomial($a);
- $b = new Polynomial($b);
- $c = new Polynomial($c);
- // When
- $a⟮bc⟯ = $a->multiply($b->multiply($c));
- $⟮ab⟯c = ($a->multiply($b))->multiply($c);
- // Then
- $this->assertEquals($a⟮bc⟯->getDegree(), $⟮ab⟯c->getDegree());
- $this->assertEquals($a⟮bc⟯->getCoefficients(), $⟮ab⟯c->getCoefficients());
- }
- /**
- * @test Axiom: a ✕ (b + c) = a ✕ b + a ✕ c
- * Distributive law.
- * @dataProvider dataProviderForThreePolynomials
- * @param array $a
- * @param array $b
- * @param array $c
- * @throws \Exception
- */
- public function testDistributiveLaw1(array $a, array $b, array $c)
- {
- // Given
- $a = new Polynomial($a);
- $b = new Polynomial($b);
- $c = new Polynomial($c);
- // When
- $a⟮b + c⟯ = $a->multiply($b->add($c));
- $⟮ab⟯ + ⟮ac⟯ = ($a->multiply($b))->add($a->multiply($c));
- // Then
- $this->assertEquals($a⟮b + c⟯->getDegree(), $⟮ab⟯ + ⟮ac⟯->getDegree());
- $this->assertEquals($a⟮b + c⟯->getCoefficients(), $⟮ab⟯ + ⟮ac⟯->getCoefficients());
- }
- /**
- * @test Axiom: (a + b) ✕ c = a ✕ c + b ✕ c
- * Distributive law.
- * @dataProvider dataProviderForThreePolynomials
- * @param array $a
- * @param array $b
- * @param array $c
- * @throws \Exception
- */
- public function testDistributiveLaw2(array $a, array $b, array $c)
- {
- // Given
- $a = new Polynomial($a);
- $b = new Polynomial($b);
- $c = new Polynomial($c);
- // When
- $⟮a + b⟯c = ($a->add($b))->multiply($c);
- $⟮ac⟯ + ⟮bc⟯ = ($a->multiply($c))->add($b->multiply($c));
- // Then
- $this->assertEquals($⟮a + b⟯c->getDegree(), $⟮ac⟯ + ⟮bc⟯->getDegree());
- $this->assertEquals($⟮a + b⟯c->getCoefficients(), $⟮ac⟯ + ⟮bc⟯->getCoefficients());
- }
- /**
- * @test Axiom: a + 0 = 0 + a = a
- * Identity of addition.
- * @dataProvider dataProviderForOnePolynomial
- * @param array $a
- * @throws \Exception
- */
- public function testIdentityOfAddition(array $a)
- {
- // Given
- $a = new Polynomial($a);
- $zero = new Polynomial([0]);
- // When
- $a+0 = $a->add($zero);
- $zero+a = $zero->add($a);
- // Then
- $this->assertEquals($a->getDegree(), $a+0->getDegree());
- $this->assertEquals($a->getDegree(), $zero+a->getDegree());
- // And
- $this->assertEquals($a->getCoefficients(), $a+0->getCoefficients());
- $this->assertEquals($a->getCoefficients(), $zero+a->getCoefficients());
- }
- /**
- * @test Axiom: a ✕ 0 = 0 ✕ a = 0
- * Identity of multiplication.
- * @dataProvider dataProviderForOnePolynomial
- * @param array $a
- * @throws \Exception
- */
- public function testIdentityOfMultiplication(array $a)
- {
- // Given
- $a = new Polynomial($a);
- $zero = new Polynomial([0]);
- // When
- $a✕0 = $a->multiply($zero);
- $zero✕a = $zero->multiply($a);
- // Then
- $this->assertEquals($zero->getDegree(), $a✕0->getDegree());
- $this->assertEquals($zero->getDegree(), $zero✕a->getDegree());
- // And
- $this->assertEquals($zero->getCoefficients(), $a✕0->getCoefficients());
- $this->assertEquals($zero->getCoefficients(), $zero✕a->getCoefficients());
- }
- /**
- * @test Axiom: -a = a * -1
- * Negation is the same as multiplying by -1
- * @dataProvider dataProviderForOnePolynomial
- * @param array $a
- * @throws \Exception
- */
- public function testNegateSameAsMultiplyingByNegativeOne(array $a)
- {
- // Given
- $a = new Polynomial($a);
- // When
- $−a = $a->negate();
- $a⟮−1⟯ = $a->multiply(-1);
- // Then
- $this->assertEquals($−a->getDegree(), $a⟮−1⟯->getDegree());
- $this->assertEquals($−a->getCoefficients(), $a⟮−1⟯->getCoefficients());
- }
- /**
- * @test Axiom: Sum of two polynomials is a polynomial
- * @dataProvider dataProviderForTwoPolynomials
- * @param array $a
- * @param array $b
- * @throws \Exception
- */
- public function testArithmeticAdditionProperty(array $a, array $b)
- {
- // Given
- $a = new Polynomial($a);
- $b = new Polynomial($b);
- // When
- $a+b = $a->add($b);
- // Then
- $this->assertInstanceOf(Polynomial::class, $a+b);
- }
- /**
- * @test Axiom: Product of two polynomials is a polynomial
- * @dataProvider dataProviderForTwoPolynomials
- * @param array $a
- * @param array $b
- * @throws \Exception
- */
- public function testArithmeticMultiplicationProperty(array $a, array $b)
- {
- // Given
- $a = new Polynomial($a);
- $b = new Polynomial($b);
- // When
- $ab = $a->multiply($b);
- // Then
- $this->assertInstanceOf(Polynomial::class, $ab);
- }
- /**
- * @test Axiom: Derivative of a polynomials is a polynomial
- * @dataProvider dataProviderForOnePolynomial
- * @param array $a
- * @throws \Exception
- */
- public function testArithmeticDerivativeProperty(array $a)
- {
- // Given
- $a = new Polynomial($a);
- // When
- $derivative = $a->differentiate();
- // Then
- $this->assertInstanceOf(Polynomial::class, $derivative);
- }
- /**
- * @test Axiom: Integral of a polynomials is a polynomial
- * @dataProvider dataProviderForOnePolynomial
- * @param array $a
- * @throws \Exception
- */
- public function testArithmeteicIntegrationProperty(array $a)
- {
- // Given
- $a = new Polynomial($a);
- // When
- $derivative = $a->integrate();
- // Then
- $this->assertInstanceOf(Polynomial::class, $derivative);
- }
- public function dataProviderForOnePolynomial(): array
- {
- return [
- [
- [0],
- ],
- [
- [1],
- ],
- [
- [2],
- ],
- [
- [8],
- ],
- [
- [1, 5],
- ],
- [
- [4, 0],
- ],
- [
- [0, 3],
- ],
- [
- [12, 4],
- ],
- [
- [1, 2, 3],
- ],
- [
- [2, 3, 4],
- ],
- [
- [1, 1, 1],
- ],
- [
- [5, 3, 6],
- ],
- [
- [2, 7, 4],
- ],
- [
- [6, 0, 3],
- ],
- [
- [4, 5, 2, 6],
- ],
- [
- [3, 5, 2, 10],
- ],
- [
- [-4, 6, 7, -1],
- ],
- [
- [-2, -1, -4, -3],
- ],
- [
- [5, 3, 6],
- ],
- [
- [7, 6, 6],
- ],
- [
- [-6, -1],
- ],
- [
- [-5, -5, -1, 2, 4, 6, 5],
- ],
- [
- [10, 20, 30, 40],
- ],
- [
- [-5, 10, -15, 20, -55],
- ],
- [
- [0, 0, 0, 0, 5],
- ],
- [
- [2, 0, 0, 0, 4],
- ],
- [
- [-1, -2, -3, -4, -5, -6, -7, -8, -9],
- ],
- [
- [1, 2, 3, 4, 5, 6, 7, 8, 9],
- ],
- [
- [4, 54, 23, -34, 12, 73, -34, 2],
- ],
- ];
- }
- public function dataProviderForTwoPolynomials(): array
- {
- return [
- [
- [0],
- [0],
- ],
- [
- [1],
- [1],
- ],
- [
- [0],
- [1],
- ],
- [
- [1],
- [0],
- ],
- [
- [2],
- [2],
- ],
- [
- [1],
- [2],
- ],
- [
- [4],
- [8],
- ],
- [
- [1, 5],
- [5, 4],
- ],
- [
- [4, 0],
- [5, 6],
- ],
- [
- [0, 3],
- [5, 5],
- ],
- [
- [12, 4],
- [5, 10],
- ],
- [
- [1, 2, 3],
- [1, 2, 3],
- ],
- [
- [1, 2, 3],
- [2, 3, 4],
- ],
- [
- [1, 1, 1],
- [2, 2, 2],
- ],
- [
- [5, 3, 6],
- [8, 7, 3],
- ],
- [
- [2, 7, 4],
- [5, 4, 7],
- ],
- [
- [6, 0, 3],
- [1, 1, 2],
- ],
- [
- [4, 5, 2, 6],
- [6, 5, 5, 4],
- ],
- [
- [3, 5, 2, 10],
- [2, -2, 5, 3],
- ],
- [
- [-4, 6, 7, -1],
- [5, 5, -5, -1],
- ],
- [
- [-2, -1, -4, -3],
- [-5, 5, -4, -3],
- ],
- [
- [1],
- [5, 3, 6],
- ],
- [
- [7, 6, 6],
- [3, 2],
- ],
- [
- [-3, 4, 5, 6],
- [-6, -1],
- ],
- [
- [5, 6, 7, 6, 5, 6],
- [-5, -5, -1, 2, 4, 6, 5],
- ],
- [
- [10, 20, 30, 40],
- [-4, 5, 6, -4, 3],
- ],
- [
- [4, 8, 12, 16, 20],
- [-5, 10, -15, 20, -55],
- ],
- [
- [0, 0, 0, 0, 5],
- [4, 3, 6, 7],
- ],
- [
- [2, 0, 0, 0, 4],
- [1, 1, 1, 1, 1],
- ],
- [
- [1, 2, 3, 4, 5, 6, 7, 8, 9],
- [-1, -2, -3, -4, -5, -6, -7, -8, -9],
- ],
- [
- [1, 2, 3, 4, 5, 6, 7, 8, 9],
- [2, 3, 4, 5, 6, 7, 8, 9, 10],
- ],
- [
- [34, 65, 34, 23, 62, 87, 34, 65],
- [4, 54, 23, -34, 12, 73, -34, 2],
- ],
- ];
- }
- public function dataProviderForThreePolynomials(): array
- {
- return [
- [
- [0],
- [0],
- [0],
- ],
- [
- [1],
- [1],
- [1],
- ],
- [
- [0],
- [1],
- [0],
- ],
- [
- [1],
- [0],
- [1],
- ],
- [
- [2],
- [2],
- [2],
- ],
- [
- [1],
- [2],
- [3],
- ],
- [
- [4],
- [8],
- [2],
- ],
- [
- [1, 5],
- [5, 4],
- [4, 3],
- ],
- [
- [4, 0],
- [5, 6],
- [6, 5],
- ],
- [
- [0, 3],
- [5, 5],
- [0, 0],
- ],
- [
- [12, 4],
- [5, 10],
- [2, 10],
- ],
- [
- [1, 2, 3],
- [1, 2, 3],
- [1, 2, 3],
- ],
- [
- [1, 2, 3],
- [2, 3, 4],
- [3, 4, 5],
- ],
- [
- [1, 1, 1],
- [2, 2, 2],
- [3, 3, 3],
- ],
- [
- [5, 3, 6],
- [8, 7, 3],
- [3, 2, 7],
- ],
- [
- [2, 7, 4],
- [5, 4, 7],
- [6, 5, 4],
- ],
- [
- [6, 0, 3],
- [1, 1, 2],
- [2, 3, 0],
- ],
- [
- [4, 5, 2, 6],
- [6, 5, 5, 4],
- [2, 2, 3, 3],
- ],
- [
- [3, 5, 2, 10],
- [2, -2, 5, 3],
- [-1, 3, 4, -1],
- ],
- [
- [-4, 6, 7, -1],
- [5, 5, -5, -1],
- [6, 5, -4, -3],
- ],
- [
- [-2, -1, -4, -3],
- [-5, 5, -4, -3],
- [1, -1, 1, -2],
- ],
- [
- [1],
- [5, 3, 6],
- [3, -2],
- ],
- [
- [7, 6, 6],
- [3, 2],
- [4],
- ],
- [
- [-3, 4, 5, 6],
- [-6, -1],
- [5, 6, 4],
- ],
- [
- [5, 6, 7, 6, 5, 6],
- [-5, -5, -1, 2, 4, 6, 5],
- [5, 5, 5, -6, -6, -4, 3],
- ],
- [
- [10, 20, 30, 40],
- [-4, 5, 6, -4, 3],
- [-3, -3, -2, 1, 5],
- ],
- [
- [4, 8, 12, 16, 20],
- [-5, 10, -15, 20, -55],
- [3, 6, 9, -12, -15],
- ],
- [
- [0, 0, 0, 0, 5],
- [4, 3, 6, 7],
- [6, 0, 0, 0, 0],
- ],
- [
- [2, 0, 0, 0, 4],
- [1, 1, 1, 1, 1],
- [2, 2, 2, -3, -2]
- ],
- [
- [1, 2, 3, 4, 5, 6, 7, 8, 9],
- [-1, -2, -3, -4, -5, -6, -7, -8, -9],
- [4, 3, 5, 6],
- ],
- [
- [1, 2, 3, 4, 5, 6, 7, 8, 9],
- [2, 3, 4, 5, 6, 7, 8, 9, 10],
- [3, 4, 5, 6, 7, 8, 9, 10, 11],
- ],
- [
- [34, 65, 34, 23, 62, 87, 34, 65],
- [4, 54, 23, -34, 12, 73, -34, 2],
- [34, 23, 12, 63, 24, -42, 12, 4],
- ],
- [
- [1, 2, 3, 4, 5, 6],
- [-1, -2, -3, -4, -6],
- [0, 0, 0, 0, 0, 0],
- ],
- ];
- }
- }
|