def test_different_states(big): all_off = Network(big.tpm, tuple([0]*5), tuple([0]*5), connectivity_matrix=big.connectivity_matrix) all_on = Network(big.tpm, tuple([1]*5), tuple([1]*5), connectivity_matrix=big.connectivity_matrix) s1 = Subsystem(range(2, 5), all_off) s2 = Subsystem(range(2, 5), all_on) a = s1.nodes[2:] b = s2.nodes[2:] x = cc.NormalizedMechanism(a, s1) y = cc.NormalizedMechanism(b, s2) assert x != y
def test_validate_state_no_error_2(): tpm = np.array([ [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, 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, 1, 1], ]) net = Network(tpm) # Globally impossible state. state = (1, 1, 0, 0) # But locally possible for first two nodes. subsystem = Subsystem(net, state, (0, 1)) validate.state_reachable(subsystem)
def check_concept_caching(net, states, flushcache): flushcache() # Build the networks for each state. networks = {s: Network(net.tpm, net.connectivity_matrix) for s in states} # Empty the cache. flushcache() # Get the complexes for each state with no concept caching. constants.CACHE_CONCEPTS = False no_caching_results = [] for s in states: no_caching_results.append(list(compute.complexes(networks[s], s))) # Empty the cache. flushcache() # Get the complexes for each state with concept caching. constants.CACHE_CONCEPTS = True caching_results = [] for s in states: caching_results.append(list(compute.complexes(networks[s], s))) assert caching_results == no_caching_results
def background_all_on(): """Two OR gates, both ON. If we look at the transition A -> B, then B should be frozen at t-1, and A should have no effect on B. """ tpm = np.array([[0, 0], [1, 1], [1, 1], [1, 1]]) network = Network(tpm) state = (1, 1) return actual.Transition(network, state, state, (0, ), (1, ))
def transition(): """An OR gate with two inputs. The OR gate is ON, others are OFF.""" tpm = np.array([[0, 0.5, 0.5], [0, 0.5, 0.5], [1, 0.5, 0.5], [1, 0.5, 0.5], [1, 0.5, 0.5], [1, 0.5, 0.5], [1, 0.5, 0.5], [1, 0.5, 0.5]]) cm = np.array([[0, 0, 0], [1, 0, 0], [1, 0, 0]]) network = Network(tpm, cm) before_state = (0, 1, 1) after_state = (1, 0, 0) return actual.Transition(network, before_state, after_state, (1, 2), (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 background_all_off(): """Two OR gates, both OFF.""" # fmt: off tpm = np.array([ [0, 0], [1, 1], [1, 1], [1, 1], ]) # fmt: on network = Network(tpm) state = (0, 0) return actual.Transition(network, state, state, (0,), (1,))
def test_rule152_complexes_no_caching(rule152): net = rule152 # Mapping from index of a PyPhi subsystem in network.subsystems to the # index of the corresponding subsystem in the Matlab list of subsets perm = {0: 0, 1: 1, 2: 3, 3: 7, 4: 15, 5: 2, 6: 4, 7: 8, 8: 16, 9: 5, 10: 9, 11: 17, 12: 11, 13: 19, 14: 23, 15: 6, 16: 10, 17: 18, 18: 12, 19: 20, 20: 24, 21: 13, 22: 21, 23: 25, 24: 27, 25: 14, 26: 22, 27: 26, 28: 28, 29: 29, 30: 30} with open('test/data/rule152_results.pkl', 'rb') as f: results = pickle.load(f) # Don't use concept caching for this test. constants.CACHE_CONCEPTS = False for k, result in results.items(): print(net.current_state, net.past_state) # Empty the DB. _flushdb() # Unpack the current/past state from the results key. current_state, past_state = k # Generate the network with the current and past state we're testing. net = Network(rule152.tpm, current_state, past_state, connectivity_matrix=rule152.connectivity_matrix) # Comptue all the complexes, leaving out the first (empty) subsystem # since Matlab doesn't include it in results. complexes = list(compute.complexes(net))[1:] # Check the phi values of all complexes. zz = [(bigmip.phi, result['subsystem_phis'][perm[i]]) for i, bigmip in list(enumerate(complexes))] diff = [utils.phi_eq(bigmip.phi, result['subsystem_phis'][perm[i]]) for i, bigmip in list(enumerate(complexes))] assert all(utils.phi_eq(bigmip.phi, result['subsystem_phis'][perm[i]]) for i, bigmip in list(enumerate(complexes))[:]) # Check the main complex in particular. main = compute.main_complex(net) # Check the phi value of the main complex. assert utils.phi_eq(main.phi, result['phi']) # Check that the nodes are the same. assert (main.subsystem.node_indices == complexes[result['main_complex'] - 1].subsystem.node_indices) # Check that the concept's phi values are the same. result_concepts = [c for c in result['concepts'] if c['is_irreducible']] z = list(zip([c.phi for c in main.unpartitioned_constellation], [c['phi'] for c in result_concepts])) diff = [i for i in range(len(z)) if not utils.phi_eq(z[i][0], z[i][1])] assert all(list(utils.phi_eq(c.phi, result_concepts[i]['phi']) for i, c in enumerate(main.unpartitioned_constellation))) # Check that the minimal cut is the same. assert main.cut == result['cut']
def background_3_node(): """A is MAJ(ABC). B is OR(A, C). C is COPY(A).""" # fmt: off tpm = np.array([ [0, 0, 0], [0, 1, 1], [0, 0, 0], [1, 1, 1], [0, 1, 0], [1, 1, 1], [1, 1, 0], [1, 1, 1], ]) # fmt: on return Network(tpm)
def test_coarsegrain_spatial_degenerate(): # TODO: move to docs? # macro-micro examples from Hoel2016 # Example 2 - Spatial Degenerate # The micro system has a full complex, and big_phi = 0.19 # The optimal coarse-graining groups AB, CD and EF, each with state # mapping ((0, 1), (2)) 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[0] == 1 and ps[1] == 1: cs[2] = 1 cs[3] = 1 if ps[2] == 1 and ps[3] == 1: cs[4] = 1 cs[5] = 1 if ps[4] == 1 and ps[5] == 1: cs[0] = 1 cs[1] = 1 tpm[psi, :] = cs cm = np.array([[0, 0, 1, 1, 0, 0], [0, 0, 1, 1, 0, 0], [0, 0, 0, 0, 1, 1], [0, 0, 0, 0, 1, 1], [1, 1, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0]]) state = (0, 0, 0, 0, 0, 0) net = Network(tpm, cm) mc = compute.major_complex(net, state) assert mc.phi == 0.194445 partition = ((0, 1), (2, 3), (4, 5)) grouping = (((0, 1), (2, )), ((0, 1), (2, )), ((0, 1), (2, ))) coarse = macro.CoarseGrain(partition, grouping) sub = macro.MacroSubsystem(net, state, range(net.size), coarse_grain=coarse) sia = compute.sia(sub) assert sia.phi == 0.834183
def test_background_noised(): tpm = np.array([[0, 0], [1, 1], [1, 1], [1, 1]]) network = Network(tpm) state = (1, 1) transition = actual.Transition(network, state, state, (0, ), (1, ), noise_background=True) assert transition._ratio(Direction.EFFECT, (0, ), (1, )) == 0.415037 assert transition._ratio(Direction.CAUSE, (1, ), (0, )) == 0.415037 # Elements outside the transition are also frozen transition = actual.Transition(network, state, state, (0, ), (0, ), noise_background=True) assert np.array_equal(transition.cause_system.tpm, network.tpm) assert np.array_equal(transition.effect_system.tpm, network.tpm)
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 test_validate_network_wrong_cm_size(s): with pytest.raises(ValueError): Network(s.network.tpm, np.ones(16).reshape(4, 4))
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_specify_elements_with_labels(standard): network = Network(standard.tpm, node_labels=('A', 'B', 'C')) subsystem = Subsystem(network, (0, 0, 0), ('B', 'C')) assert subsystem.node_indices == (1, 2) assert tuple(node.label for node in subsystem.nodes) == ('B', 'C') assert str(subsystem) == 'Subsystem(B, C)'
def test_rule152_complexes_no_caching(rule152): net = rule152 # Mapping from index of a PyPhi subsystem in network.subsystems to the # index of the corresponding subsystem in the Matlab list of subsets perm = { 0: 0, 1: 1, 2: 3, 3: 7, 4: 15, 5: 2, 6: 4, 7: 8, 8: 16, 9: 5, 10: 9, 11: 17, 12: 11, 13: 19, 14: 23, 15: 6, 16: 10, 17: 18, 18: 12, 19: 20, 20: 24, 21: 13, 22: 21, 23: 25, 24: 27, 25: 14, 26: 22, 27: 26, 28: 28, 29: 29, 30: 30, } with open("test/data/rule152_results.pkl", "rb") as f: results = pickle.load(f) # Don't use concept caching for this test. constants.CACHE_CONCEPTS = False for state, result in results.items(): # Empty the DB. _flushdb() # Unpack the state from the results key. # Generate the network with the state we're testing. net = Network(rule152.tpm, state, cm=rule152.cm) # Comptue all the complexes, leaving out the first (empty) subsystem # since Matlab doesn't include it in results. complexes = list(compute.complexes(net))[1:] # Check the phi values of all complexes. zz = [(sia.phi, result["subsystem_phis"][perm[i]]) for i, sia in list(enumerate(complexes))] diff = [ utils.eq(sia.phi, result["subsystem_phis"][perm[i]]) for i, sia in list(enumerate(complexes)) ] assert all( utils.eq(sia.phi, result["subsystem_phis"][perm[i]]) for i, sia in list(enumerate(complexes))[:]) # Check the major complex in particular. major = compute.major_complex(net) # Check the phi value of the major complex. assert utils.eq(major.phi, result["phi"]) # Check that the nodes are the same. assert (major.subsystem.node_indices == complexes[ result["major_complex"] - 1].subsystem.node_indices) # Check that the concept's phi values are the same. result_concepts = [ c for c in result["concepts"] if c["is_irreducible"] ] z = list( zip([c.phi for c in major.ces], [c["phi"] for c in result_concepts])) diff = [i for i in range(len(z)) if not utils.eq(z[i][0], z[i][1])] assert all( list( utils.eq(c.phi, result_concepts[i]["phi"]) for i, c in enumerate(major.ces))) # Check that the minimal cut is the same. assert major.cut == result["cut"]