From bebfbafae87a719e8b1d394f6aead5cfb9d66771 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Wed, 4 Sep 2019 20:39:11 +0200 Subject: [PATCH] added metrics. @todo: implement n-dim --- Math/Topology/Metrics2D.php | 261 +++++++++++++++++++++++++++ tests/Math/Topology/Metric2DTest.php | 100 ++++++++++ 2 files changed, 361 insertions(+) create mode 100644 Math/Topology/Metrics2D.php create mode 100644 tests/Math/Topology/Metric2DTest.php diff --git a/Math/Topology/Metrics2D.php b/Math/Topology/Metrics2D.php new file mode 100644 index 000000000..08faa3e9e --- /dev/null +++ b/Math/Topology/Metrics2D.php @@ -0,0 +1,261 @@ + $e2[0]; }); + + $vis = \array_fill(0, $size, false); + $ans = 0; + + for ($i = 0; $i < $size; ++$i) { + if ($vis[$i] || $bPos[$i][1] === $i) { + continue; + } + + $cycleSize = 0; + $j = $i; + + while (!$vis[$j]) { + $vis[$j] = true; + $j = $bPos[$j][1]; + ++$cycleSize; + } + + $ans += $cycleSize - 1; + } + + return $ans; + } +} diff --git a/tests/Math/Topology/Metric2DTest.php b/tests/Math/Topology/Metric2DTest.php new file mode 100644 index 000000000..3171de79b --- /dev/null +++ b/tests/Math/Topology/Metric2DTest.php @@ -0,0 +1,100 @@ + 0, 'y' => 3], ['x' => 7, 'y' => 6]) + ); + } + + public function testEuclidean() : void + { + self::assertEqualsWithDelta( + 7.615773, + Metric2D::euclidean(['x' => 0, 'y' => 3], ['x' => 7, 'y' => 6]), + 0.1 + ); + } + + public function testChebyshev() : void + { + self::assertEquals( + 7.0, + Metric2D::chebyshev(['x' => 0, 'y' => 3], ['x' => 7, 'y' => 6]) + ); + } + + public function testMinkowski() : void + { + self::assertEqualsWithDelta( + 7.179, + Metric2D::minkowski(['x' => 0, 'y' => 3], ['x' => 7, 'y' => 6], 3), + 0.1 + ); + } + + public function testCanberra() : void + { + self::assertEqualsWithDelta( + 1.333, + Metric2D::canberra(['x' => 0, 'y' => 3], ['x' => 7, 'y' => 6]), + 0.1 + ); + } + + public function testBrayCurtis() : void + { + self::assertEqualsWithDelta( + 0.625, + Metric2D::brayCurtis(['x' => 0, 'y' => 3], ['x' => 7, 'y' => 6]), + 0.1 + ); + } + + public function testAngularSeparation() : void + { + self::assertEqualsWithDelta( + 0.6508, + Metric2D::angularSeparation(['x' => 0, 'y' => 3], ['x' => 7, 'y' => 6]), + 0.1 + ); + } + + public function testHammingDistance() : void + { + self::assertEquals( + 3.0, + Metric2D::hammingDistance([1, 1, 1, 1], [0, 1, 0, 0]), + ); + } + + public function testUlam(): void + { + self::assertEquals( + 2, + Metric2D::hammingDistance([3, 6, 4, 8], [4, 6, 8, 3]) + ); + } +}