diff --git a/tests/test_distances.py b/tests/test_distances.py new file mode 100644 index 0000000..e03cc56 --- /dev/null +++ b/tests/test_distances.py @@ -0,0 +1,89 @@ +import pytest +import taichi as ti +import taichi.math as tm +from catsim.tools import ( + euclidean_distance, + manhattan_distance, + chebyshev_distance, + get_distance, +) +from catsim.constants import ( + EUCLIDEAN_DISTANCE, + CHEBYSHEV_DISTANCE, + MANHATTAN_DISTANCE, +) + + +@ti.data_oriented +class TestDistanceFunctions: + @ti.kernel + def get_euclidean(self, p1: tm.vec2, p2: tm.vec2) -> ti.f32: + return euclidean_distance(p1, p2) + + @ti.kernel + def get_manhattan(self, p1: tm.vec2, p2: tm.vec2) -> ti.f32: + return manhattan_distance(p1, p2) + + @ti.kernel + def get_chebyshev(self, p1: tm.vec2, p2: tm.vec2) -> ti.f32: + return chebyshev_distance(p1, p2) + + @ti.kernel + def get_distance_by_type( + self, p1: tm.vec2, p2: tm.vec2, distance_type: ti.i32 + ) -> ti.f32: + return get_distance(p1, p2, distance_type) + + @pytest.mark.parametrize( + "p1, p2, expected", + [ + (tm.vec2(0, 0), tm.vec2(3, 4), 5.0), + (tm.vec2(1, 1), tm.vec2(4, 5), 5.0), + (tm.vec2(-2, -3), tm.vec2(1, 1), 5.0), + (tm.vec2(-1.5, 0), tm.vec2(1.0, 0), 2.5), + (tm.vec2(-1e5, -1e5), tm.vec2(-1e5, -1e5), 0.0), + (tm.vec2(1000, 2000), tm.vec2(3000, 4000), 2828.4271247), + (tm.vec2(1e5, 1e5), tm.vec2(-1e4, -1e6), 1105486.3183232), + ], + ) + def test_euclidean(self, p1, p2, expected): + result = self.get_euclidean(p1, p2) + assert pytest.approx(result, 0.001) == expected + + @pytest.mark.parametrize( + "p1, p2, expected", + [ + (tm.vec2(0, 0), tm.vec2(3, 4), 7.0), + (tm.vec2(-2, -3), tm.vec2(1, 1), 7.0), + (tm.vec2(-5, -10), tm.vec2(-6, -3), 8.0), + (tm.vec2(-1, -2), tm.vec2(5, -7), 11.0), + ], + ) + def test_manhattan(self, p1, p2, expected): + result = self.get_manhattan(p1, p2) + assert pytest.approx(result, 0.001) == expected + + @pytest.mark.parametrize( + "p1, p2, expected", + [ + (tm.vec2(0, 0), tm.vec2(3, 4), 4.0), + (tm.vec2(-2, -3), tm.vec2(1, -5), 3.0), + (tm.vec2(-2, -3), tm.vec2(1, -7), 4.0), + (tm.vec2(-5, -10), tm.vec2(-6, -3), 7.0), + ], + ) + def test_chebyshev(self, p1, p2, expected): + result = self.get_chebyshev(p1, p2) + assert pytest.approx(result, 0.001) == expected + + @pytest.mark.parametrize( + "dist_type, p1, p2, expected", + [ + (EUCLIDEAN_DISTANCE, tm.vec2(0, 0), tm.vec2(3, 4), 5.0), + (MANHATTAN_DISTANCE, tm.vec2(0, 0), tm.vec2(3, 4), 7.0), + (CHEBYSHEV_DISTANCE, tm.vec2(0, 0), tm.vec2(3, 4), 4.0), + ], + ) + def test_distance(self, dist_type, p1, p2, expected): + result = self.get_distance_by_type(p1, p2, dist_type) + assert pytest.approx(result, 0.001) == expected diff --git a/tests/test_initialization.py b/tests/test_initialization.py new file mode 100644 index 0000000..f6c459e --- /dev/null +++ b/tests/test_initialization.py @@ -0,0 +1,62 @@ +import taichi as ti +import catsim.cat as cat +from catsim.constants import ( + DISABLE_PROB_INTER, + MOVE_PATTERN_RANDOM_ID, + MOVE_PATTERN_LINE_ID, +) + + +def init_cat_env(move_radius, r0, r1, width, height, move_pattern, prob_inter): + cat.init_cat_env( + move_radius, + r0, + r1, + width, + height, + move_pattern, + prob_inter, + ) + + +def test_init_cat_env(): + cat.init_cat_env( + move_radius=10.5, + r0=2.0, + r1=8.0, + width=100, + height=200, + move_pattern=MOVE_PATTERN_RANDOM_ID, + prob_inter=DISABLE_PROB_INTER, + ) + assert cat._MOVE_RADIUS == 10.5 + assert cat._RADIUS_0 == 2.0 + assert cat._RADIUS_1 == 8.0 + assert cat._PLATE_WIDTH == 100 + assert cat._PLATE_HEIGHT == 200 + assert cat._MOVE_PATTERN == MOVE_PATTERN_RANDOM_ID + assert cat._PROB_INTER == DISABLE_PROB_INTER + + +@ti.kernel +def init_cat(cat_r: ti.f32) -> cat.Cat: + catInstance = cat.Cat() + catInstance.init_cat(cat_r) + return catInstance + + +def test_cat_initialization_with_env(): + cat.init_cat_env( + move_radius=15.0, + r0=5.0, + r1=10.0, + width=50, + height=50, + move_pattern=MOVE_PATTERN_LINE_ID, + prob_inter=DISABLE_PROB_INTER, + ) + catInstance = init_cat(3.0) + assert 0 <= catInstance.point[0] <= cat._PLATE_WIDTH + assert 0 <= catInstance.point[0] <= cat._PLATE_HEIGHT + assert catInstance.radius == 3.0 + assert catInstance.move_pattern == MOVE_PATTERN_LINE_ID diff --git a/tests/test_move.py b/tests/test_move.py index f6e84c4..6581212 100644 --- a/tests/test_move.py +++ b/tests/test_move.py @@ -2,7 +2,7 @@ import taichi as ti import taichi.math as tm -from catsim.tools import move_pattern_line, move_pattern_random +from catsim.tools import move_pattern_line, move_pattern_random, move_pattern_phis @ti.data_oriented @@ -24,6 +24,12 @@ def move_line( ) -> tm.vec2: return move_pattern_line(point, old_point, move_r, plate_w, plate_h) + @ti.kernel + def move_phis( + self, point: tm.vec2, old_point: tm.vec2, plate_w: ti.i32, plate_h: ti.i32 + ) -> tm.vec2: + return move_pattern_phis(point, old_point, plate_w, plate_h) + @pytest.mark.parametrize( "x, y, move_radius", [ @@ -58,3 +64,20 @@ def test_move_radius(self, x: int, y: int, move_radius: int): new_point[0] - point[0] <= move_radius and new_point[1] - point[1] <= move_radius ) + + @pytest.mark.parametrize( + "x, y, old_x, old_y, plate_w, plate_h, expected_x, expected_y", + [ + (10, 10, 5, 5, 100, 100, 15, 15), + (0, 0, 10, 10, 100, 100, 10, 10), + (5, 5, 20, 20, 30, 30, 15, 15), + ], + ) + def test_move_phis( + self, x, y, old_x, old_y, plate_w, plate_h, expected_x, expected_y + ): + point = tm.vec2(x, y) + old_point = tm.vec2(old_x, old_y) + new_point = self.move_phis(point, old_point, plate_w, plate_h) + assert new_point[0] == expected_x + assert new_point[1] == expected_y