trueskill/tests/Numerics/MatrixTest.php

231 lines
7.6 KiB
PHP
Raw Normal View History

2022-07-05 13:55:47 +00:00
<?php
namespace DNW\Skills\Tests\Numerics;
2010-09-01 12:21:10 +00:00
2022-07-05 13:33:34 +00:00
use DNW\Skills\Numerics\IdentityMatrix;
use DNW\Skills\Numerics\Matrix;
use DNW\Skills\Numerics\SquareMatrix;
use DNW\Skills\Tests\TestCase;
2024-01-16 15:07:14 +00:00
use Exception;
2010-09-01 12:21:10 +00:00
2023-08-04 07:22:05 +00:00
// phpcs:disable PSR2.Methods.FunctionCallSignature,Generic.Functions.FunctionCallArgumentSpacing.TooMuchSpaceAfterComma
2016-05-24 12:06:43 +00:00
class MatrixTest extends TestCase
2010-09-01 12:21:10 +00:00
{
2023-08-01 11:26:38 +00:00
public function testTwoByTwoDeterminant(): void
2010-09-01 12:21:10 +00:00
{
$a = new SquareMatrix(1, 2,
3, 4);
2010-09-01 12:21:10 +00:00
$this->assertEquals(-2, $a->getDeterminant());
$b = new SquareMatrix(3, 4,
5, 6);
2010-09-01 12:21:10 +00:00
$this->assertEquals(-2, $b->getDeterminant());
$c = new SquareMatrix(1, 1,
1, 1);
2010-09-01 12:21:10 +00:00
$this->assertEquals(0, $c->getDeterminant());
$d = new SquareMatrix(12, 15,
17, 21);
2010-09-01 12:21:10 +00:00
$this->assertEquals(12 * 21 - 15 * 17, $d->getDeterminant());
}
2023-08-01 11:26:38 +00:00
public function testThreeByThreeDeterminant(): void
2010-09-01 12:21:10 +00:00
{
$a = new SquareMatrix(1, 2, 3,
4, 5, 6,
7, 8, 9);
2010-09-01 12:21:10 +00:00
$this->assertEquals(0, $a->getDeterminant());
$pi = new SquareMatrix(3, 1, 4,
1, 5, 9,
2, 6, 5);
2010-09-01 12:21:10 +00:00
// Verified against http://www.wolframalpha.com/input/?i=determinant+%7B%7B3%2C1%2C4%7D%2C%7B1%2C5%2C9%7D%2C%7B2%2C6%2C5%7D%7D
$this->assertEquals(-90, $pi->getDeterminant());
}
2023-08-01 11:26:38 +00:00
public function testFourByFourDeterminant(): void
2010-09-01 12:21:10 +00:00
{
2022-07-05 13:55:47 +00:00
$a = new SquareMatrix(1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
13, 14, 15, 16);
2010-09-01 12:21:10 +00:00
$this->assertEquals(0, $a->getDeterminant());
$pi = new SquareMatrix(3, 1, 4, 1,
5, 9, 2, 6,
5, 3, 5, 8,
9, 7, 9, 3);
2010-09-01 12:21:10 +00:00
// Verified against http://www.wolframalpha.com/input/?i=determinant+%7B+%7B3%2C1%2C4%2C1%7D%2C+%7B5%2C9%2C2%2C6%7D%2C+%7B5%2C3%2C5%2C8%7D%2C+%7B9%2C7%2C9%2C3%7D%7D
$this->assertEquals(98, $pi->getDeterminant());
}
2023-08-01 11:26:38 +00:00
public function testEightByEightDeterminant(): void
2010-09-01 12:21:10 +00:00
{
2022-07-05 13:55:47 +00:00
$a = new SquareMatrix(1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32,
33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 32, 44, 45, 46, 47, 48,
49, 50, 51, 52, 53, 54, 55, 56,
57, 58, 59, 60, 61, 62, 63, 64);
2010-09-01 12:21:10 +00:00
$this->assertEquals(0, $a->getDeterminant());
$pi = new SquareMatrix(3, 1, 4, 1, 5, 9, 2, 6,
5, 3, 5, 8, 9, 7, 9, 3,
2, 3, 8, 4, 6, 2, 6, 4,
3, 3, 8, 3, 2, 7, 9, 5,
0, 2, 8, 8, 4, 1, 9, 7,
1, 6, 9, 3, 9, 9, 3, 7,
5, 1, 0, 5, 8, 2, 0, 9,
7, 4, 9, 4, 4, 5, 9, 2);
2010-09-01 12:21:10 +00:00
// Verified against http://www.wolframalpha.com/input/?i=det+%7B%7B3%2C1%2C4%2C1%2C5%2C9%2C2%2C6%7D%2C%7B5%2C3%2C5%2C8%2C9%2C7%2C9%2C3%7D%2C%7B2%2C3%2C8%2C4%2C6%2C2%2C6%2C4%7D%2C%7B3%2C3%2C8%2C3%2C2%2C7%2C9%2C5%7D%2C%7B0%2C2%2C8%2C8%2C4%2C1%2C9%2C7%7D%2C%7B1%2C6%2C9%2C3%2C9%2C9%2C3%2C7%7D%2C%7B5%2C1%2C0%2C5%2C8%2C2%2C0%2C9%7D%2C%7B7%2C4%2C9%2C4%2C4%2C5%2C9%2C2%7D%7D
$this->assertEquals(1378143, $pi->getDeterminant());
}
2010-09-02 02:17:00 +00:00
2023-08-01 11:26:38 +00:00
public function testEquals(): void
2010-09-02 02:17:00 +00:00
{
$a = new SquareMatrix(1, 2,
3, 4);
2010-09-02 02:17:00 +00:00
$b = new SquareMatrix(1, 2,
3, 4);
2010-09-02 02:17:00 +00:00
$this->assertTrue($a->equals($b));
$c = Matrix::fromRowsColumns(2, 3,
1, 2, 3,
4, 5, 6);
2010-09-02 02:17:00 +00:00
$d = Matrix::fromRowsColumns(2, 3,
1, 2, 3,
4, 5, 6);
2010-09-02 02:17:00 +00:00
$this->assertTrue($c->equals($d));
$e = Matrix::fromRowsColumns(3, 2,
1, 4,
2, 5,
3, 6);
2010-09-02 02:17:00 +00:00
$f = $e->getTranspose();
$this->assertTrue($d->equals($f));
// Test rounding (thanks to nsp on GitHub for finding this case)
$g = new SquareMatrix(1, 2.00000000000001,
3, 4);
2010-09-02 02:17:00 +00:00
$h = new SquareMatrix(1, 2,
3, 4);
2010-09-02 02:17:00 +00:00
$this->assertTrue($g->equals($h));
2024-01-16 15:07:14 +00:00
$i = new Matrix(1, 2, [[1,2]]);
$j = new Matrix(2, 1, [[1],[2]]);
$this->assertFalse($i->equals($j));
$k = new Matrix(2, 2, [[1,2],[3,4]]);
$l = new Matrix(2, 2, [[4,3],[2,1]]);
$this->assertFalse($k->equals($l));
2010-09-02 02:17:00 +00:00
}
2023-08-01 11:26:38 +00:00
public function testAdjugate(): void
{
// From Wikipedia: http://en.wikipedia.org/wiki/Adjugate_matrix
$a = new SquareMatrix(1, 2,
3, 4);
2022-07-05 13:55:47 +00:00
$b = new SquareMatrix(4, -2,
-3, 1);
$this->assertTrue($b->equals($a->getAdjugate()));
$c = new SquareMatrix(-3, 2, -5,
-1, 0, -2,
3, -4, 1);
$d = new SquareMatrix(-8, 18, -4,
-5, 12, -1,
2022-07-05 13:55:47 +00:00
4, -6, 2);
$this->assertTrue($d->equals($c->getAdjugate()));
}
2023-08-01 11:26:38 +00:00
public function testInverse(): void
{
// see http://www.mathwords.com/i/inverse_of_a_matrix.htm
$a = new SquareMatrix(4, 3,
3, 2);
$b = new SquareMatrix(-2, 3,
3, -4);
$aInverse = $a->getInverse();
$this->assertTrue($b->equals($aInverse));
$identity2x2 = new IdentityMatrix(2);
$aaInverse = Matrix::multiply($a, $aInverse);
$this->assertTrue($identity2x2->equals($aaInverse));
$c = new SquareMatrix(1, 2, 3,
0, 4, 5,
1, 0, 6);
$cInverse = $c->getInverse();
$d = Matrix::scalarMultiply((1.0 / 22), new SquareMatrix(24, -12, -2,
5, 3, -5,
2022-07-05 13:55:47 +00:00
-4, 2, 4));
$this->assertTrue($d->equals($cInverse));
$identity3x3 = new IdentityMatrix(3);
$ccInverse = Matrix::multiply($c, $cInverse);
$this->assertTrue($identity3x3->equals($ccInverse));
}
2024-01-16 15:07:14 +00:00
public function testErrorDeterminant(): void
{
$this->expectException(Exception::class);
$matrix = new Matrix(2, 3, [[1,2,3],[1,2,3]]);
$matrix->getDeterminant();
}
public function testErrorAdjugate(): void
{
$this->expectException(Exception::class);
$matrix = new Matrix(2, 3, [[1,2,3],[1,2,3]]);
$matrix->getAdjugate();
}
public function testErrorAdd(): void
{
$this->expectException(Exception::class);
$m1 = new Matrix(2, 3, [[1,2,3],[1,2,3]]);
$m2 = new Matrix(1, 1, [[1,1]]);
Matrix::add($m1, $m2);
}
public function testErrorMultiply(): void
{
$this->expectException(Exception::class);
$m1 = new Matrix(2, 3, [[1,2,3],[1,2,3]]);
$m2 = new Matrix(1, 1, [[1,1]]);
Matrix::multiply($m1, $m2);
}
2022-07-05 13:55:47 +00:00
}
2023-08-04 07:22:05 +00:00
// phpcs:enable