Closed swifmaneum closed 3 years ago
Here are a few test cases we can add (to test_cellpylib.py
):
def test_binary_rule(self):
rule_number = 6667021275756174439087127638698866559
radius = 3
timesteps = 12
init = np.array([[1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1]])
actual = cpl.evolve(init, timesteps=timesteps,
apply_rule=lambda n, c, t: cpl.binary_rule(n, rule_number), r=radius)
expected = np.array([[1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1],
[1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1],
[1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1],
[1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])
np.testing.assert_equal(expected.tolist(), actual.tolist())
def test_binary_rule_powers_of_two_nks(self):
rule_number = 30
radius = 1
size = 149
timesteps = 149
expected = cpl.evolve(cpl.init_simple(size=size), timesteps=timesteps,
apply_rule=lambda n, c, t: cpl.binary_rule(n, rule_number, scheme="nks"), r=radius)
powers_of_two = 2 ** np.arange(radius * 2 + 1)[::-1]
rule = list(map(int, bin(rule_number)[2:]))
rule_bin_array = np.pad(rule, ((2 ** (radius * 2 + 1)) - len(rule), 0), 'constant').tolist()
actual = cpl.evolve(cpl.init_simple(size=size), timesteps=timesteps,
apply_rule=lambda n, c, t: cpl.binary_rule(n, rule_bin_array, scheme="nks", powers_of_two=powers_of_two),
r=radius)
np.testing.assert_equal(expected.tolist(), actual.tolist())
def test_binary_rule_powers_of_two_default(self):
rule_number = 6667021275756174439087127638698866559
radius = 3
timesteps = 49
init = np.array([[1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0,
1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1]])
expected = cpl.evolve(init, timesteps=timesteps,
apply_rule=lambda n, c, t: cpl.binary_rule(n, rule_number), r=radius)
powers_of_two = 2 ** np.arange(radius * 2 + 1)[::-1]
rule = list(map(int, bin(rule_number)[2:]))
rule_bin_array = np.pad(rule, ((2 ** (radius * 2 + 1)) - len(rule), 0), 'constant')
actual = cpl.evolve(init, timesteps=timesteps,
apply_rule=lambda n, c, t: cpl.binary_rule(n, rule_bin_array, powers_of_two=powers_of_two),
r=radius)
np.testing.assert_equal(expected.tolist(), actual.tolist())
I also changed your implementation of binary_rule
locally, on line 98, before running the tests above:
if isinstance(rule, (list, np.ndarray)):
assert len(rule) == n
rule_bin_array = rule
I added your suggestions. Right now there's only the assert len(rule) == n
for checking that the rule array is sized correctly but I agree that we could add a check and pad the rule array if necessary. I also added an additional assert ensuring that powers_of_two
has the right size.
I added your suggestions. Right now there's only the
assert len(rule) == n
for checking that the rule array is sized correctly but I agree that we could add a check and pad the rule array if necessary. I also added an additional assert ensuring thatpowers_of_two
has the right size.
Sounds good, thank you for contributing this!
closes #3
…rule; Adding an additional parameter powers_of_two to the binary_rule method allowing faster computation