| import unittest
|
| import warnings
|
|
|
| import numpy as np
|
|
|
| from ia_utils.vector_healing import enhanced_dense_healing_hybrid, median_healing
|
|
|
|
|
| class TestEnhancedDenseHealingHybrid(unittest.TestCase):
|
| def test_output_and_reconstruction_error_with_nan_inf_input(self):
|
| rng = np.random.default_rng(42)
|
| vettori = rng.normal(size=(30, 8))
|
| vettori[5, 2] = np.nan
|
| vettori[10, 3] = np.inf
|
| vettori[20, 0] = -np.inf
|
|
|
| out, metadata = enhanced_dense_healing_hybrid(vettori)
|
|
|
| self.assertFalse(np.isnan(out).any(), "L'output non deve contenere NaN")
|
| self.assertFalse(np.isinf(out).any(), "L'output non deve contenere Inf")
|
|
|
| reconstruction_error = metadata["reconstruction_error"]
|
| self.assertTrue(
|
| np.isfinite(reconstruction_error),
|
| f"reconstruction_error deve essere un numero reale valido, trovato: {reconstruction_error}",
|
| )
|
| self.assertFalse(np.isnan(reconstruction_error))
|
|
|
| def test_all_nan_column_produces_no_warning_and_finite_output(self):
|
| rng = np.random.default_rng(3)
|
| vettori = rng.normal(size=(20, 32))
|
| vettori[:, 4] = np.nan
|
|
|
| with warnings.catch_warnings(record=True) as caught:
|
| warnings.simplefilter("always")
|
| out, metadata = enhanced_dense_healing_hybrid(vettori)
|
|
|
| runtime_warnings = [w for w in caught if issubclass(w.category, RuntimeWarning)]
|
| self.assertEqual(runtime_warnings, [], f"RuntimeWarning inattesi: {runtime_warnings}")
|
| self.assertFalse(np.isnan(out).any())
|
| self.assertFalse(np.isinf(out).any())
|
| self.assertTrue(np.all(out[:, 4] == 0.0))
|
|
|
| def test_fallback_triggered_false_on_clean_data_without_nan_or_inf(self):
|
|
|
|
|
|
|
|
|
| vettori_puliti = np.random.default_rng(1).normal(size=(30, 64))
|
| self.assertFalse(np.isnan(vettori_puliti).any())
|
| self.assertFalse(np.isinf(vettori_puliti).any())
|
|
|
| _, meta = enhanced_dense_healing_hybrid(vettori_puliti)
|
|
|
| self.assertFalse(meta['fallback_triggered'])
|
|
|
| def test_fallback_triggered_true_still_holds_with_real_nan_inf_corruption(self):
|
|
|
|
|
|
|
| rng = np.random.default_rng(42)
|
| vettori = rng.normal(size=(30, 8))
|
| vettori[5, 2] = np.nan
|
| vettori[10, 3] = np.inf
|
| vettori[20, 0] = -np.inf
|
|
|
| _, meta = enhanced_dense_healing_hybrid(vettori)
|
|
|
| self.assertTrue(meta['fallback_triggered'])
|
|
|
|
|
| class TestMedianHealing(unittest.TestCase):
|
| def test_basic_shape_and_dtype(self):
|
| rng = np.random.default_rng(1)
|
| vettori = rng.normal(size=(25, 6))
|
| out, radius = median_healing(vettori)
|
| self.assertEqual(out.shape, vettori.shape)
|
| self.assertIsInstance(radius, int)
|
|
|
| def test_all_nan_column_produces_no_warning_and_finite_output(self):
|
| rng = np.random.default_rng(3)
|
| vettori = rng.normal(size=(20, 32))
|
| vettori[:, 4] = np.nan
|
|
|
| with warnings.catch_warnings(record=True) as caught:
|
| warnings.simplefilter("always")
|
| out, radius = median_healing(vettori)
|
|
|
| runtime_warnings = [w for w in caught if issubclass(w.category, RuntimeWarning)]
|
| self.assertEqual(runtime_warnings, [], f"RuntimeWarning inattesi: {runtime_warnings}")
|
| self.assertFalse(np.isnan(out).any())
|
| self.assertTrue(np.all(out[:, 4] == 0.0))
|
|
|
|
|
| if __name__ == "__main__":
|
| unittest.main()
|
|
|