Skip to content

Commit

Permalink
Add Chebyshev Distance.
Browse files Browse the repository at this point in the history
  • Loading branch information
markrogoyski committed Mar 2, 2024
1 parent 5d13385 commit cc0d818
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 0 deletions.
31 changes: 31 additions & 0 deletions src/Statistics/Distance.php
Original file line number Diff line number Diff line change
Expand Up @@ -470,4 +470,35 @@ function (float $|pᵢ − qᵢ|, float $|pᵢ| + |qᵢ|) {
$|p| + |q|
));
}

/**
* Chebyshev Distance
* A metric defined on a real coordinate space where the distance between two points
* is the greatest of their differences along any coordinate dimension.
*
* D(x, y) = max(|xᵢ − yᵢ|)
*
* https://en.wikipedia.org/wiki/Chebyshev_distance
*
* @param array<float> $xs
* @param array<float> $ys
*
* @return float
*
* @throws Exception\BadDataException
*/
public static function chebyshev(array $xs, array $ys): float
{
if (\count($xs) !== \count($ys)) {
throw new Exception\BadDataException('xs and ys must have the same number of elements');
}

return \max(\array_map(
function (float $xᵢ, $yᵢ) {
return \abs($xᵢ - $yᵢ);
},
$xs,
$ys
));
}
}
94 changes: 94 additions & 0 deletions tests/Statistics/DistanceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1252,4 +1252,98 @@ public function testCanberraExceptionDifferentNumberElements()
// When
$distance = Distance::canberra($p, $q);
}

/**
* @test chebyshev
* @dataProvider dataProviderForChebyshev
* @param array $x
* @param array $y
* @param float $expected
*/
public function testChebyshev(array $x, array $y, float $expected): void
{
// When
$distance = Distance::chebyshev($x, $y);

// Then
$this->assertEqualsWithDelta($expected, $distance, 0.0001);
}

public function dataProviderForChebyshev(): array
{
return [
[
[0],
[0],
0
],
[
[1],
[1],
0
],
[
[1],
[0],
1
],
[
[0],
[1],
1
],
[
[1, 2],
[2, 4],
2
],
[
[1, 2, 3],
[2, 4, 6],
3
],
[
[0, 3, 4, 5],
[7, 6, 3, -1],
7
],
[
[1, 2, 3, 4],
[-5, -6, 7, 8],
8
],
[
[1, 5, 2, 3, 10],
[4, 15, 20, 5, 5],
18
],
[
[1, 5, 2, 3, 10],
[1, 5, 2, 3, 10],
0
],
[
[4, 15, 20, 5, 5],
[4, 15, 20, 5, 5],
0
],
];
}

/**
* @test chebyshev exception when inputs are different lengths
* @throws Exception\BadDataException
*/
public function testChebyshevExceptionDifferentNumberElements()
{
// Given
$xs = [1, 2, 3];
$ys = [2, 3];

// Then
$this->expectException(Exception\BadDataException::class);

// When
Distance::chebyshev($xs, $ys);
}
}

0 comments on commit cc0d818

Please sign in to comment.