def test_line_and_curve(self): # B1([5461/16384, 5462/16384]) and B2([0, 1]) are linearized # and when the segments intersect they produce s = -1/3 < 0. nodes1 = np.asfortranarray([[0.0, 1.5, 3.0], [2.25, -2.25, 2.25]]) s = 8191.0 / 24576.0 nodes2 = np.asfortranarray([[-0.5, 4.0], [1.75, -2.75]]) t = 12287.0 / 36864.0 computed_s, computed_t = self._call_function_under_test( s, nodes1, t, nodes2) utils.almost(self, 1.0 / 3.0, computed_s, 1) utils.almost(self, 1.0 / 3.0, computed_t, 1)
def test_simple_root(self): # B1([4095/8192, 1/2]) and B2([1365/8192, 1366/8192]) are linearized # and when the segments intersect they produce s = 24580/24579 > 1. nodes1 = np.asfortranarray([[0.0, 0.375, 0.75], [0.0, 0.75, 0.375]]) s = 100675585.0 / 201351168.0 nodes2 = np.asfortranarray([[0.25, 0.625, 1.0], [0.5625, 0.1875, 0.9375]]) t = 33558529.0 / 201351168.0 computed_s, computed_t = self._call_function_under_test( s, nodes1, t, nodes2) utils.almost(self, 0.5, computed_s, 1) utils.almost(self, 1.0 / 6.0, computed_t, 4)
def test_both_nonzero(self): # B1([6826/8192, 6827/8192]) and B2([1/2, 4097/8192]) are linearized # and when the segments intersect they produce t = -1/24579 < 0. # The root is a simple root. nodes1 = np.asfortranarray([[0.0, 0.375, 0.75], [0.0, 0.75, 0.375]]) s = 167792639.0 / 201351168.0 nodes2 = np.asfortranarray([[0.25, 0.625, 1.0], [0.5625, 0.1875, 0.9375]]) t = 100675583.0 / 201351168.0 computed_s, computed_t = self._call_function_under_test( s, nodes1, t, nodes2) utils.almost(self, 5.0 / 6.0, computed_s, 2) utils.almost(self, 0.5, computed_t, 1)
def test_double_root(self): # B1([5461/8192, 5462/8192]) and B2([2730/8192, 2731/8192]) are # linearized and the segments are parallel. The curves intersect # at the point B1(2/3) = [1/2, 1/2] = B2(1/3) and they have parallel # tangent vectors B1'(2/3) = [3/4, 0] = B2'(1/3). nodes1 = np.asfortranarray([[0.0, 0.375, 0.75], [0.0, 0.75, 0.375]]) s = 10923.0 / 16384.0 nodes2 = np.asfortranarray([[0.25, 0.625, 1.0], [0.625, 0.25, 1.0]]) t = 5461.0 / 16384.0 computed_s, computed_t = self._call_function_under_test( s, nodes1, t, nodes2) utils.almost(self, 2.0 / 3.0, computed_s, 1) utils.almost(self, 1.0 / 3.0, computed_t, 1)
def test_below_error_ratio(self): # B1([12287/16384, 3/4]) and B2([2457/8192, 2458/8192]) are linearized # and when the segments intersect they produce # s = 33555797/33551701 > 1. nodes1 = np.asfortranarray([[1.0, -1.0, 1.0], [0.0, 0.25, 0.5]]) s = 25163776.0 / 33551701.0 nodes2 = np.asfortranarray([[-0.125, 0.5, 1.125], [-0.28125, 1.28125, -0.28125]]) t = 41228331827.0 / 137427767296.0 evaluate_fn = self._simple_evaluate(nodes1, nodes2) converged, current_s, current_t = self._call_function_under_test( evaluate_fn, s, t) self.assertTrue(converged) self.assertEqual(0.75, current_s) utils.almost(self, 3.0 / 10.0, current_t, 1)
def test_below_error_ratio_dg(self): # B1([2730/8192, 2731/8192]) and B2([2047/4096, 1/2]) are # linearized and when the segments intersect they produce # t = 11/10 > 1. nodes1 = np.asfortranarray([[0.5, 1.25, 2.0], [0.125, -0.25, 0.5]]) nodes2 = np.asfortranarray([[0.5, 1.0, 1.5], [-0.125, 0.125, -0.125]]) # NOTE: These ``s-t`` values come after the simple root case exits # due to linear convergence, having started from # s = 6827 / 20480 and t = 20481 / 40960 and updating 4 times. s = 109227.0 / 327680.0 t = 327681.0 / 655360.0 evaluate_fn = self._double_evaluate(nodes1, nodes2) converged, current_s, current_t = self._call_function_under_test( evaluate_fn, s, t) self.assertTrue(converged) utils.almost(self, 1.0 / 3.0, current_s, 1) utils.almost(self, 0.5, current_t, 1)
def test_nearby_solutions(self): # B1([158/512, 159/512]) and B2([304/1024, 305/1024]) are linearized # and when the segments intersect they produce perfectly valid # s = float.fromhex("0x1.f19b11c66f80cp-7") ~= 0.0152 and # t = float.fromhex("0x1.edecc2b71e352p-1") ~= 0.9647. This causes # a convergence failure even though the curves are not tangent at # the nearby point of intersection. nodes1 = np.asfortranarray( [ [ float.fromhex("0x1.002f11833164ap-1"), float.fromhex("0x1.c516e980c0ce0p-2"), float.fromhex("0x1.89092ee6e6df4p-2"), ], [ float.fromhex("-0x1.32718972d77a1p-1"), float.fromhex("-0x1.5e002a95d165ep-1"), float.fromhex("-0x1.8640e302433dfp-1"), ], ] ) s = float.fromhex("0x1.3c07c66c4719cp-2") nodes2 = np.asfortranarray( [ [ float.fromhex("0x1.fbb8cfd966f05p-2"), float.fromhex("0x1.c6cd0e74ae3ecp-2"), float.fromhex("0x1.8c4a283f3c04dp-2"), ], [ float.fromhex("-0x1.325bc2f4e012cp-1"), float.fromhex("-0x1.614b060a21ebap-1"), float.fromhex("-0x1.8192083f28f11p-1"), ], ] ) t = float.fromhex("0x1.30f6f6615b8f1p-2") computed_s, computed_t = self._call_function_under_test( s, nodes1, t, nodes2 ) known_s = float.fromhex("0x1.3c07c30226a3cp-2") utils.almost(self, known_s, computed_s, 447) known_t = float.fromhex("0x1.30f6f2bdde113p-2") utils.almost(self, known_t, computed_t, 474)