(self)
| 2452 | |
| 2453 | @support.requires_resource('cpu') |
| 2454 | def test_kde_random(self): |
| 2455 | kde_random = statistics.kde_random |
| 2456 | StatisticsError = statistics.StatisticsError |
| 2457 | kernels = ['normal', 'gauss', 'logistic', 'sigmoid', 'rectangular', |
| 2458 | 'uniform', 'triangular', 'parabolic', 'epanechnikov', |
| 2459 | 'quartic', 'biweight', 'triweight', 'cosine'] |
| 2460 | sample = [-2.1, -1.3, -0.4, 1.9, 5.1, 6.2] |
| 2461 | |
| 2462 | # Smoke test |
| 2463 | |
| 2464 | for kernel in kernels: |
| 2465 | with self.subTest(kernel=kernel): |
| 2466 | rand = kde_random(sample, h=1.5, kernel=kernel) |
| 2467 | selections = [rand() for i in range(10)] |
| 2468 | |
| 2469 | # Check error cases |
| 2470 | |
| 2471 | with self.assertRaises(StatisticsError): |
| 2472 | kde_random([], h=1.0) # Empty dataset |
| 2473 | with self.assertRaises(TypeError): |
| 2474 | kde_random(['abc', 'def'], 1.5) # Non-numeric data |
| 2475 | with self.assertRaises(TypeError): |
| 2476 | kde_random(iter(sample), 1.5) # Data is not a sequence |
| 2477 | with self.assertRaises(StatisticsError): |
| 2478 | kde_random(sample, h=-1.0) # Zero bandwidth |
| 2479 | with self.assertRaises(StatisticsError): |
| 2480 | kde_random(sample, h=0.0) # Negative bandwidth |
| 2481 | with self.assertRaises(TypeError): |
| 2482 | kde_random(sample, h='str') # Wrong bandwidth type |
| 2483 | with self.assertRaises(StatisticsError): |
| 2484 | kde_random(sample, h=1.0, kernel='bogus') # Invalid kernel |
| 2485 | |
| 2486 | # Test name and docstring of the generated function |
| 2487 | |
| 2488 | h = 1.5 |
| 2489 | kernel = 'cosine' |
| 2490 | rand = kde_random(sample, h, kernel) |
| 2491 | self.assertEqual(rand.__name__, 'rand') |
| 2492 | self.assertIn(kernel, rand.__doc__) |
| 2493 | self.assertIn(repr(h), rand.__doc__) |
| 2494 | |
| 2495 | # Approximate distribution test: Compare a random sample to the expected distribution |
| 2496 | |
| 2497 | data = [-2.1, -1.3, -0.4, 1.9, 5.1, 6.2, 7.8, 14.3, 15.1, 15.3, 15.8, 17.0] |
| 2498 | xarr = [x / 10 for x in range(-100, 250)] |
| 2499 | n = 1_000_000 |
| 2500 | h = 1.75 |
| 2501 | dx = 0.1 |
| 2502 | |
| 2503 | def p_observed(x): |
| 2504 | # P(x <= X < x+dx) |
| 2505 | i = bisect.bisect_left(big_sample, x) |
| 2506 | j = bisect.bisect_left(big_sample, x + dx) |
| 2507 | return (j - i) / len(big_sample) |
| 2508 | |
| 2509 | def p_expected(x): |
| 2510 | # P(x <= X < x+dx) |
| 2511 | return F_hat(x + dx) - F_hat(x) |
nothing calls this directly
no test coverage detected