def test_validate_blackbox_and_coarsegrain(): blackbox = None coarse_grain = macro.CoarseGrain(((0, 1), (2, )), ((0, 1), (2, ))) validate.blackbox_and_coarse_grain(blackbox, coarse_grain) blackbox = macro.Blackbox(((0, 1), (2, )), (0, 2)) coarse_grain = None validate.blackbox_and_coarse_grain(blackbox, coarse_grain) blackbox = macro.Blackbox(((0, 1), (2, )), (0, 1, 2)) coarse_grain = macro.CoarseGrain(((0, 1), (2, )), ((0, 1), (2, ))) validate.blackbox_and_coarse_grain(blackbox, coarse_grain) # Blackboxing with multiple outputs must be coarse-grained blackbox = macro.Blackbox(((0, 1), (2, )), (0, 1, 2)) coarse_grain = None with pytest.raises(ValueError): validate.blackbox_and_coarse_grain(blackbox, coarse_grain) # Coarse-graining does not group multiple outputs of a box into the same # macro element blackbox = macro.Blackbox(((0, 1), (2, )), (0, 1, 2)) coarse_grain = macro.CoarseGrain(((0, ), (1, 2)), ((0, 1), (2, ))) with pytest.raises(ValueError): validate.blackbox_and_coarse_grain(blackbox, coarse_grain)
def test_validate_blackbox(): validate.blackbox(macro.Blackbox(((0, 1), ), (1, ))) # Unsorted output indices with pytest.raises(ValueError): validate.blackbox(macro.Blackbox(((0, 1), ), (1, 0))) # Two boxes may not contain the same elements with pytest.raises(ValueError): validate.blackbox(macro.Blackbox(((0, ), (0, 1)), (0, 1))) # Every box must have an output with pytest.raises(ValueError): validate.blackbox(macro.Blackbox(((0, ), (1, )), (0, )))
def test_macro2micro(s): # Only blackboxing blackbox = macro.Blackbox(((0, 2), (1, )), (1, 2)) subsys = macro.MacroSubsystem(s.network, s.state, s.node_indices, blackbox=blackbox) assert subsys.macro2micro((0, )) == (0, 2) assert subsys.macro2micro((1, )) == (1, ) assert subsys.macro2micro((1, 0)) == (0, 1, 2) assert subsys.macro2blackbox_outputs((0, )) == (2, ) assert subsys.macro2blackbox_outputs((1, )) == (1, ) assert subsys.macro2blackbox_outputs((1, 0)) == (1, 2) # Only coarse-graining coarse_grain = macro.CoarseGrain(((0, ), (1, 2)), (((0, ), (1, )), ((0, ), (1, 2)))) subsys = macro.MacroSubsystem(s.network, s.state, s.node_indices, coarse_grain=coarse_grain) assert subsys.macro2micro((0, )) == (0, ) assert subsys.macro2micro((1, )) == (1, 2) assert subsys.macro2micro((0, 1)) == (0, 1, 2) with pytest.raises(ValueError): subsys.macro2blackbox_outputs((0, )) # Blackboxing and coarse-graining blackbox = macro.Blackbox(((0, 2), (1, )), (1, 2)) coarse_grain = macro.CoarseGrain(((1, 2), ), (((0, ), (1, 2)), )) subsys = macro.MacroSubsystem(s.network, s.state, s.node_indices, blackbox=blackbox, coarse_grain=coarse_grain) assert subsys.macro2micro((0, )) == (0, 1, 2) assert subsys.macro2blackbox_outputs((0, )) == (1, 2) # Pure micro subsys = macro.MacroSubsystem(s.network, s.state, s.node_indices) assert subsys.macro2micro((1, )) == (1, ) assert subsys.macro2micro((0, 1)) == (0, 1) with pytest.raises(ValueError): subsys.macro2blackbox_outputs((1, ))
def test_blackbox(s): ms = macro.MacroSubsystem(s.network, s.state, s.node_indices, blackbox=macro.Blackbox(((0, 1, 2),), (1,))) assert np.array_equal(ms.tpm, np.array([[.5], [.5]])) assert np.array_equal(ms.cm, np.array([[1]])) assert ms.node_indices == (0,) assert ms.state == (0,)
def test_blackbox_partial_noise(s): blackbox = macro.Blackbox(((0, ), (1, 2)), (0, 1)) subsys = macro.MacroSubsystem(s.network, s.state, s.node_indices, blackbox=blackbox) noised = subsys._blackbox_partial_noise(blackbox, macro.SystemAttrs.pack(s)) # Noise connection from 2 -> 0 assert np.array_equal( noised.tpm, convert.to_multidimensional( np.array([ [.5, 0, 0], [.5, 0, 1], [1., 0, 1], [1., 0, 0], [.5, 1, 0], [.5, 1, 1], [1., 1, 1], [1., 1, 0], ]))) # No change assert np.array_equal(noised.cm, np.array([[0, 0, 1], [1, 0, 1], [1, 1, 0]]))
def test_blackbox_and_coarse_grain_external(): # Larger, with external nodes, blackboxed and coarse-grained tpm = np.zeros((2**6, 6)) network = pyphi.Network(tpm) state = (0, 0, 0, 0, 0, 0) blackbox = macro.Blackbox(( (1, 4), (2, ), (3, ), (5, ), ), (1, 2, 3, 5)) partition = ((1, ), (2, ), (3, 5)) grouping = (((0, ), (1, )), ((1, ), (0, )), ((0, ), (1, 2))) coarse_grain = macro.CoarseGrain(partition, grouping) ms = macro.MacroSubsystem(network, state, (1, 2, 3, 4, 5), blackbox=blackbox, coarse_grain=coarse_grain) answer_tpm = np.array([[[[0, 1, 0], [0, 1, 0]], [[0, 1, 0], [0, 1, 0]]], [[[0, 1, 0], [0, 1, 0]], [[0, 1, 0], [0, 1, 0]]]]) assert np.array_equal(ms.tpm, answer_tpm) assert np.array_equal(ms.cm, np.ones((3, 3))) assert ms.node_indices == (0, 1, 2) assert ms.size == 3 assert ms.state == (0, 1, 0)
def test_macro_cut_is_for_micro_indices(s): with pytest.raises(ValueError): macro.MacroSubsystem(s.network, s.state, s.node_indices, blackbox=macro.Blackbox((2, ), (0, 1)), cut=models.Cut((0, ), (1, )))
def test_all_coarse_grains_for_blackbox(): blackbox = macro.Blackbox(((0, 1), ), (0, 1)) assert list(macro.all_coarse_grains_for_blackbox(blackbox)) == [ macro.CoarseGrain(((0, 1), ), (((0, 1), (2, )), )), macro.CoarseGrain(((0, 1), ), (((0, 2), (1, )), )), macro.CoarseGrain(((0, 1), ), (((0, ), (1, 2)), )), ]
def test_blackbox_external(s): # Which is the same if one of these indices is external ms = macro.MacroSubsystem(s.network, s.state, (1, 2), blackbox=macro.Blackbox(((1, 2),), (1,))) assert np.array_equal(ms.tpm, np.array([[.5], [.5]])) assert np.array_equal(ms.cm, np.array([[1]])) assert ms.node_indices == (0,) assert ms.state == (0,)
def test_blackbox_and_coarse_grain(s): blackbox = macro.Blackbox(((0, 1, 2),), (0, 2)) coarse_grain = macro.CoarseGrain(partition=((0, 2),), grouping=((((0, 1), (2,)),))) ms = macro.MacroSubsystem(s.network, s.state, s.node_indices, blackbox=blackbox, coarse_grain=coarse_grain) assert np.array_equal(ms.tpm, np.array([[0], [1]])) assert np.array_equal(ms.cm, [[1]]) assert ms.node_indices == (0,) assert ms.size == 1 assert ms.state == (0,)
def test_xor_propogation_delay(): # Three interconnected XOR gates, with COPY gates along each connection # acting as propagation delays. nodes = 9 tpm = np.zeros((2**nodes, nodes)) for psi, ps in enumerate(utils.all_states(nodes)): cs = [0 for i in range(nodes)] if ps[2] ^ ps[7]: cs[0] = 1 if ps[0] == 1: cs[1] = 1 cs[8] = 1 if ps[1] ^ ps[5]: cs[3] = 1 if ps[3] == 1: cs[2] = 1 cs[4] = 1 if ps[4] ^ ps[8]: cs[6] = 1 if ps[6] == 1: cs[5] = 1 cs[7] = 1 tpm[psi, :] = cs cm = np.array([[0, 1, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 1, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 1, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 0]]) # The state of the system is all OFF state = (0, 0, 0, 0, 0, 0, 0, 0, 0) network = Network(tpm, cm=cm) partition = ((0, 2, 7), (1, 3, 5), (4, 6, 8)) output_indices = (0, 3, 6) blackbox = macro.Blackbox(partition, output_indices) assert blackbox.hidden_indices == (1, 2, 4, 5, 7, 8) time = 2 subsys = macro.MacroSubsystem(network, state, network.node_indices, blackbox=blackbox, time_scale=time) sia = compute.sia(subsys) assert sia.phi == 1.874999 assert sia.cut == models.Cut((0, ), (1, 2, 3, 4, 5, 6, 7, 8))
def test_blackbox_timescale(): # System is an OR gate and a COPY gate; the OR gate is connected with a # self loop. # fmt: off tpm = convert.to_multidimensional( np.array([ [0, 0], [1, 1], [1, 0], [1, 1], ])) cm = np.array([ [1, 1], [1, 0], ]) # fmt: on indices = (0, 1) blackbox = macro.Blackbox(((0, ), (1, )), (0, 1)) steps = 2 state = (1, 0) system = macro.SystemAttrs(tpm, cm, indices, state) result = macro.run_tpm(system, steps, blackbox) # fmt: off answer = convert.state_by_state2state_by_node( np.array([ [1, 3, 1, 3], [0, 4, 0, 4], [1, 3, 1, 3], [0, 4, 0, 4], ]) / 8) # fmt: on np.testing.assert_array_equal(result, answer) result = macro.run_tpm(system, steps, blackbox) # fmt: off answer = convert.state_by_state2state_by_node( np.array([ [1, 1, 1, 1], [0, 2, 0, 2], [1, 1, 1, 1], [0, 2, 0, 2], ]) / 4) # fmt: on np.testing.assert_array_equal(result, answer)
def test_subsystem_equality(s): macro_subsys = macro.MacroSubsystem(s.network, s.state, s.node_indices) assert s != macro_subsys assert hash(s) != hash(macro_subsys) blackbox = macro.Blackbox(((0, 1, 2),), (2,)) macro_subsys_bb = macro.MacroSubsystem( s.network, s.state, s.node_indices, blackbox=blackbox, time_scale=2) assert macro_subsys != macro_subsys_bb assert hash(macro_subsys) != hash(macro_subsys_bb) coarse_grain = macro.CoarseGrain( ((0, 1), (2,)), (((0, 1), (2,)), ((0,), (1,)))) macro_subsys_cg = macro.MacroSubsystem( s.network, s.state, s.node_indices, coarse_grain=coarse_grain) assert macro_subsys != macro_subsys_cg assert hash(macro_subsys) != hash(macro_subsys_cg)
def degenerate(): nodes = 6 tpm = np.zeros((2**nodes, nodes)) for psi, ps in enumerate(utils.all_states(nodes)): cs = [0 for i in range(nodes)] if ps[5] == 1: cs[0] = 1 cs[1] = 1 if ps[0] == 1 and ps[1]: cs[2] = 1 if ps[2] == 1: cs[3] = 1 cs[4] = 1 if ps[3] == 1 and ps[4] == 1: cs[5] = 1 tpm[psi, :] = cs cm = np.array([[0, 0, 1, 0, 0, 0], [0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 1, 0], [0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 1], [1, 1, 0, 0, 0, 0]]) current_state = (0, 0, 0, 0, 0, 0) network = Network(tpm, cm) partition = ((0, 1, 2), (3, 4, 5)) output_indices = (2, 5) blackbox = macro.Blackbox(partition, output_indices) time_scale = 2 return macro.MacroSubsystem(network, current_state, network.node_indices, blackbox=blackbox, time_scale=time_scale)
def cg_bb(): """A blackbox with multiple outputs for a box, which must be coarse- grained.""" partition = ((1, 3), (4, ), (5, )) output_indices = (1, 3, 4, 5) return macro.Blackbox(partition, output_indices)
def bb(): partition = ((1, 3), (4, )) output_indices = (3, 4) return macro.Blackbox(partition, output_indices)
def test_basic_nor_or(): # A system composed of NOR and OR (copy) gates, which mimics the basic # pyphi network nodes = 12 tpm = np.zeros((2**nodes, nodes)) for psi, ps in enumerate(utils.all_states(nodes)): cs = [0 for i in range(nodes)] if ps[5] == 0 and ps[11] == 0: cs[0] = 1 if ps[0] == 0: cs[1] = 1 if ps[1] == 1: cs[2] = 1 if ps[11] == 0: cs[3] = 1 if ps[3] == 0: cs[4] = 1 if ps[4] == 1: cs[5] = 1 if ps[2] == 0: cs[6] = 1 if ps[5] == 0: cs[7] = 1 if ps[6] == 0 and ps[7] == 0: cs[8] = 1 if ps[2] == 0 and ps[5] == 0: cs[9] = 1 if ps[9] == 1: cs[10] = 1 if ps[8] == 0 and ps[10] == 0: cs[11] = 1 tpm[psi, :] = cs cm = np.array([ [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], ]) state = (0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0) network = Network(tpm, cm=cm) # (0, 1, 2) compose the OR element, # (3, 4, 5) the COPY, # (6, 7, 8, 9, 10, 11) the XOR partition = ((0, 1, 2), (3, 4, 5), (6, 7, 8, 9, 10, 11)) output = (2, 5, 11) blackbox = macro.Blackbox(partition, output) assert blackbox.hidden_indices == (0, 1, 3, 4, 6, 7, 8, 9, 10) time = 3 sub = macro.MacroSubsystem(network, state, network.node_indices, blackbox=blackbox, time_scale=time) with config.override(CUT_ONE_APPROXIMATION=True): sia = compute.sia(sub) assert sia.phi == 1.958332 assert sia.cut == models.Cut((6, ), (0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11))
def test_soup(): # An first example attempting to capture the "soup" metaphor # # The system will consist of 6 elements 2 COPY elements (A, B) input to an # AND element (C) AND element (C) inputs to two COPY elements (D, E) 2 COPY # elements (D, E) input to an AND element (F) AND element (F) inputs to two # COPY elements (A, B) # # For the soup example, element B receives an additional input from D, and # implements AND logic instead of COPY nodes = 6 tpm = np.zeros((2**nodes, nodes)) for psi, ps in enumerate(utils.all_states(nodes)): cs = [0 for i in range(nodes)] if ps[5] == 1: cs[0] = 1 if ps[3] == 1 and ps[5] == 1: cs[1] = 1 if ps[0] == 1 and ps[1]: cs[2] = 1 if ps[2] == 1: cs[3] = 1 cs[4] = 1 if ps[3] == 1 and ps[4] == 1: cs[5] = 1 tpm[psi, :] = cs cm = np.array([[0, 0, 1, 0, 0, 0], [0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 1, 0], [0, 1, 0, 0, 0, 1], [0, 0, 0, 0, 0, 1], [1, 1, 0, 0, 0, 0]]) network = Network(tpm, cm) # State all OFF state = (0, 0, 0, 0, 0, 0) assert compute.major_complex(network, state).phi == 0.125 # With D ON (E must also be ON otherwise the state is unreachable) state = (0, 0, 0, 1, 1, 0) assert compute.major_complex(network, state).phi == 0.215278 # Once the connection from D to B is frozen (with D in the ON state), we # recover the degeneracy example state = (0, 0, 0, 1, 1, 0) partition = ((0, 1, 2), (3, 4, 5)) output_indices = (2, 5) blackbox = macro.Blackbox(partition, output_indices) time = 2 sub = macro.MacroSubsystem(network, state, (0, 1, 2, 3, 4, 5), blackbox=blackbox, time_scale=time) assert compute.phi(sub) == 0.638888 # When the connection from D to B is frozen (with D in the OFF state), # element B is inactivated and integration is compromised. state = (0, 0, 0, 0, 0, 0) partition = ((0, 1, 2), (3, 4, 5)) output_indices = (2, 5) blackbox = macro.Blackbox(partition, output_indices) time = 2 sub = macro.MacroSubsystem(network, state, (0, 1, 2, 3, 4, 5), blackbox=blackbox, time_scale=time) assert compute.phi(sub) == 0
def test_blackbox_indices(bb): assert bb.micro_indices == (1, 3, 4) assert bb.macro_indices == (0, 1) assert bb.reindex() == macro.Blackbox(((0, 1), (2, )), (1, 2))
def test_all_blackboxes(): assert list(macro.all_blackboxes((1, 2, 3))) == [ macro.Blackbox(((1, 2), (3, )), (1, 3)), macro.Blackbox(((1, 2), (3, )), (2, 3)), macro.Blackbox(((1, 2), (3, )), (1, 2, 3)), macro.Blackbox(((1, 3), (2, )), (1, 2)), macro.Blackbox(((1, 3), (2, )), (2, 3)), macro.Blackbox(((1, 3), (2, )), (1, 2, 3)), macro.Blackbox(((1, ), (2, 3)), (1, 2)), macro.Blackbox(((1, ), (2, 3)), (1, 3)), macro.Blackbox(((1, ), (2, 3)), (1, 2, 3)), macro.Blackbox(((1, 2, 3), ), (1, )), macro.Blackbox(((1, 2, 3), ), (2, )), macro.Blackbox(((1, 2, 3), ), (3, )), macro.Blackbox(((1, 2, 3), ), (1, 2)), macro.Blackbox(((1, 2, 3), ), (1, 3)), macro.Blackbox(((1, 2, 3), ), (2, 3)), macro.Blackbox(((1, 2, 3), ), (1, 2, 3)), ]