|
3 | 3 | import autoarray as aa |
4 | 4 |
|
5 | 5 |
|
6 | | -def test__data_and_model_are_identical__no_masking__check_values_are_correct(): |
7 | | - mask = aa.Mask2D(mask=[[False, False], [False, False]], pixel_scales=(1.0, 1.0)) |
| 6 | +# --------------------------------------------------------------------------- |
| 7 | +# Helper: build the "identical model, no masking" fit used by multiple tests |
| 8 | +# --------------------------------------------------------------------------- |
8 | 9 |
|
| 10 | +def _make_identical_fit_no_mask(): |
| 11 | + mask = aa.Mask2D(mask=[[False, False], [False, False]], pixel_scales=(1.0, 1.0)) |
9 | 12 | data = aa.Array2D(values=[1.0, 2.0, 3.0, 4.0], mask=mask) |
10 | 13 | noise_map = aa.Array2D(values=[2.0, 2.0, 2.0, 2.0], mask=mask) |
11 | | - |
12 | 14 | dataset = aa.Imaging(data=data, noise_map=noise_map) |
13 | | - |
14 | 15 | dataset = dataset.apply_mask(mask=mask) |
15 | | - |
16 | 16 | model_data = aa.Array2D(values=[1.0, 2.0, 3.0, 4.0], mask=mask) |
| 17 | + fit = aa.m.MockFitImaging( |
| 18 | + dataset=dataset, use_mask_in_fit=False, model_data=model_data |
| 19 | + ) |
| 20 | + return fit, noise_map |
17 | 21 |
|
| 22 | + |
| 23 | +def _make_different_fit_with_mask(): |
| 24 | + mask = aa.Mask2D(mask=[[False, False], [True, False]], pixel_scales=(1.0, 1.0)) |
| 25 | + data = aa.Array2D(values=[1.0, 2.0, 4.0], mask=mask) |
| 26 | + noise_map = aa.Array2D(values=[2.0, 2.0, 2.0], mask=mask) |
| 27 | + dataset = aa.Imaging(data=data, noise_map=noise_map) |
| 28 | + model_data = aa.Array2D(values=[1.0, 2.0, 3.0], mask=mask) |
18 | 29 | fit = aa.m.MockFitImaging( |
19 | 30 | dataset=dataset, use_mask_in_fit=False, model_data=model_data |
20 | 31 | ) |
| 32 | + return fit, noise_map |
| 33 | + |
| 34 | + |
| 35 | +def _make_identical_fit_with_inversion(): |
| 36 | + mask = aa.Mask2D(mask=[[False, False], [False, False]], pixel_scales=(1.0, 1.0)) |
| 37 | + data = aa.Array2D(values=[1.0, 2.0, 3.0, 4.0], mask=mask) |
| 38 | + noise_map = aa.Array2D(values=[2.0, 2.0, 2.0, 2.0], mask=mask) |
| 39 | + dataset = aa.Imaging(data=data, noise_map=noise_map) |
| 40 | + dataset = dataset.apply_mask(mask=mask) |
| 41 | + model_data = aa.Array2D(values=[1.0, 2.0, 3.0, 4.0], mask=mask) |
| 42 | + inversion = aa.m.MockInversion( |
| 43 | + linear_obj_list=[aa.m.MockMapper()], |
| 44 | + data_vector=1, |
| 45 | + regularization_term=2.0, |
| 46 | + log_det_curvature_reg_matrix_term=3.0, |
| 47 | + log_det_regularization_matrix_term=4.0, |
| 48 | + ) |
| 49 | + fit = aa.m.MockFitImaging( |
| 50 | + dataset=dataset, |
| 51 | + use_mask_in_fit=False, |
| 52 | + model_data=model_data, |
| 53 | + inversion=inversion, |
| 54 | + ) |
| 55 | + return fit, noise_map |
| 56 | + |
| 57 | + |
| 58 | +# --------------------------------------------------------------------------- |
| 59 | +# Tests: identical data and model, no masking |
| 60 | +# --------------------------------------------------------------------------- |
| 61 | + |
| 62 | + |
| 63 | +def test__mask__no_masking__returns_2x2_all_false_mask(): |
| 64 | + fit, _ = _make_identical_fit_no_mask() |
21 | 65 |
|
22 | 66 | assert (fit.mask == np.array([[False, False], [False, False]])).all() |
| 67 | + |
| 68 | + |
| 69 | +def test__data__no_masking__returns_correct_data_values(): |
| 70 | + fit, _ = _make_identical_fit_no_mask() |
| 71 | + |
23 | 72 | assert (fit.data == np.array([1.0, 2.0, 3.0, 4.0])).all() |
| 73 | + |
| 74 | + |
| 75 | +def test__noise_map__no_masking__returns_correct_noise_map_values(): |
| 76 | + fit, _ = _make_identical_fit_no_mask() |
| 77 | + |
24 | 78 | assert (fit.noise_map == np.array([2.0, 2.0, 2.0, 2.0])).all() |
| 79 | + |
| 80 | + |
| 81 | +def test__signal_to_noise_map__no_masking__returns_correct_signal_to_noise_values(): |
| 82 | + fit, _ = _make_identical_fit_no_mask() |
| 83 | + |
25 | 84 | assert (fit.signal_to_noise_map == np.array([0.5, 1.0, 1.5, 2.0])).all() |
26 | | - assert (fit.model_data == np.array([1.0, 2.0, 3.0, 4.0])).all() |
| 85 | + |
| 86 | + |
| 87 | +def test__residual_map__identical_data_and_model__all_zero_residuals(): |
| 88 | + fit, _ = _make_identical_fit_no_mask() |
| 89 | + |
27 | 90 | assert (fit.residual_map == np.array([0.0, 0.0, 0.0, 0.0])).all() |
| 91 | + |
| 92 | + |
| 93 | +def test__normalized_residual_map__identical_data_and_model__all_zero_normalized_residuals(): |
| 94 | + fit, _ = _make_identical_fit_no_mask() |
| 95 | + |
28 | 96 | assert (fit.normalized_residual_map == np.array([0.0, 0.0, 0.0, 0.0])).all() |
| 97 | + |
| 98 | + |
| 99 | +def test__chi_squared_map__identical_data_and_model__all_zero_chi_squared_map(): |
| 100 | + fit, _ = _make_identical_fit_no_mask() |
| 101 | + |
29 | 102 | assert (fit.chi_squared_map == np.array([0.0, 0.0, 0.0, 0.0])).all() |
30 | 103 |
|
| 104 | + |
| 105 | +def test__chi_squared__identical_data_and_model__is_zero(): |
| 106 | + fit, _ = _make_identical_fit_no_mask() |
| 107 | + |
31 | 108 | assert fit.chi_squared == 0.0 |
| 109 | + |
| 110 | + |
| 111 | +def test__reduced_chi_squared__identical_data_and_model__is_zero(): |
| 112 | + fit, _ = _make_identical_fit_no_mask() |
| 113 | + |
32 | 114 | assert fit.reduced_chi_squared == 0.0 |
| 115 | + |
| 116 | + |
| 117 | +def test__noise_normalization__uniform_noise_map__correct_log_sum_formula(): |
| 118 | + fit, noise_map = _make_identical_fit_no_mask() |
| 119 | + |
33 | 120 | assert fit.noise_normalization == np.sum(np.log(2 * np.pi * noise_map.array**2.0)) |
34 | | - assert fit.log_likelihood == -0.5 * (fit.chi_squared + fit.noise_normalization) |
35 | 121 |
|
36 | 122 |
|
37 | | -def test__data_and_model_are_different__include_masking__check_values_are_correct(): |
38 | | - mask = aa.Mask2D(mask=[[False, False], [True, False]], pixel_scales=(1.0, 1.0)) |
| 123 | +def test__log_likelihood__identical_data_and_model__negative_half_noise_normalization(): |
| 124 | + fit, _ = _make_identical_fit_no_mask() |
39 | 125 |
|
40 | | - data = aa.Array2D(values=[1.0, 2.0, 4.0], mask=mask) |
41 | | - noise_map = aa.Array2D(values=[2.0, 2.0, 2.0], mask=mask) |
| 126 | + assert fit.log_likelihood == -0.5 * (fit.chi_squared + fit.noise_normalization) |
42 | 127 |
|
43 | | - dataset = aa.Imaging(data=data, noise_map=noise_map) |
44 | 128 |
|
45 | | - model_data = aa.Array2D(values=[1.0, 2.0, 3.0], mask=mask) |
| 129 | +# --------------------------------------------------------------------------- |
| 130 | +# Tests: different data and model with partial mask |
| 131 | +# --------------------------------------------------------------------------- |
46 | 132 |
|
47 | | - fit = aa.m.MockFitImaging( |
48 | | - dataset=dataset, use_mask_in_fit=False, model_data=model_data |
49 | | - ) |
50 | 133 |
|
51 | | - assert (fit.mask == np.array([[False, False], [True, False]])).all() |
52 | | - assert (fit.data.slim == np.array([1.0, 2.0, 4.0])).all() |
53 | | - assert (fit.noise_map.slim == np.array([2.0, 2.0, 2.0])).all() |
54 | | - assert (fit.signal_to_noise_map.slim == np.array([0.5, 1.0, 2.0])).all() |
55 | | - assert (fit.model_data.slim == np.array([1.0, 2.0, 3.0])).all() |
| 134 | +def test__residual_map__different_data_and_model_with_partial_mask__correct_slim_residuals(): |
| 135 | + fit, _ = _make_different_fit_with_mask() |
| 136 | + |
56 | 137 | assert (fit.residual_map.slim == np.array([0.0, 0.0, 1.0])).all() |
| 138 | + |
| 139 | + |
| 140 | +def test__normalized_residual_map__different_data_and_model_with_partial_mask__correct_slim_values(): |
| 141 | + fit, _ = _make_different_fit_with_mask() |
| 142 | + |
57 | 143 | assert (fit.normalized_residual_map.slim == np.array([0.0, 0.0, 0.5])).all() |
| 144 | + |
| 145 | + |
| 146 | +def test__chi_squared_map__different_data_and_model_with_partial_mask__correct_slim_chi_squared(): |
| 147 | + fit, _ = _make_different_fit_with_mask() |
| 148 | + |
58 | 149 | assert (fit.chi_squared_map.slim == np.array([0.0, 0.0, 0.25])).all() |
59 | 150 |
|
| 151 | + |
| 152 | +def test__chi_squared__different_model_with_masked_data__correct_value(): |
| 153 | + fit, _ = _make_different_fit_with_mask() |
| 154 | + |
60 | 155 | assert fit.chi_squared == 0.25 |
| 156 | + |
| 157 | + |
| 158 | +def test__reduced_chi_squared__different_model_with_masked_data__divided_by_unmasked_pixel_count(): |
| 159 | + fit, _ = _make_different_fit_with_mask() |
| 160 | + |
61 | 161 | assert fit.reduced_chi_squared == 0.25 / 3.0 |
| 162 | + |
| 163 | + |
| 164 | +def test__log_likelihood__different_model_with_masked_data__correct_value(): |
| 165 | + fit, noise_map = _make_different_fit_with_mask() |
| 166 | + |
62 | 167 | assert fit.noise_normalization == np.sum(np.log(2 * np.pi * noise_map.array**2.0)) |
63 | 168 | assert fit.log_likelihood == -0.5 * (fit.chi_squared + fit.noise_normalization) |
64 | 169 |
|
65 | 170 |
|
66 | | -def test__data_and_model_are_identical__inversion_included__changes_certain_properties(): |
67 | | - mask = aa.Mask2D(mask=[[False, False], [False, False]], pixel_scales=(1.0, 1.0)) |
| 171 | +# --------------------------------------------------------------------------- |
| 172 | +# Tests: identical data and model with inversion |
| 173 | +# --------------------------------------------------------------------------- |
68 | 174 |
|
69 | | - data = aa.Array2D(values=[1.0, 2.0, 3.0, 4.0], mask=mask) |
70 | | - noise_map = aa.Array2D(values=[2.0, 2.0, 2.0, 2.0], mask=mask) |
71 | 175 |
|
72 | | - dataset = aa.Imaging(data=data, noise_map=noise_map) |
| 176 | +def test__chi_squared__identical_data_and_model_with_inversion__is_zero(): |
| 177 | + fit, _ = _make_identical_fit_with_inversion() |
73 | 178 |
|
74 | | - dataset = dataset.apply_mask(mask=mask) |
| 179 | + assert fit.chi_squared == 0.0 |
75 | 180 |
|
76 | | - model_data = aa.Array2D(values=[1.0, 2.0, 3.0, 4.0], mask=mask) |
77 | 181 |
|
78 | | - inversion = aa.m.MockInversion( |
79 | | - linear_obj_list=[aa.m.MockMapper()], |
80 | | - data_vector=1, |
81 | | - regularization_term=2.0, |
82 | | - log_det_curvature_reg_matrix_term=3.0, |
83 | | - log_det_regularization_matrix_term=4.0, |
84 | | - ) |
85 | | - |
86 | | - fit = aa.m.MockFitImaging( |
87 | | - dataset=dataset, |
88 | | - use_mask_in_fit=False, |
89 | | - model_data=model_data, |
90 | | - inversion=inversion, |
91 | | - ) |
| 182 | +def test__reduced_chi_squared__identical_data_and_model_with_inversion__is_zero(): |
| 183 | + fit, _ = _make_identical_fit_with_inversion() |
92 | 184 |
|
93 | | - assert fit.chi_squared == 0.0 |
94 | 185 | assert fit.reduced_chi_squared == 0.0 |
95 | | - assert fit.noise_normalization == np.sum(np.log(2 * np.pi * noise_map.array**2.0)) |
96 | | - assert fit.log_likelihood == -0.5 * (fit.chi_squared + fit.noise_normalization) |
| 186 | + |
| 187 | + |
| 188 | +def test__log_likelihood_with_regularization__with_inversion__adds_regularization_term(): |
| 189 | + fit, noise_map = _make_identical_fit_with_inversion() |
97 | 190 |
|
98 | 191 | assert fit.log_likelihood_with_regularization == -0.5 * ( |
99 | 192 | fit.chi_squared + 2.0 + fit.noise_normalization |
100 | 193 | ) |
| 194 | + |
| 195 | + |
| 196 | +def test__log_evidence__with_inversion__uses_chi_squared_reg_and_determinant_terms(): |
| 197 | + fit, noise_map = _make_identical_fit_with_inversion() |
| 198 | + |
101 | 199 | assert fit.log_evidence == -0.5 * ( |
102 | 200 | fit.chi_squared + 2.0 + 3.0 - 4.0 + fit.noise_normalization |
103 | 201 | ) |
| 202 | + |
| 203 | + |
| 204 | +def test__figure_of_merit__with_inversion__equals_log_evidence(): |
| 205 | + fit, _ = _make_identical_fit_with_inversion() |
| 206 | + |
104 | 207 | assert fit.figure_of_merit == fit.log_evidence |
0 commit comments