def test_optimised_test_pattern(self): ts = OTPS( target=(1, 2), pattern=TP({ (3, 4): +1, (5, 6): -1, }), pattern_translation_multiple=(7, 8), target_translation_multiple=(9, 10), quantisation_index=11, decoded_value=12, num_search_iterations=13, ) its = invert_test_pattern_specification(ts) assert its == OTPS( target=(1, 2), pattern=TP({ (3, 4): -1, (5, 6): +1, }), pattern_translation_multiple=(7, 8), target_translation_multiple=(9, 10), quantisation_index=11, decoded_value=12, num_search_iterations=13, )
def test_serialise_test_pattern_specifications(): before = OrderedDict([ ((1, "LH", 2, 3), OTPS( target=(4, 5), pattern=TP({(10, 20): 1}), pattern_translation_multiple=(6, 7), target_translation_multiple=(8, 9), quantisation_index=30, decoded_value=40, num_search_iterations=50, )), ((2, "HL", 3, 2), OTPS( target=(1, 0), pattern=TP({(10, 20): 1}), pattern_translation_multiple=(6, 7), target_translation_multiple=(8, 9), quantisation_index=30, decoded_value=40, num_search_iterations=50, )), ]) after = serialise_test_pattern_specifications(OTPS, before) after = json_roundtrip(after) assert after == [ { "level": 1, "array_name": "LH", "phase": [2, 3], "target": [4, 5], "pattern": serialise_test_pattern(TP({(10, 20): 1})), "pattern_translation_multiple": [6, 7], "target_translation_multiple": [8, 9], "quantisation_index": 30, "decoded_value": 40, "num_search_iterations": 50, }, { "level": 2, "array_name": "HL", "phase": [3, 2], "target": [1, 0], "pattern": serialise_test_pattern(TP({(10, 20): 1})), "pattern_translation_multiple": [6, 7], "target_translation_multiple": [8, 9], "quantisation_index": 30, "decoded_value": 40, "num_search_iterations": 50, }, ] assert deserialise_test_pattern_specifications(OTPS, after) == before
def test_normalise_dict(self): t = TP({ (-5, 50): +1, (10, -1): 0, }) assert t.origin == (50, -5) assert t.polarities.shape == (1, 1)
def test_len(self): t = TP({ (-5, 50): +1, (10, -1): -1, (0, 0): 0, }) assert len(t) == 2
def test_offset_picture(self): test_patterns = OrderedDict([ ( (1, "Output", 0, 0), TPS( pattern=TP({ (2, 1): +1, (1, 2): -1, }), pattern_translation_multiple=(4, 4), target=(1, 1), target_translation_multiple=(1, 1), ), ), ]) width, height = 20, 10 pictures, locations = pack_test_patterns(width, height, test_patterns) assert len(pictures) == 1 assert list(locations) == list(test_patterns) # Should have been assigned to the top-left most point possible exp_picture = np.zeros((height, width), dtype=np.int8) exp_picture[1, 2] = +1 exp_picture[2, 1] = -1 assert np.array_equal(pictures[0], exp_picture) assert locations[(1, "Output", 0, 0)] == (0, 1, 1)
def test_conversion_to_array(self): test_pattern, search_slice = convert_test_pattern_to_padded_picture_and_slice( # NB: Coordinates are (x, y) here test_pattern=TP({ (2, 3): +1, (4, 5): -1, }), input_min=-512, input_max=511, dwt_depth=3, dwt_depth_ho=0, ) assert np.array_equal( test_pattern, np.array([ [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 511, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, -512, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], ])) # NB: Coordinates are (y, x) here! assert search_slice == (slice(3, 6), slice(2, 5))
def test_serialise_picture(): before = TP({ (10, 20): +1, (11, 20): -1, (12, 20): +1, (13, 20): -1, (14, 20): +1, (10, 21): +1, (12, 21): -1, (14, 21): +1, (10, 22): +1, (14, 22): -1, }) after = serialise_test_pattern(before) assert after["dx"] == 10 assert after["dy"] == 20 assert after["width"] == 5 assert after["height"] == 3 # positive array: mask array # 10101 11111 # 1x0x1 10101 # 1xxx0 10001 # Packed positive array: 1010110001100000________ # '----''----''----''----' # Decimal 43 6 0 # Base64 r G A = assert after["positive"] == "rGA=" # Packed mask array: 1111110101100010________ # '----''----''----''----' # Decimal 63 22 8 # Base64 / W I = assert after["mask"] == "/WI=" after = json_roundtrip(after) assert deserialise_test_pattern(after) == before
def test_eq(self): t1 = TP({ (0, 0): +1, (1, 0): -1, }) t2 = TP({ (0, 0): +1, (1, 0): -1, }) t3 = TP({ (1, 1): +1, (2, 1): -1, }) assert t1 == t2 assert t1 != (-t2) assert t1 != t3
def test_simple_packing(self): test_patterns = OrderedDict([ ( (1, "Output", 0, 0), TPS( pattern=TP({ (2, 1): +1, (1, 2): -1, }), pattern_translation_multiple=(4, 4), target=(1, 1), target_translation_multiple=(1, 1), ), ), ( (1, "Output", 0, 1), TPS( pattern=TP({ (2, 1): +1, (1, 2): +1, }), pattern_translation_multiple=(4, 4), target=(1, 1), target_translation_multiple=(1, 1), ), ), ]) width, height = 20, 10 pictures, locations = pack_test_patterns(width, height, test_patterns) assert len(pictures) == 1 assert list(locations) == list(test_patterns) exp_picture = np.zeros((height, width), dtype=np.int8) # First pattern, top left exp_picture[1, 2] = +1 exp_picture[2, 1] = -1 # Second pattern, just underneath exp_picture[5, 2] = +1 exp_picture[6, 1] = +1 assert np.array_equal(pictures[0], exp_picture) assert locations[(1, "Output", 0, 0)] == (0, 1, 1) assert locations[(1, "Output", 0, 1)] == (0, 1, 2)
def test_from_dict(self): t = TP({ (-5, 50): +1, (10, -1): -1, }) assert t.origin == (-1, -5) assert t.polarities.shape == (52, 16) assert t.polarities[51, 0] == +1 assert t.polarities[0, 15] == -1
def test_from_origin_and_polarities(self): polarities = np.array([ [0, 0, 0, -1], [1, 0, 0, 0], ]) t = TP((-1, -5), polarities) assert t.origin == (-1, -5) assert t.polarities.dtype == np.int8 assert np.array_equal(t.polarities, polarities)
def test_as_dict(self): t = TP({ (-5, 50): +1, (10, -1): -1, }) assert t.as_dict() == { (-5, 50): +1, (10, -1): -1, }
def test_normalise_origin_and_polarities(self): polarities = np.array([ [0, 0, 0, 0], [0, 0, 1, -1], [0, 0, 0, 0], ]) t = TP((-1, -5), polarities) assert t.origin == (0, -3) assert t.polarities.shape == (1, 2) assert np.array_equal(t.polarities, [[1, -1]])
def test_rounding_up_sizes(self, dwt_depth, dwt_depth_ho, exp_shape): test_pattern, search_slice = convert_test_pattern_to_padded_picture_and_slice( # NB: Coordinates are (x, y) here test_pattern=TP({ (6, 6): +1, }), input_min=-512, input_max=511, dwt_depth=dwt_depth, dwt_depth_ho=dwt_depth_ho, ) assert test_pattern.shape == exp_shape
def test_test_pattern(self): ts = TPS( target=(1, 2), pattern=TP({ (3, 4): +1, (5, 6): -1, }), pattern_translation_multiple=(7, 8), target_translation_multiple=(9, 10), ) its = invert_test_pattern_specification(ts) assert its == TPS( target=(1, 2), pattern=TP({ (3, 4): -1, (5, 6): +1, }), pattern_translation_multiple=(7, 8), target_translation_multiple=(9, 10), )
def test_as_picture_and_slice(self): p, s = TP({ (1, 2): +1, (3, 4): -1, }).as_picture_and_slice() assert np.array_equal(p, [ [0, 0, 0, 0], [0, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 0], [0, 0, 0, -1], ]) assert np.array_equal(p[s], [ [1, 0, 0], [0, 0, 0], [0, 0, -1], ])
def test_terminate_early( self, synthesis_intermediate_pyexps, filter_params, ): input_min = -512 input_max = 511 ts = TPS( target=(0, 0), pattern=TP({(0, 0): -1}), pattern_translation_multiple=(0, 0), target_translation_multiple=(0, 0), ) synthesis_pyexp = Argument("coeffs")[0]["LL"][0, 0] kwargs = { "h_filter_params": filter_params, "v_filter_params": filter_params, "dwt_depth": 0, "dwt_depth_ho": 0, "quantisation_matrix": { 0: { "LL": 0 } }, "synthesis_pyexp": synthesis_pyexp, "test_pattern_specification": ts, "input_min": input_min, "input_max": input_max, "max_quantisation_index": 1, "random_state": np.random.RandomState(1), "base_iterations": 100, "added_corruptions_per_iteration": 1, "removed_corruptions_per_iteration": 0, "added_iterations_per_improvement": 50, "number_of_searches": 10, } # Check that with terminate early disabled the search runs the full # base set of iterations but finds no improvement new_ts = optimise_synthesis_maximising_test_pattern( terminate_early=None, **kwargs) assert new_ts.pattern == ts.pattern assert new_ts.num_search_iterations == 100 * 10 # Check terminate early allows early termination after the specified # number of iterations new_ts = optimise_synthesis_maximising_test_pattern(terminate_early=3, **kwargs) assert new_ts.pattern == ts.pattern assert new_ts.num_search_iterations == 100 * 3 # Should run all iterations if an improvement is found kwargs["test_pattern_specification"] = TPS( target=(0, 0), pattern=TP({(0, 0): +1}), pattern_translation_multiple=(0, 0), target_translation_multiple=(0, 0), ) new_ts = optimise_synthesis_maximising_test_pattern(terminate_early=3, **kwargs) assert new_ts.num_search_iterations >= 100 * 10
def test_target_translation(self): # The test patterns should be allocated like so: # # +--+----+-----+ # |0 | 1 | | # +--+ | | # | +----+-+---+ # | | 2 | | # | | | | # +--+------+---+ # test_patterns = OrderedDict([ ( (1, "Output", 0, 0), TPS( pattern=TP({ (2, 1): +1, (1, 2): -1, }), pattern_translation_multiple=(4, 4), target=(1, 1), target_translation_multiple=(1, 1), ), ), ( (1, "Output", 0, 1), TPS( pattern=TP({ (10, 1): +1, (1, 5): +1, }), pattern_translation_multiple=(4, 4), target=(1, 1), target_translation_multiple=(1, 1), ), ), ( (1, "Output", 0, 2), TPS( pattern=TP({ (5, 1): -1, (1, 5): -1, }), pattern_translation_multiple=(4, 4), target=(2, 3), target_translation_multiple=(4, 5), ), ), ]) width, height = 20, 15 pictures, locations = pack_test_patterns(width, height, test_patterns) assert len(pictures) == 1 assert list(locations) == list(test_patterns) exp_picture = np.zeros((height, width), dtype=np.int8) # First pattern, top left exp_picture[1, 2] = +1 exp_picture[2, 1] = -1 # Second pattern, just to the right exp_picture[1, 14] = +1 exp_picture[5, 5] = +1 # Third pattern, below-right of both exp_picture[13, 5] = -1 exp_picture[9, 9] = -1 assert np.array_equal(pictures[0], exp_picture) assert locations[(1, "Output", 0, 0)] == (0, 1, 1) assert locations[(1, "Output", 0, 1)] == (0, 2, 1) assert locations[(1, "Output", 0, 2)] == (0, 2 + 4, 3 + (2 * 5))
def test_as_picture_and_slice_invalid(self): with pytest.raises(ValueError): TP({(-1, 0): +1}).as_picture_and_slice() with pytest.raises(ValueError): TP({(0, -1): +1}).as_picture_and_slice()
def test_as_picture_and_slice_empty(self): p, s = TP({}).as_picture_and_slice() assert p.shape == (0, 0) assert p[s].shape == (0, 0)
def test_overspill_pictures(self): # Tests that allocation can overspill onto extra pictures and that # later allocations can be inserted onto any available picture. # # +------+------+ +-------------+ # | | | | 1 | # | 0 | 2 | +-------------+ # | | | | 3 | # +------+------+ +-------------+ # test_patterns = OrderedDict([ ( (1, "Output", 0, 0), TPS( pattern=TP({ (9, 0): -1, (0, 9): -1, }), pattern_translation_multiple=(1, 1), target=(1, 1), target_translation_multiple=(1, 1), ), ), ( (1, "Output", 0, 1), TPS( pattern=TP({ (19, 0): +1, (0, 4): -1, }), pattern_translation_multiple=(1, 1), target=(1, 1), target_translation_multiple=(1, 1), ), ), ( (1, "Output", 0, 2), TPS( pattern=TP({ (9, 0): +1, (0, 9): +1, }), pattern_translation_multiple=(1, 1), target=(1, 1), target_translation_multiple=(1, 1), ), ), ( (1, "Output", 0, 3), TPS( pattern=TP({ (19, 0): -1, (0, 4): +1, }), pattern_translation_multiple=(1, 1), target=(1, 1), target_translation_multiple=(1, 1), ), ), ]) width, height = 20, 10 pictures, locations = pack_test_patterns(width, height, test_patterns) assert len(pictures) == 2 assert list(locations) == list(test_patterns) exp_picture_0 = np.zeros((height, width), dtype=np.int8) exp_picture_1 = np.zeros((height, width), dtype=np.int8) # Pattern 0 exp_picture_0[0, 9] = -1 exp_picture_0[9, 0] = -1 # Pattern 1 exp_picture_1[0, 19] = +1 exp_picture_1[4, 0] = -1 # Pattern 2 exp_picture_0[0, 19] = +1 exp_picture_0[9, 10] = +1 # Pattern 3 exp_picture_1[5, 19] = -1 exp_picture_1[9, 0] = +1 assert np.array_equal(pictures[0], exp_picture_0) assert np.array_equal(pictures[1], exp_picture_1) assert locations[(1, "Output", 0, 0)] == (0, 1, 1) assert locations[(1, "Output", 0, 1)] == (1, 1, 1) assert locations[(1, "Output", 0, 2)] == (0, 11, 1) assert locations[(1, "Output", 0, 3)] == (1, 1, 6)
def test_large_test_patterns_skipped(self): test_patterns = OrderedDict([ ( (1, "Output", 0, 0), TPS( pattern=TP({ (1, 0): +1, (0, 1): -1, }), pattern_translation_multiple=(1, 1), target=(1, 1), target_translation_multiple=(1, 1), ), ), ( (1, "Output", 0, 1), TPS( pattern=TP({ (100, 0): -1, (0, 100): -1, }), pattern_translation_multiple=(1, 1), target=(1, 1), target_translation_multiple=(1, 1), ), ), ( (1, "Output", 0, 2), TPS( pattern=TP({ (1, 0): -1, (0, 1): +1, }), pattern_translation_multiple=(1, 1), target=(1, 1), target_translation_multiple=(1, 1), ), ), ]) width, height = 20, 10 pictures, locations = pack_test_patterns(width, height, test_patterns) assert len(pictures) == 1 assert list(locations) == [ (1, "Output", 0, 0), (1, "Output", 0, 2), ] exp_picture = np.zeros((height, width), dtype=np.int8) # First pattern, top left exp_picture[0, 1] = +1 exp_picture[1, 0] = -1 # Third pattern, underneath exp_picture[2, 1] = -1 exp_picture[3, 0] = +1 assert np.array_equal(pictures[0], exp_picture) assert locations[(1, "Output", 0, 0)] == (0, 1, 1) assert locations[(1, "Output", 0, 2)] == (0, 1, 3)
def test_neg(self): t = TP({ (0, 0): +1, (1, 0): -1, }) assert np.array_equal((-t).polarities, [[-1, +1]])
def test_empty(self): t = TP({}) assert t.origin == (0, 0) assert t.polarities.shape == (0, 0) assert len(t) == 0
def test_repr(self): t = TP({ (-10, 20): -1, }) assert repr(t) == "TestPattern({(-10, 20): -1})"