Skip to content

Commit

Permalink
Adding test case that requires more than default number of MAX_CANDID…
Browse files Browse the repository at this point in the history
…ATES.

Also updating all "hardcoded" references to 64 (in `.f90` files)
to now refer to `MAX_CANDIDATES`.
  • Loading branch information
dhermes committed Jan 22, 2018
1 parent 60d6122 commit 0dc310e
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 12 deletions.
16 changes: 8 additions & 8 deletions src/bezier/curve_intersection.f90
Expand Up @@ -823,13 +823,13 @@ subroutine all_intersections( &
! a C compatible interface is exposed as ``all_intersections_abi``.

! Possible error states:
! * Status_SUCCESS : On success.
! * Status_PARALLEL : Via ``intersect_one_round()``.
! * Status_WIGGLE_FAIL: Via ``intersect_one_round()``.
! * Status_NO_CONVERGE: If the curves don't converge to linear after
! ``MAX_INTERSECT_SUBDIVISIONS``.
! * (N >= 64) : The number of candidates if it exceeds the limit
! ``MAX_CANDIDATES == 64``.
! * Status_SUCCESS : On success.
! * Status_PARALLEL : Via ``intersect_one_round()``.
! * Status_WIGGLE_FAIL : Via ``intersect_one_round()``.
! * Status_NO_CONVERGE : If the curves don't converge to linear after
! ``MAX_INTERSECT_SUBDIVISIONS``.
! * (N >= MAX_CANDIDATES): The number of candidates if it exceeds the limit
! ``MAX_CANDIDATES`` (64 is the default).

integer(c_int), intent(in) :: num_nodes_first
real(c_double), intent(in) :: nodes_first(num_nodes_first, 2)
Expand Down Expand Up @@ -926,7 +926,7 @@ subroutine all_intersections_abi( &
! * Status_NO_CONVERGE : Via ``all_intersections()``.
! * Status_INSUFFICIENT_SPACE: If ``intersections_size`` is smaller than
! the number of intersections.
! * (N >= 64) : Via ``all_intersections()``.
! * (N >= MAX_CANDIDATES) : Via ``all_intersections()``.

integer(c_int), intent(in) :: num_nodes_first
real(c_double), intent(in) :: nodes_first(num_nodes_first, 2)
Expand Down
6 changes: 3 additions & 3 deletions src/bezier/surface_intersection.f90
Expand Up @@ -795,7 +795,7 @@ subroutine surfaces_intersection_points( &
! * Status_PARALLEL : Via ``curve_intersection.all_intersections()``.
! * Status_WIGGLE_FAIL : Via ``curve_intersection.all_intersections()``.
! * Status_NO_CONVERGE : Via ``curve_intersection.all_intersections()``.
! * (N >= 64) : Via ``curve_intersection.all_intersections()``.
! * (N >= MAX_CANDIDATES): Via ``curve_intersection.all_intersections()``.
! * Status_EDGE_END : Via ``add_st_vals()``.
! * Status_BAD_TANGENT : Via ``add_st_vals()``.
! * Status_SAME_CURVATURE: Via ``add_st_vals()``.
Expand Down Expand Up @@ -1345,7 +1345,7 @@ subroutine surfaces_intersect( &
! * Status_PARALLEL : Via ``surfaces_intersection_points()``.
! * Status_WIGGLE_FAIL : Via ``surfaces_intersection_points()``.
! * Status_NO_CONVERGE : Via ``surfaces_intersection_points()``.
! * (N >= 64) : Via ``surfaces_intersection_points()``.
! * (N >= MAX_CANDIDATES): Via ``surfaces_intersection_points()``.
! * Status_EDGE_END : Via ``surfaces_intersection_points()``.
! * Status_BAD_TANGENT : Via ``surfaces_intersection_points()``.
! * Status_SAME_CURVATURE: Via ``surfaces_intersection_points()``.
Expand Down Expand Up @@ -1448,7 +1448,7 @@ subroutine surfaces_intersect_abi( &
! * Status_PARALLEL : Via ``surfaces_intersect()``.
! * Status_WIGGLE_FAIL : Via ``surfaces_intersect()``.
! * Status_NO_CONVERGE : Via ``surfaces_intersect()``.
! * (N >= 64) : Via ``surfaces_intersect()``.
! * (N >= MAX_CANDIDATES) : Via ``surfaces_intersect()``.
! * Status_EDGE_END : Via ``surfaces_intersect()``.
! * Status_BAD_TANGENT : Via ``surfaces_intersect()``.
! * Status_SAME_CURVATURE : Via ``surfaces_intersect()``.
Expand Down
63 changes: 62 additions & 1 deletion tests/unit/test__geometric_intersection.py
Expand Up @@ -1222,7 +1222,7 @@ def test_workspace_too_small(self):
self.assertEqual(self.workspace_size(), 2)


class Test__set_max_candidates(unittest.TestCase):
class Test__set_max_candidates(utils.NumPyTestCase):
# NOTE: This is also a test for ``_get_max_candidates``.

@staticmethod
Expand All @@ -1248,6 +1248,61 @@ def test_it(self):
# Put things back the way they were.
self._call_function_under_test(curr_candidates)

@staticmethod
def intersect(nodes1, nodes2):
from bezier import _geometric_intersection

return _geometric_intersection._all_intersections(nodes1, nodes2)

def test_on_intersection(self):
from bezier import _geometric_intersection

template = _geometric_intersection._TOO_MANY_TEMPLATE
# B1(s) = [s(2s - 1), s(3 - 2s)]
# f1(x, y) = 4(x^2 + 2xy - 3x + y^2 - y)
nodes1 = np.asfortranarray([
[0.0, 0.0],
[-0.5, 1.5],
[1.0, 1.0],
])
# B2(s) = [(1 - 2s)(s - 1), 2s^2 - s + 1]
# f2(x, y) = 4(x^2 + 2xy - x + y^2 - 3y + 2)
nodes2 = np.asfortranarray([
[-1.0, 1.0],
[0.5, 0.5],
[0.0, 2.0],
])

curr_candidates = self.get_max_candidates()
self.assertEqual(curr_candidates, 64)

# First, show failure with the default.
with self.assertRaises(NotImplementedError) as exc_info:
self.intersect(nodes1, nodes2)
self.assertEqual(exc_info.exception.args, (template.format(88),))

# Then, show failure with twice the limit.
self._call_function_under_test(128)
with self.assertRaises(NotImplementedError) as exc_info:
self.intersect(nodes1, nodes2)
self.assertEqual(exc_info.exception.args, (template.format(184),))

# Then, show failure with (almost) four times the limit.
self._call_function_under_test(255)
with self.assertRaises(NotImplementedError) as exc_info:
self.intersect(nodes1, nodes2)
self.assertEqual(exc_info.exception.args, (template.format(256),))

# Then, show success.
self._call_function_under_test(256)
result = self.intersect(nodes1, nodes2)
# f2(*B1(s)) = 8(2s - 1)^2
# f1(*B2(t)) = 8(2t - 1)^2
self.assertEqual(result, np.asfortranarray([[0.5, 0.5]]))

# Put things back the way they were.
self._call_function_under_test(curr_candidates)


@utils.needs_curve_intersection_speedup
class Test_speedup_set_max_candidates(Test__set_max_candidates):
Expand All @@ -1265,6 +1320,12 @@ def get_max_candidates():

return _curve_intersection_speedup.get_max_candidates()

@staticmethod
def intersect(nodes1, nodes2):
from bezier import _curve_intersection_speedup

return _curve_intersection_speedup.all_intersections(nodes1, nodes2)


class Test__set_similar_ulps(unittest.TestCase):
# NOTE: This is also a test for ``_get_similar_ulps``.
Expand Down

0 comments on commit 0dc310e

Please sign in to comment.