def test_fit_pwl_points_raises_when_min_slope_exceeds_max_slope(self): np.random.seed(48440) x = np.sort(np.random.uniform(size=3)) y = -np.sort(np.random.normal(size=3)) w = np.random.uniform(size=3) with self.assertRaises(ValueError): fitter.fit_pwl_points(x, x, y, w, 3, min_slope=1, max_slope=-1)
def test_fit_pwl_points_raises_when_requiring_too_many_x_knots(self): np.random.seed(48440) x = np.sort(np.random.uniform(size=100)) y = -np.sort(np.random.normal(size=100)) w = np.random.uniform(size=100) # For 3 segments, we can require up to 4 knots. fitter.fit_pwl_points(x, x, y, w, 3, required_x_knots=x[[0, 1, 2, 3]]) with self.assertRaises(ValueError): fitter.fit_pwl_points(x, x, y, w, 3, required_x_knots=x[[0, 1, 2, 3, 4]])
def test_fit_pwl_points_ignores_extra_segments(self): # A curve can optimally fit the sample with one knot per sample point. Any # additional knots would be wasted, so fit_pwl_points shouldn't generate # them. np.random.seed(48440) x = np.sort(np.random.uniform(size=3)) y = np.random.normal(size=3) w = np.random.uniform(size=3) np.testing.assert_array_equal( fitter.fit_pwl_points(x, x, y, w, num_segments=2), fitter.fit_pwl_points(x, x, y, w, num_segments=3))
def test_fit_pwl_points_required_x_knots(self): x = np.arange(51, dtype=float) y = pwlcurve.PWLCurve([(0, 0), (25, 25), (50, 0)]).eval(x) w = np.ones_like(x) # Optimal knots don't change the fit. self.assertEqual( fitter.fit_pwl_points(x, x, y, w, 2, required_x_knots=[0, 25]), fitter.fit_pwl_points(x, x, y, w, 2)) # Suboptimal knots do change the fit. self.assert_notallclose( fitter.fit_pwl_points(x, x, y, w, 2, required_x_knots=[5]), fitter.fit_pwl_points(x, x, y, w, 2))
def test_fit_pwl_points_non_mono_two_segment(self): x = np.arange(51, dtype=float) y = pwlcurve.PWLCurve([(0, 0), (25, 25), (50, 0)]).eval(x) w = np.ones_like(x) curve_xs, curve_ys = fitter.fit_pwl_points(x, x, y, w, 2) self.assert_allclose(curve_xs, [0, 25, 50]) self.assert_allclose(curve_ys, [0, 25, 0])
def test_fit_pwl_points_required_x_knots_appear_in_solution(self): np.random.seed(48440) x = np.sort(np.random.uniform(size=100)) y = -np.sort(np.random.normal(size=100)) w = np.random.uniform(size=100) for num_required_x_knots in range(5): required_x_knots = np.random.uniform(size=num_required_x_knots) x_pnts, _ = fitter.fit_pwl_points( x, x, y, w, 3, required_x_knots=required_x_knots) self.assertContainsSubset(required_x_knots, x_pnts)
def test_fit_pwl_points_mono_with_extra_segments(self): # Monotonicity constraints should hold even when fit_pwl_points is asked for # more segments than necessary. np.random.seed(48440) x = np.sort(np.random.uniform(size=3)) y = -np.sort(np.random.normal(size=3)) w = np.random.uniform(size=3) # Fit mono-decreasing data with mono-increasing constraints. That way, we'll # know if fit_pwl_points ignores the constraints. _, y_pnts = fitter.fit_pwl_points(x, x, y, w, num_segments=3, min_slope=0) self.assert_increasing(y_pnts)
def test_fit_pwl_points_returns_mean_when_one_knot(self): # A proper PWLCurve requires two knots. When given only one knot candidate, # fit_pwl_points should return a constant mean(y) PWLCurve. np.random.seed(48440) x_knots = np.array([.4]) x = np.sort(np.random.uniform(size=100)) y = x**2 + np.random.normal(scale=.1, size=100) w = np.random.uniform(size=100) _, y_points = fitter.fit_pwl_points(x_knots, x, y, w, num_segments=2) y_mean = np.average(y, weights=w) # y_points should all be y.mean(). np.testing.assert_array_equal(y_mean * np.ones_like(y_points), y_points)
def test_fit_pwl_points_required_x_knots_handles_empty_cases(self): np.random.seed(48440) x = np.sort(np.random.uniform(size=100)) y = -np.sort(np.random.normal(size=100)) w = np.random.uniform(size=100) self.assertEqual( fitter.fit_pwl_points(x, x, y, w, 3), fitter.fit_pwl_points(x, x, y, w, 3, required_x_knots=None)) self.assertEqual( fitter.fit_pwl_points(x, x, y, w, 3), fitter.fit_pwl_points(x, x, y, w, 3, required_x_knots=[])) self.assertEqual( fitter.fit_pwl_points(x, x, y, w, 3), fitter.fit_pwl_points(x, x, y, w, 3, required_x_knots=np.array([])))