def test_mismatch_num_input_ports_with_default_variable_error(self): with pytest.raises(MechanismError) as error_text: TransferMechanism(default_variable=[[0], [0]], input_ports=[[32]]) assert mismatches_specified_default_variable_error_text in str( error_text.value)
def transfer_mech(self): return TransferMechanism(function=pnl.Logistic)
def test_reinforcement(): input_layer = TransferMechanism( default_variable=[0, 0, 0], name='Input Layer', ) action_selection = TransferMechanism( default_variable=[0, 0, 0], function=SoftMax( output=PROB, gain=1.0, ), name='Action Selection', ) p = Process( default_variable=[0, 0, 0], size=3, pathway=[input_layer, action_selection], learning=LearningProjection(learning_function=Reinforcement( learning_rate=0.05)), target=0, ) # print ('reward prediction weights: \n', action_selection.input_states[0].path_afferents[0].matrix) # print ('targetMechanism weights: \n', action_selection.output_states.sendsToProjections[0].matrix) reward_values = [10, 10, 10] # Must initialize reward (won't be used, but needed for declaration of lambda function) action_selection.output_state.value = [0, 0, 1] # Get reward value for selected action) reward = lambda: [ reward_values[int(np.nonzero(action_selection.output_state.value)[0])] ] def print_header(system): print("\n\n**** TRIAL: ", system.scheduler_processing.clock.simple_time) def show_weights(): print( 'Reward prediction weights: \n', action_selection.input_states[0].path_afferents[0].get_mod_matrix( s)) print('\nAction selected: {}; predicted reward: {}'.format( np.nonzero(action_selection.output_state.value)[0][0], action_selection.output_state.value[np.nonzero( action_selection.output_state.value)[0][0]], )) input_list = {input_layer: [[1, 1, 1]]} s = System( processes=[p], # learning_rate=0.05, targets=[0], ) results = s.run( num_trials=10, inputs=input_list, targets=reward, call_before_trial=functools.partial(print_header, s), call_after_trial=show_weights, ) results_list = [] for elem in s.results: for nested_elem in elem: nested_elem = nested_elem.tolist() try: iter(nested_elem) except TypeError: nested_elem = [nested_elem] results_list.extend(nested_elem) mech_objective_action = s.mechanisms[2] mech_learning_input_to_action = s.mechanisms[3] reward_prediction_weights = action_selection.input_states[ 0].path_afferents[0] expected_output = [ (input_layer.get_output_values(s), [np.array([1., 1., 1.])]), (action_selection.get_output_values(s), [np.array([0., 3.71496434, 0.])]), (pytest.helpers.expand_np_ndarray( mech_objective_action.get_output_values(s)), pytest.helpers.expand_np_ndarray( [np.array([6.28503566484375]), np.array(39.50167330835792)])), (pytest.helpers.expand_np_ndarray( mech_learning_input_to_action.get_output_values(s)), pytest.helpers.expand_np_ndarray([[ np.array([0., 0.31425178324218755, 0.]), np.array([0., 0.31425178324218755, 0.]) ]])), (reward_prediction_weights.get_mod_matrix(s), np.array([ [1., 0., 0.], [0., 4.02921612, 0.], [0., 0., 1.8775], ])), (results, [ [np.array([0., 1., 0.])], [np.array([0., 1.45, 0.])], [np.array([0., 0., 1.])], [np.array([0., 1.8775, 0.])], [np.array([0., 2.283625, 0.])], [np.array([0., 2.66944375, 0.])], [np.array([0., 0., 1.45])], [np.array([0., 3.03597156, 0.])], [np.array([0., 3.38417298, 0.])], [np.array([0., 3.71496434, 0.])], ]), ] for i, exp in enumerate(expected_output): val, expected = exp np.testing.assert_allclose( val, expected, err_msg='Failed on expected_output[{0}]'.format(i))
def test_runtime_param_error(self): T = TransferMechanism() with pytest.raises(ComponentError) as error_text: T.execute(runtime_params={"glunfump": 10.0}, input=2.0) assert ("Invalid specification in runtime_params arg for TransferMechanism" in str(error_text.value) and "'glunfump'" in str(error_text.value))
def test_LCAMechanism_length_2(self): T = TransferMechanism(function=Linear(slope=1.0), size=2) L = LCAMechanism(function=Linear(slope=2.0), size=2, self_excitation=3.0, leak=0.5, competition=1.0, time_step_size=0.1) P = Process(pathway=[T, L]) S = System(processes=[P]) L.reinitialize_when = Never() # - - - - - - - Equations to be executed - - - - - - - # new_transfer_input = # previous_transfer_input # + (leak * previous_transfer_input_1 + self_excitation * result1 + competition * result2 + outside_input1) * dt # + noise # result = new_transfer_input*2.0 # recurrent_matrix = [[3.0]] # - - - - - - - - - - - - - - - - - - - - - - - - - - results = [] def record_execution(): results.append(L.parameters.value.get(S)[0]) S.run(inputs={T: [1.0, 2.0]}, num_trials=3, call_after_trial=record_execution) # - - - - - - - TRIAL 1 - - - - - - - # new_transfer_input_1 = 0.0 + ( 0.5 * 0.0 + 3.0 * 0.0 - 1.0*0.0 + 1.0)*0.1 + 0.0 = 0.1 # f(new_transfer_input_1) = 0.1 * 2.0 = 0.2 # new_transfer_input_2 = 0.0 + ( 0.5 * 0.0 + 3.0 * 0.0 - 1.0*0.0 + 2.0)*0.1 + 0.0 = 0.2 # f(new_transfer_input_2) = 0.2 * 2.0 = 0.4 # - - - - - - - TRIAL 2 - - - - - - - # new_transfer_input = 0.1 + ( 0.5 * 0.1 + 3.0 * 0.2 - 1.0*0.4 + 1.0)*0.1 + 0.0 = 0.225 # f(new_transfer_input) = 0.265 * 2.0 = 0.45 # new_transfer_input_2 = 0.2 + ( 0.5 * 0.2 + 3.0 * 0.4 - 1.0*0.2 + 2.0)*0.1 + 0.0 = 0.51 # f(new_transfer_input_2) = 0.1 * 2.0 = 1.02 # - - - - - - - TRIAL 3 - - - - - - - # new_transfer_input = 0.225 + ( 0.5 * 0.225 + 3.0 * 0.45 - 1.0*1.02 + 1.0)*0.1 + 0.0 = 0.36925 # f(new_transfer_input) = 0.36925 * 2.0 = 0.7385 # new_transfer_input_2 = 0.51 + ( 0.5 * 0.51 + 3.0 * 1.02 - 1.0*0.45 + 2.0)*0.1 + 0.0 = 0.9965 # f(new_transfer_input_2) = 0.9965 * 2.0 = 1.463 assert np.allclose(results, [[0.2, 0.4], [0.45, 1.02], [0.7385, 1.993]])
def test_input_specification_multiple_nested_compositions(self): # level_0 composition --------------------------------- innermost composition level_0 = Composition(name="level_0") A0 = TransferMechanism(name="A0", default_variable=[[0.], [0.]], function=Linear(slope=1.)) B0 = TransferMechanism(name="B0", function=Linear(slope=2.)) level_0.add_node(A0) level_0.add_node(B0) level_0.add_projection(MappingProjection(), A0, B0) level_0.add_projection( MappingProjection(sender=A0.output_states[1], receiver=B0), A0, B0) level_0._analyze_graph() # level_1 composition --------------------------------- level_1 = Composition(name="level_1") A1 = TransferMechanism(name="A1", function=Linear(slope=1.)) B1 = TransferMechanism(name="B1", function=Linear(slope=2.)) level_1.add_node(level_0) level_1.add_node(A1) level_1.add_node(B1) level_1.add_projection(MappingProjection(), level_0, B1) level_1.add_projection(MappingProjection(), A1, B1) level_1._analyze_graph() # level_2 composition --------------------------------- outermost composition level_2 = Composition(name="level_2") A2 = TransferMechanism(name="A2", size=2, function=Linear(slope=1.)) B2 = TransferMechanism(name="B2", function=Linear(slope=2.)) level_2.add_node(level_1) level_2.add_node(A2) level_2.add_node(B2) level_2.add_projection(MappingProjection(), level_1, B2) level_2.add_projection(MappingProjection(), A2, B2) level_2._analyze_graph() sched = Scheduler(composition=level_2) # FIX: order of InputStates in each inner composition (level_0 and level_1) level_2.run(inputs={ A2: [[1.0, 2.0]], level_1: { A1: [[1.0]], level_0: { A0: [[1.0], [2.0]] } } }, scheduler_processing=sched) # level_0 output = 2.0 * (1.0 + 2.0) = 6.0 assert np.allclose(level_0.get_output_values(level_2), [6.0]) # level_1 output = 2.0 * (1.0 + 6.0) = 14.0 assert np.allclose(level_1.get_output_values(level_2), [14.0]) # level_2 output = 2.0 * (1.0 + 2.0 + 14.0) = 34.0 assert np.allclose(level_2.get_output_values(level_2), [34.0])
def test_params_for_output_port_variable_and_value(self): T1 = TransferMechanism(output_ports=['FIRST', 'SECOND']) T2 = TransferMechanism() T3 = TransferMechanism() # C = Composition(pathways=[[T1.output_ports['FIRST'],T2], # [T1.output_ports['SECOND'],T3]]) # FIX 5/8/20 [JDC]: NEED TO ADD PROJECTIONS SINCE CAN'T SPECIFIY OUTPUT PORT IN PATHWAY P1 = MappingProjection(sender=T1.output_ports['FIRST'], receiver=T2) P2 = MappingProjection(sender=T1.output_ports['SECOND'], receiver=T2) C = Composition(nodes=[T1,T2], projections=[P1,P2]) T1.output_ports['SECOND'].function.slope = 1.5 # Run 0: Test of both OutputPort variables assigned C.run(inputs={T1: 10.0}, runtime_params={ T1: {OUTPUT_PORT_PARAMS: {'variable': 2}}} ) assert T1.value == 0.0 # T1 did not execute since both of its OutputPorts were assigned a variable assert T2.value == 5 # (2*1 + 2*1.5) # Run 1: Test of both OutputPort values assigned C.run(inputs={T1: 11.0}, runtime_params={ T1: {OUTPUT_PORT_PARAMS: {'value': 3}}} ) assert T1.value == 0.0 # T1 did not execute since both of its OutputPorts were assigned a value assert T2.value == 6 # (3 + 3) # Run 2: Test of on OutputPort variable and the other value assigned C.run(inputs={T1: 12.0}, runtime_params={ T1: {OUTPUT_PORT_PARAMS: { 'FIRST': {'value': 5}, 'SECOND': {'variable': 13}}}} ) assert T1.value == 0.0 # T1 did not execute since both of its OutputPorts were assigned a variable or value assert T2.value == 24.5 # (5 + 13*1.5) # Run 3: Tests of numerical accuracy over all permutations of assignments C.run(inputs={T1: 2.0}, runtime_params={ T1: { OUTPUT_PORT_PARAMS: { 'variable':(1.7, AtTrial(1)), # variable of all Projection to all ParameterPorts 'value':(3, AtTrial(2)), 'FIRST': {'variable':(5, Any(AtTrial(3),AtTrial(5),AtTrial(9),AtTrial(11))), 'value':(7, Any(AtTrial(6),AtTrial(8),AtTrial(10),AtTrial(12))) }, 'SECOND': {'variable': (11, Any(AtTrial(4),AtTrial(5),AtTrial(10),AtTrial(11),AtTrial(12))), 'value': (13, Any(AtTrial(7),AtTrial(8),AtTrial(9),AtTrial(11),AtTrial(12))) }, }, }, T2: { 'slope': 3 }, }, num_trials=13 ) assert np.allclose(C.results,[ # OutputPort Conditions satisfied: np.array([[5]]), # Run 0, Trial 0: See above np.array([[6]]), # Run 1, Trial 0: See above np.array([[24.5]]), # Run 2, Trial 0: See above np.array([[15]]), # Run 3, Trial 0: None (2*1 + 2*1.5) * 3 np.array([[12.75]]), # Run 3, Trial 1: variable general (1.7*1 + 1.7*1.5) * 3 np.array([[18]]), # Run 3, Trial 2: value general (3*1 + 3*1) * 3 np.array([[24]]), # Run 3, Trial 3: FIRST variable (5*1 + 2*1.5) * 3 np.array([[55.5]]), # Run 3, Trial 4: SECOND variable (2*1 + 11*1.5) * 3 np.array([[64.5]]), # Run 3, Trial 5: FIRST and SECOND variable (5*1 + 11*1.5) * 3 np.array([[30]]), # Run 3, Trial 6: FIRST value (7 + 2*1.5) * 3 np.array([[45]]), # Run 3, Trial 7: SECOND value (2*1 + 13) * 3 np.array([[60]]), # Run 3, Trial 8: FIRST and SECOND value (7+13) * 3 np.array([[54]]), # Run 3, Trial 9: FIRST variable and SECOND value (5*1 + 13) * 3 np.array([[70.5]]), # Run 3, Trial 10: FIRST value and SECOND variable (7 + 11*1.5) * 3 np.array([[54]]), # Run 3, Trial 11: FIRST and SECOND variable and SECOND value (5*1 + 13) * 3 np.array([[60]]), # Run 3, Trial 12: FIRST and SECOND value and SECOND variable (7+13) * 3 ])
def test_InputPort_mismatches_default(self): with pytest.raises(MechanismError) as error_text: i = InputPort(reference_value=[0, 0, 0]) TransferMechanism(default_variable=[0, 0], input_ports=[i]) assert mismatches_specified_default_variable_error_text in str( error_text.value)
def test_projection_no_args_projection_spec_with_default(self): p = MappingProjection() T = TransferMechanism(default_variable=[[0, 0]], input_ports=[p]) np.testing.assert_array_equal(T.defaults.variable, np.array([[0, 0]])) assert len(T.input_ports) == 1
def test_inputPort_class(self): T = TransferMechanism(input_ports=[InputPort]) np.testing.assert_array_equal(T.defaults.variable, [InputPort.defaults.variable]) assert len(T.input_ports) == 1
def test_inputPort_class_with_variable(self): T = TransferMechanism(default_variable=[[0, 0]], input_ports=[InputPort]) np.testing.assert_array_equal(T.defaults.variable, np.array([[0, 0]])) assert len(T.input_ports) == 1
def test_params_override(self): T = TransferMechanism(input_ports=[[0], [0]], params={INPUT_PORTS: [[0, 0], [0]]}) assert T.defaults.variable.shape == np.array([[0, 0], [0]], dtype=object).shape assert len(T.input_ports) == 2
def test_dict_with_variable(self): T = TransferMechanism(input_ports=[{NAME: 'FIRST', VARIABLE: [0, 0]}]) np.testing.assert_array_equal(T.defaults.variable, np.array([[0, 0]])) assert len(T.input_ports) == 1
class TestInputPortSpec: # ------------------------------------------------------------------------------------------------ # InputPort SPECIFICATIONS # ------------------------------------------------------------------------------------------------ # TEST 1a # Match of default_variable and specification of multiple InputPorts by value and string def test_match_with_default_variable(self): T = TransferMechanism(default_variable=[[0, 0], [0]], input_ports=[[32, 24], 'HELLO']) assert T.defaults.variable.shape == np.array([[0, 0], [0]], dtype=object).shape assert len(T.input_ports) == 2 assert T.input_ports[1].name == 'HELLO' # # PROBLEM WITH input FOR RUN: # my_mech_2.execute() # ------------------------------------------------------------------------------------------------ # # TEST 1b # # Match of default_variable and specification of multiple InputPorts by value and string # # def test_match_with_default_variable(self): # # T = TransferMechanism( # default_variable=[[0], [0]], # input_ports=[[32, 24], 'HELLO'] # ) # assert T.defaults.variable.shape == np.array([[0, 0], [0]], dtype=object).shape # assert len(T.input_ports) == 2 # assert T.input_ports[1].name == 'HELLO' # # ------------------------------------------------------------------------------------------------ # # TEST 2 # # Mismatch between InputPort variable specification and corresponding item of owner Mechanism's variable # # # Deprecated this test as length of variable of each InputPort should be allowed to vary from # # corresponding item of Mechanism's default variable, so long as each is 1d and then number of InputPorts # # is consistent with number of items in Mechanism's default_variable (i.e., its length in axis 0). # # def test_mismatch_with_default_variable_error(self): # # with pytest.raises(InputPortError) as error_text: # TransferMechanism( # default_variable=[[0], [0]], # input_ports=[[32, 24], 'HELLO'] # ) # assert mismatches_default_variable_format_error_text in str(error_text.value) # ------------------------------------------------------------------------------------------------ # TEST 2a # Mismatch between InputPort variable specification and corresponding item of owner Mechanism's variable # Replacement for original TEST 2, which insures that the number InputPorts specified corresponds to the # number of items in the Mechanism's default_variable (i.e., its length in axis 0). def test_fewer_input_ports_than_default_variable_error(self): with pytest.raises(PortError) as error_text: TransferMechanism(default_variable=[[0], [0]], input_ports=['HELLO']) assert mismatches_fewer_input_ports_than_default_variable_error_text in str( error_text.value) # ------------------------------------------------------------------------------------------------ # TEST 2b # Mismatch between InputPort variable specification and corresponding item of owner Mechanism's variable # Replacement for original TEST 2, which insures that the number InputPorts specified corresponds to the # number of items in the Mechanism's default_variable (i.e., its length in axis 0). def test_more_input_ports_than_default_variable_error(self): with pytest.raises(PortError) as error_text: TransferMechanism(default_variable=[[0], [0]], input_ports=[[32], [24], 'HELLO']) assert mismatches_more_input_ports_than_default_variable_error_text in str( error_text.value) # ------------------------------------------------------------------------------------------------ # TEST 2c # Mismatch between InputPort variable specification and corresponding item of owner Mechanism's variable # Replacement for original TEST 2, which insures that the number InputPorts specified corresponds to the # number of items in the Mechanism's default_variable (i.e., its length in axis 0). def test_mismatch_num_input_ports_with_default_variable_error(self): with pytest.raises(MechanismError) as error_text: TransferMechanism(default_variable=[[0], [0]], input_ports=[[32]]) assert mismatches_specified_default_variable_error_text in str( error_text.value) # ------------------------------------------------------------------------------------------------ # TEST 2d # Mismatch between dimensionality of InputPort variable owner Mechanism's variable # FIX: This needs to be handled better in Port._parse_port_spec (~Line 3018): # seems to be adding the two axis2 values def test_mismatch_dim_input_ports_with_default_variable_error(self): with pytest.raises(PortError) as error_text: TransferMechanism(default_variable=[[0], [0]], input_ports=[[[32], [24]], 'HELLO']) assert 'Port value' in str( error_text.value) and 'does not match reference_value' in str( error_text.value) # ------------------------------------------------------------------------------------------------ # TEST 3 # Override of input_ports (mis)specification by INPUT_PORTS entry in params specification dict def test_override_by_dict_spec(self): T = TransferMechanism(default_variable=[[0, 0], [0]], input_ports=[[32], 'HELLO'], params={INPUT_PORTS: [[32, 24], 'HELLO']}) assert T.defaults.variable.shape == np.array([[0, 0], [0]], dtype=object).shape assert len(T.input_ports) == 2 assert T.input_ports[1].name == 'HELLO' # # PROBLEM WITH input FOR RUN: # my_mech_2.execute() # ------------------------------------------------------------------------------------------------ # TEST 4 # Specification using input_ports without default_variable def test_transfer_mech_input_ports_no_default_variable(self): # PROBLEM: SHOULD GENERATE TWO INPUT_PORTS ( # ONE WITH [[32],[24]] AND OTHER WITH [[0]] AS VARIABLE INSTANCE DEFAULT # INSTEAD, SEEM TO IGNORE InputPort SPECIFICATIONS AND JUST USE DEFAULT_VARIABLE # NOTE: WORKS FOR ObjectiveMechanism, BUT NOT TransferMechanism T = TransferMechanism(input_ports=[[32, 24], 'HELLO']) assert T.defaults.variable.shape == np.array([[0, 0], [0]], dtype=object).shape assert len(T.input_ports) == 2 assert T.input_ports[1].name == 'HELLO' # ------------------------------------------------------------------------------------------------ # TEST 5 # Specification using INPUT_PORTS entry in params specification dict without default_variable def test_transfer_mech_input_ports_specification_dict_no_default_variable( self): # PROBLEM: SHOULD GENERATE TWO INPUT_PORTS ( # ONE WITH [[32],[24]] AND OTHER WITH [[0]] AS VARIABLE INSTANCE DEFAULT # INSTEAD, SEEM TO IGNORE InputPort SPECIFICATIONS AND JUST USE DEFAULT_VARIABLE # NOTE: WORKS FOR ObjectiveMechanism, BUT NOT TransferMechanism T = TransferMechanism(params={INPUT_PORTS: [[32, 24], 'HELLO']}) assert T.defaults.variable.shape == np.array([[0, 0], [0]], dtype=object).shape assert len(T.input_ports) == 2 assert T.input_ports[1].name == 'HELLO' # ------------------------------------------------------------------------------------------------ # TEST 6 # Mechanism specification def test_mech_spec_list(self): R1 = TransferMechanism(output_ports=['FIRST', 'SECOND']) T = TransferMechanism(default_variable=[[0]], input_ports=[R1]) np.testing.assert_array_equal(T.defaults.variable, np.array([[0]])) assert len(T.input_ports) == 1 assert T.input_port.path_afferents[0].sender == R1.output_port T.execute() # ------------------------------------------------------------------------------------------------ # TEST 7 # Mechanism specification outside of a list def test_mech_spec_standalone(self): R1 = TransferMechanism(output_ports=['FIRST', 'SECOND']) # Mechanism outside of list specification T = TransferMechanism(default_variable=[[0]], input_ports=R1) np.testing.assert_array_equal(T.defaults.variable, np.array([[0]])) assert len(T.input_ports) == 1 assert T.input_port.path_afferents[0].sender == R1.output_port T.execute() # ------------------------------------------------------------------------------------------------ # TEST 8 # OutputPort specification def test_output_port_spec_list_two_items(self): R1 = TransferMechanism(output_ports=['FIRST', 'SECOND']) T = TransferMechanism( default_variable=[[0], [0]], input_ports=[R1.output_ports['FIRST'], R1.output_ports['SECOND']]) np.testing.assert_array_equal(T.defaults.variable, np.array([[0], [0]])) assert len(T.input_ports) == 2 assert T.input_ports.names[0] == 'InputPort-0' assert T.input_ports.names[1] == 'InputPort-1' for input_port in T.input_ports: for projection in input_port.path_afferents: assert projection.sender.owner is R1 T.execute() # ------------------------------------------------------------------------------------------------ # TEST 9 # OutputPort specification outside of a list def test_output_port_spec_standalone(self): R1 = TransferMechanism(output_ports=['FIRST', 'SECOND']) T = TransferMechanism(default_variable=[0], input_ports=R1.output_ports['FIRST']) np.testing.assert_array_equal(T.defaults.variable, np.array([[0]])) assert len(T.input_ports) == 1 assert T.input_ports.names[0] == 'InputPort-0' T.input_port.path_afferents[0].sender == R1.output_port T.execute() # ------------------------------------------------------------------------------------------------ # TEST 10 # OutputPorts in PROJECTIONS entries of a specification dictiontary, using with names (and one outside of a list) def test_specification_dict(self): R1 = TransferMechanism(output_ports=['FIRST', 'SECOND']) T = TransferMechanism(default_variable=[[0], [0]], input_ports=[{ NAME: 'FROM DECISION', PROJECTIONS: [R1.output_ports['FIRST']] }, { NAME: 'FROM RESPONSE_TIME', PROJECTIONS: R1.output_ports['SECOND'] }]) np.testing.assert_array_equal(T.defaults.variable, np.array([[0], [0]])) assert len(T.input_ports) == 2 assert T.input_ports.names[0] == 'FROM DECISION' assert T.input_ports.names[1] == 'FROM RESPONSE_TIME' for input_port in T.input_ports: for projection in input_port.path_afferents: assert projection.sender.owner is R1 T.execute() # ------------------------------------------------------------------------------------------------ # TEST 11 # default_variable override of value of OutputPort specification def test_default_variable_override_mech_list(self): R2 = TransferMechanism(size=3) # default_variable override of OutputPort.value T = TransferMechanism(default_variable=[[0, 0]], input_ports=[R2]) np.testing.assert_array_equal(T.defaults.variable, np.array([[0, 0]])) assert len(T.input_ports) == 1 assert len( T.input_port.path_afferents[0].sender.defaults.variable) == 3 assert len(T.input_port.defaults.variable[0]) == 2 T.execute() # ------------------------------------------------------------------------------------------------ # TEST 12 # 2-item tuple specification with default_variable override of OutputPort.value def test_2_item_tuple_spec(self): R2 = TransferMechanism(size=3) T = TransferMechanism(size=2, input_ports=[(R2, np.zeros((3, 2)))]) np.testing.assert_array_equal(T.defaults.variable, np.array([[0, 0]])) assert len(T.input_ports) == 1 assert len( T.input_port.path_afferents[0].sender.defaults.variable) == 3 assert T.input_port.socket_width == 2 T.execute() # ------------------------------------------------------------------------------------------------ # TEST 12.1 # 2-item tuple specification with value as first item (and no size specification for T) def test_2_item_tuple_value_for_first_item(self): R2 = TransferMechanism(size=3) T = TransferMechanism(input_ports=[([0, 0], R2)]) np.testing.assert_array_equal(T.defaults.variable, np.array([[0, 0]])) assert len(T.input_ports) == 1 assert T.input_port.path_afferents[0].sender.socket_width == 3 assert T.input_port.socket_width == 2 T.execute() # ------------------------------------------------------------------------------------------------ # TEST 13 # 4-item tuple Specification def test_projection_tuple_with_matrix_spec(self): R2 = TransferMechanism(size=3) T = TransferMechanism(size=2, input_ports=[(R2, None, None, np.zeros((3, 2)))]) np.testing.assert_array_equal(T.defaults.variable, np.array([[0, 0]])) assert len(T.input_ports) == 1 assert T.input_port.path_afferents[0].sender.defaults.variable.shape[ -1] == 3 assert T.input_port.socket_width == 2 T.execute() # ------------------------------------------------------------------------------------------------ # TEST 14 # Standalone Projection specification def test_projection_list(self): R2 = TransferMechanism(size=3) P = MappingProjection(sender=R2) T = TransferMechanism(size=2, input_ports=[P]) np.testing.assert_array_equal(T.defaults.variable, np.array([[0, 0]])) assert len(T.input_ports) == 1 assert len( T.input_port.path_afferents[0].sender.defaults.variable) == 3 assert len(T.input_port.defaults.variable) == 2 T.execute() # ------------------------------------------------------------------------------------------------ # TEST 15 # Projection specification in Tuple def test_projection_in_tuple(self): R2 = TransferMechanism(size=3) P = MappingProjection(sender=R2) T = TransferMechanism(size=2, input_ports=[(R2, None, None, P)]) np.testing.assert_array_equal(T.defaults.variable, np.array([[0, 0]])) assert len(T.input_ports) == 1 assert len( T.input_port.path_afferents[0].sender.defaults.variable) == 3 assert len(T.input_port.defaults.variable) == 2 T.execute() # ------------------------------------------------------------------------------------------------ # TEST 16 # PROJECTIONS specification in InputPort specification dictionary def test_projection_in_specification_dict(self): R1 = TransferMechanism(output_ports=['FIRST', 'SECOND']) T = TransferMechanism(input_ports=[{ NAME: 'My InputPort with Two Projections', PROJECTIONS: [R1.output_ports['FIRST'], R1.output_ports['SECOND']] }]) np.testing.assert_array_equal(T.defaults.variable, np.array([[0]])) assert len(T.input_ports) == 1 assert T.input_port.name == 'My InputPort with Two Projections' for input_port in T.input_ports: for projection in input_port.path_afferents: assert projection.sender.owner is R1 T.execute() # ------------------------------------------------------------------------------------------------ # TEST 17 # MECHANISMS/OUTPUT_PORTS entries in params specification dict def test_output_port_in_specification_dict(self): R1 = TransferMechanism(output_ports=['FIRST', 'SECOND']) T = TransferMechanism(input_ports=[{ MECHANISM: R1, OUTPUT_PORTS: ['FIRST', 'SECOND'] }]) np.testing.assert_array_equal(T.defaults.variable, np.array([[0]])) assert len(T.input_ports) == 1 for input_port in T.input_ports: for projection in input_port.path_afferents: assert projection.sender.owner is R1 # ------------------------------------------------------------------------------------------------ # TEST 18 # String specification with variable specification def test_dict_with_variable(self): T = TransferMechanism(input_ports=[{NAME: 'FIRST', VARIABLE: [0, 0]}]) np.testing.assert_array_equal(T.defaults.variable, np.array([[0, 0]])) assert len(T.input_ports) == 1 # ------------------------------------------------------------------------------------------------ # TEST 19 # String specification with variable specification conflicts with default_variable def test_dict_with_variable_matches_default(self): T = TransferMechanism(default_variable=[0, 0], input_ports=[{ NAME: 'FIRST', VARIABLE: [0, 0] }]) np.testing.assert_array_equal(T.defaults.variable, np.array([[0, 0]])) assert len(T.input_ports) == 1 # ------------------------------------------------------------------------------------------------ # TEST 20 def test_dict_with_variable_matches_default_2(self): T = TransferMechanism(default_variable=[[0, 0]], input_ports=[{ NAME: 'FIRST', VARIABLE: [0, 0] }]) np.testing.assert_array_equal(T.defaults.variable, np.array([[0, 0]])) assert len(T.input_ports) == 1 # ------------------------------------------------------------------------------------------------ # TEST 21 def test_dict_with_variable_matches_default_multiple_input_ports(self): T = TransferMechanism(default_variable=[[0, 0], [0]], input_ports=[{ NAME: 'FIRST', VARIABLE: [0, 0] }, { NAME: 'SECOND', VARIABLE: [0] }]) assert T.defaults.variable.shape == np.array([[0, 0], [0]], dtype=object).shape assert len(T.input_ports) == 2 # ------------------------------------------------------------------------------------------------ # TEST 22 def test_dict_with_variable_mismatches_default(self): with pytest.raises(MechanismError) as error_text: TransferMechanism(default_variable=[[0]], input_ports=[{ NAME: 'FIRST', VARIABLE: [0, 0] }]) assert mismatches_specified_default_variable_error_text in str( error_text.value) # ------------------------------------------------------------------------------------------------ # TEST 23 def test_dict_with_variable_mismatches_default_multiple_input_ports(self): with pytest.raises(MechanismError) as error_text: TransferMechanism(default_variable=[[0], [0]], input_ports=[{ NAME: 'FIRST', VARIABLE: [0, 0] }, { NAME: 'SECOND', VARIABLE: [0] }]) assert mismatches_specified_default_variable_error_text in str( error_text.value) # ------------------------------------------------------------------------------------------------ # TEST 24 def test_dict_with_variable_matches_size(self): T = TransferMechanism(size=2, input_ports=[{ NAME: 'FIRST', VARIABLE: [0, 0] }]) np.testing.assert_array_equal(T.defaults.variable, np.array([[0, 0]])) assert len(T.input_ports) == 1 # ------------------------------------------------------------------------------------------------ # TEST 25 def test_dict_with_variable_mismatches_size(self): with pytest.raises(MechanismError) as error_text: TransferMechanism(size=1, input_ports=[{ NAME: 'FIRST', VARIABLE: [0, 0] }]) assert mismatches_size_error_text in str(error_text.value) # ------------------------------------------------------------------------------------------------ # TEST 26 def test_params_override(self): T = TransferMechanism(input_ports=[[0], [0]], params={INPUT_PORTS: [[0, 0], [0]]}) assert T.defaults.variable.shape == np.array([[0, 0], [0]], dtype=object).shape assert len(T.input_ports) == 2 # ------------------------------------------------------------------------------------------------ # TEST 28 def test_inputPort_class(self): T = TransferMechanism(input_ports=[InputPort]) np.testing.assert_array_equal(T.defaults.variable, [InputPort.defaults.variable]) assert len(T.input_ports) == 1 # ------------------------------------------------------------------------------------------------ # TEST 29 def test_inputPort_class_with_variable(self): T = TransferMechanism(default_variable=[[0, 0]], input_ports=[InputPort]) np.testing.assert_array_equal(T.defaults.variable, np.array([[0, 0]])) assert len(T.input_ports) == 1 # ------------------------------------------------------------------------------------------------ # TEST 30 def test_InputPort_mismatches_default(self): with pytest.raises(MechanismError) as error_text: i = InputPort(reference_value=[0, 0, 0]) TransferMechanism(default_variable=[0, 0], input_ports=[i]) assert mismatches_specified_default_variable_error_text in str( error_text.value) # ------------------------------------------------------------------------------------------------ # TEST 31 def test_projection_with_matrix_and_sender(self): m = TransferMechanism(size=2) p = MappingProjection(sender=m, matrix=[[0, 0, 0], [0, 0, 0]]) T = TransferMechanism(input_ports=[p]) np.testing.assert_array_equal(T.defaults.variable, np.array([[0, 0, 0]])) assert len(T.input_ports) == 1 # ------------------------------------------------------------------------------------------------ # TEST 32 def tests_for_projection_with_matrix_and_sender_mismatches_default(self): with pytest.raises(MechanismError) as error_text: m = TransferMechanism(size=2) p = MappingProjection(sender=m, matrix=[[0, 0, 0], [0, 0, 0]]) TransferMechanism(default_variable=[0, 0], input_ports=[p]) assert mismatches_specified_default_variable_error_text in str( error_text.value) with pytest.raises(FunctionError) as error_text: m = TransferMechanism(size=3, output_ports=[pnl.MEAN]) p = MappingProjection(sender=m, matrix=[[0, 0, 0], [0, 0, 0]]) T = TransferMechanism(input_ports=[p]) assert re.match(mismatches_specified_matrix_pattern, str(error_text.value)) with pytest.raises(FunctionError) as error_text: m2 = TransferMechanism(size=2, output_ports=[pnl.MEAN]) p2 = MappingProjection(sender=m2, matrix=[[1, 1, 1], [1, 1, 1]]) T2 = TransferMechanism(input_ports=[p2]) assert re.match(mismatches_specified_matrix_pattern, str(error_text.value)) # ------------------------------------------------------------------------------------------------ # TEST 33 def test_projection_with_sender_and_default(self): t = TransferMechanism(size=3) p = MappingProjection(sender=t) T = TransferMechanism(default_variable=[[0, 0]], input_ports=[p]) np.testing.assert_array_equal(T.defaults.variable, np.array([[0, 0]])) assert len(T.input_ports) == 1 # ------------------------------------------------------------------------------------------------ # TEST 34 def test_projection_no_args_projection_spec(self): p = MappingProjection() T = TransferMechanism(input_ports=[p]) np.testing.assert_array_equal(T.defaults.variable, np.array([[0]])) assert len(T.input_ports) == 1 # ------------------------------------------------------------------------------------------------ # TEST 35 def test_projection_no_args_projection_spec_with_default(self): p = MappingProjection() T = TransferMechanism(default_variable=[[0, 0]], input_ports=[p]) np.testing.assert_array_equal(T.defaults.variable, np.array([[0, 0]])) assert len(T.input_ports) == 1 # ------------------------------------------------------------------------------------------------ # TEST 36 def test_projection_no_args_dict_spec(self): p = MappingProjection() T = TransferMechanism(input_ports=[{ VARIABLE: [0, 0, 0], PROJECTIONS: [p] }]) np.testing.assert_array_equal(T.defaults.variable, np.array([[0, 0, 0]])) assert len(T.input_ports) == 1 # ------------------------------------------------------------------------------------------------ # TEST 37 def test_projection_no_args_dict_spec_mismatch_with_default(self): with pytest.raises(MechanismError) as error_text: p = MappingProjection() TransferMechanism(default_variable=[0, 0], input_ports=[{ VARIABLE: [0, 0, 0], PROJECTIONS: [p] }]) assert mismatches_specified_default_variable_error_text in str( error_text.value) # ------------------------------------------------------------------------------------------------ # TEST 38 def test_outputPort_(self): with pytest.raises(MechanismError) as error_text: p = MappingProjection() TransferMechanism(default_variable=[0, 0], input_ports=[{ VARIABLE: [0, 0, 0], PROJECTIONS: [p] }]) assert mismatches_specified_default_variable_error_text in str( error_text.value) # ------------------------------------------------------------------------------------------------ # TEST 26 def test_add_input_port_with_projection_in_mech_constructor(self): T1 = TransferMechanism() I = InputPort(projections=[T1]) T2 = TransferMechanism(input_ports=[I]) assert T2.input_ports[0].path_afferents[0].sender.owner is T1 # ------------------------------------------------------------------------------------------------ # TEST 27 def test_add_input_port_with_projection_using_add_ports(self): T1 = TransferMechanism() I = InputPort(projections=[T1]) T2 = TransferMechanism() T2.add_ports([I]) assert T2.input_ports[1].path_afferents[0].sender.owner is T1 # ------------------------------------------------------------------------------------------------ # TEST 28 def test_add_input_port_with_projection_by_assigning_owner(self): T1 = TransferMechanism() T2 = TransferMechanism() InputPort(owner=T2, projections=[T1]) assert T2.input_ports[1].path_afferents[0].sender.owner is T1 # ------------------------------------------------------------------------------------------------ # TEST 29 def test_add_input_port_with_projection_by_assigning_owner_error(self): with pytest.raises(PortError) as error_text: S1 = TransferMechanism() S2 = TransferMechanism() TransferMechanism(name='T', input_ports=[{ 'MY INPUT 1': [S1], 'MY INPUT 2': [S2] }]) # ------------------------------------------------------------------------------------------------ # TEST 30 def test_use_set_to_specify_projections_for_input_port_error(self): with pytest.raises(ProjectionError) as error_text: T1 = TransferMechanism() T2 = TransferMechanism() TransferMechanism(input_ports=[{'MY PORT': {T1, T2}}]) assert ('Connection specification for InputPort of' in str( error_text.value) and 'is a set' in str(error_text.value) and 'it should be a list' in str(error_text.value)) # ------------------------------------------------------------------------------------------------ # TEST 31 def test_multiple_states_specified_using_port_Name_format_error(self): with pytest.raises(PortError) as error_text: # Don't bother to specify anything as the value for each entry in the dict, since doesn't get there TransferMechanism(input_ports=[{'MY PORT A': {}, 'MY PORT B': {}}]) assert ( 'There is more than one entry of the InputPort specification dictionary' in str(error_text.value) and 'that is not a keyword; there should be only one (used to name the Port, with a list of ' 'Projection specifications' in str(error_text.value)) # ------------------------------------------------------------------------------------------------ # TEST 32 def test_default_name_and_projections_listing_for_input_port_in_constructor( self): T1 = TransferMechanism() my_input_port = InputPort(projections=[T1]) T2 = TransferMechanism(input_ports=[my_input_port]) assert T2.input_ports[0].name == 'InputPort-0' assert T2.input_ports[0].projections[0].sender.name == 'RESULT' # ------------------------------------------------------------------------------------------------ # TEST 33 def test_2_item_tuple_with_port_Name_list_and_mechanism(self): # T1 has OutputPorts of with same lengths, # so T2 should use that length for its InputPort variable (since it is not otherwise specified) T1 = TransferMechanism(input_ports=[[0, 0], [0, 0]]) T2 = TransferMechanism(input_ports=[(['RESULT-0', 'RESULT-1'], T1)]) assert len(T2.input_ports[0].value) == 2 assert T2.input_ports[0].path_afferents[0].sender.name == 'RESULT-0' assert T2.input_ports[0].path_afferents[1].sender.name == 'RESULT-1' # T1 has OutputPorts with different lengths both of which are specified by T2 to project to a singe InputPort, # so T2 should use its variable default as format for the InputPort (since it is not otherwise specified) T1 = TransferMechanism(input_ports=[[0, 0], [0, 0, 0]]) T2 = TransferMechanism(input_ports=[(['RESULT-0', 'RESULT-1'], T1)]) assert len(T2.input_ports[0].value) == 1 assert T2.input_ports[0].path_afferents[0].sender.name == 'RESULT-0' assert T2.input_ports[0].path_afferents[1].sender.name == 'RESULT-1' # ------------------------------------------------------------------------------------------------ # TEST 34 def test_lists_of_mechanisms_and_output_ports(self): # Test "bare" list of Mechanisms T0 = TransferMechanism(name='T0') T1 = TransferMechanism(name='T1', input_ports=[[0, 0], [0, 0, 0]]) T2 = TransferMechanism(name='T2', input_ports=[[T0, T1]]) assert len(T2.input_ports[0].path_afferents) == 2 assert T2.input_ports[0].path_afferents[0].sender.owner.name == 'T0' assert T2.input_ports[0].path_afferents[1].sender.owner.name == 'T1' assert T2.input_ports[0].path_afferents[1].matrix.base.shape == (2, 1) # Test list of Mechanisms in 4-item tuple specification T3 = TransferMechanism(name='T3', input_ports=[([T0, T1], None, None, InputPort)]) assert len(T3.input_ports[0].path_afferents) == 2 assert T3.input_ports[0].path_afferents[0].sender.owner.name == 'T0' assert T3.input_ports[0].path_afferents[1].sender.owner.name == 'T1' assert T3.input_ports[0].path_afferents[1].matrix.base.shape == (2, 1) # Test "bare" list of OutputPorts T4 = TransferMechanism( name='T4', input_ports=[[T0.output_ports[0], T1.output_ports[1]]]) assert len(T4.input_ports[0].path_afferents) == 2 assert T4.input_ports[0].path_afferents[0].sender.owner.name == 'T0' assert T4.input_ports[0].path_afferents[1].sender.owner.name == 'T1' assert T4.input_ports[0].path_afferents[1].matrix.base.shape == (3, 1) # Test list of OutputPorts in 4-item tuple specification T5 = TransferMechanism(name='T5', input_ports=[ ([T0.output_ports[0], T1.output_ports[1]], None, None, InputPort) ]) assert len(T5.input_ports[0].path_afferents) == 2 assert T5.input_ports[0].path_afferents[0].sender.owner.name == 'T0' assert T5.input_ports[0].path_afferents[1].sender.owner.name == 'T1' assert T5.input_ports[0].path_afferents[1].matrix.base.shape == (3, 1) # ------------------------------------------------------------------------------------------------ # TEST 35 def test_list_of_mechanisms_with_gating_mechanism(self): T1 = TransferMechanism(name='T6') G = GatingMechanism(gating_signals=['a', 'b']) T2 = TransferMechanism(input_ports=[[T1, G]], output_ports=[G.gating_signals['b']]) assert T2.input_ports[0].path_afferents[0].sender.owner.name == 'T6' assert T2.input_ports[0].mod_afferents[0].sender.name == 'a' assert T2.output_ports[0].mod_afferents[0].sender.name == 'b' # ------------------------------------------------------------------------------------------------ # THOROUGH TESTING OF mech, 2-item, 3-item and 4-item tuple specifications with and without default_variable/size # (some of these may be duplicative of tests above) # pytest does not support fixtures in parametrize, but a class member is enough for this test transfer_mech = TransferMechanism(size=3) @pytest.mark.parametrize( 'default_variable, size, input_ports, variable_len_state, variable_len_mech', [ # default_variable tests ([0, 0], None, [transfer_mech], 2, 2), ([0, 0], None, [(transfer_mech, None)], 2, 2), ([0, 0], None, [(transfer_mech, 1, 1)], 2, 2), ([0, 0], None, [((RESULT, transfer_mech), 1, 1)], 2, 2), ([0, 0], None, [(transfer_mech, 1, 1, None)], 2, 2), # size tests (None, 2, [transfer_mech], 2, 2), (None, 2, [(transfer_mech, None)], 2, 2), (None, 2, [(transfer_mech, 1, 1)], 2, 2), (None, 2, [(transfer_mech, 1, 1, None)], 2, 2), # no default_variable or size tests (None, None, [transfer_mech], 3, 3), (None, None, [(transfer_mech, None)], 3, 3), (None, None, [(transfer_mech, 1, 1)], 3, 3), (None, None, [(transfer_mech, 1, 1, None)], 3, 3), # tests of input ports with different variable and value shapes # ([[0,0]], None, [{VARIABLE: [[0], [0]], FUNCTION: LinearCombination}], 2, 2), # (None, 2, [{VARIABLE: [[0], [0]], FUNCTION: LinearCombination}], 2, 2), (None, 1, [{ VARIABLE: [0, 0], FUNCTION: Reduce(weights=[1, -1]) }], 2, 1), # (None, None, [transfer_mech], 3, 3), # (None, None, [(transfer_mech, None)], 3, 3), # (None, None, [(transfer_mech, 1, 1)], 3, 3), # (None, None, [(transfer_mech, 1, 1, None)], 3, 3), # # tests of input ports with different variable and value shapes # ([[0]], None, [{VARIABLE: [[0], [0]], FUNCTION: LinearCombination}], 2, 1), # (None, 1, [{VARIABLE: [0, 0], FUNCTION: Reduce(weights=[1, -1])}], 2, 1), ]) def test_mech_and_tuple_specifications_with_and_without_default_variable_or_size( self, default_variable, size, input_ports, variable_len_state, variable_len_mech, ): # ADD TESTING WITH THIS IN PLACE OF transfer_mech: # p = MappingProjection(sender=transfer_mech) T = TransferMechanism(default_variable=default_variable, size=size, input_ports=input_ports) assert T.input_ports[0].socket_width == variable_len_state assert T.defaults.variable.shape[-1] == variable_len_mech def test_input_ports_arg_no_list(self): T = TransferMechanism(input_ports={VARIABLE: [0, 0, 0]}) np.testing.assert_array_equal(T.defaults.variable, np.array([[0, 0, 0]])) assert len(T.input_ports) == 1 def test_input_ports_params_no_list(self): T = TransferMechanism(params={INPUT_PORTS: {VARIABLE: [0, 0, 0]}}) np.testing.assert_array_equal(T.defaults.variable, np.array([[0, 0, 0]])) assert len(T.input_ports) == 1
def test_compositions_as_origin_nodes(self, mode): inner_composition_1 = Composition(name="inner_composition_1") A = TransferMechanism(name="A", function=Linear(slope=0.5)) B = TransferMechanism(name="B", function=Linear(slope=2.0)) C = TransferMechanism(name="C", function=Linear(slope=3.0)) inner_composition_1.add_node(A) inner_composition_1.add_node(B) inner_composition_1.add_node(C) inner_composition_1.add_projection(MappingProjection(), A, C) inner_composition_1.add_projection(MappingProjection(), B, C) inner_composition_1._analyze_graph() inner_composition_2 = Composition(name="inner_composition_2") A2 = TransferMechanism(name="A2", function=Linear(slope=0.25)) B2 = TransferMechanism(name="B2", function=Linear(slope=1.0)) inner_composition_2.add_node(A2) inner_composition_2.add_node(B2) inner_composition_2.add_projection(MappingProjection(), A2, B2) inner_composition_2._analyze_graph() mechanism_d = TransferMechanism(name="D", function=Linear(slope=3.0)) outer_composition = Composition(name="outer_composition") outer_composition.add_node(inner_composition_1) outer_composition.add_node(inner_composition_2) outer_composition.add_node(mechanism_d) outer_composition.add_projection(projection=MappingProjection(), sender=inner_composition_1, receiver=mechanism_d) outer_composition.add_projection(projection=MappingProjection(), sender=inner_composition_2, receiver=mechanism_d) sched = Scheduler(composition=outer_composition) outer_composition._analyze_graph() # FIX: order of InputStates on inner composition 1 is not stable output = outer_composition.run( inputs={ # inner_composition_1: [[2.0], [1.0]], inner_composition_1: { A: [2.0], B: [1.0] }, inner_composition_2: [[12.0]] }, scheduler_processing=sched, bin_execute=mode) assert np.allclose(output, [[[36.]]]) if mode == 'Python': assert np.allclose(A.get_output_values(outer_composition), [[1.0]]) assert np.allclose(B.get_output_values(outer_composition), [[2.0]]) assert np.allclose(C.get_output_values(outer_composition), [[9.0]]) assert np.allclose(A2.get_output_values(outer_composition), [[3.0]]) assert np.allclose(B2.get_output_values(outer_composition), [[3.0]]) assert np.allclose( inner_composition_1.get_output_values(outer_composition), [[9.0]]) assert np.allclose( inner_composition_2.get_output_values(outer_composition), [[3.0]]) assert np.allclose( mechanism_d.get_output_values(outer_composition), [[36.0]]) assert np.allclose( outer_composition.get_output_values(outer_composition), [[36.0]])
def test_add_input_port_with_projection_in_mech_constructor(self): T1 = TransferMechanism() I = InputPort(projections=[T1]) T2 = TransferMechanism(input_ports=[I]) assert T2.input_ports[0].path_afferents[0].sender.owner is T1
def test_compositions_as_origin_nodes_multiple_trials(self, mode): inner_composition_1 = Composition(name="inner_composition_1") A = TransferMechanism(name="A", function=Linear(slope=0.5)) B = TransferMechanism(name="B", function=Linear(slope=2.0)) C = TransferMechanism(name="C", function=Linear(slope=3.0)) inner_composition_1.add_node(A) inner_composition_1.add_node(B) inner_composition_1.add_node(C) inner_composition_1.add_projection(MappingProjection(), A, C) inner_composition_1.add_projection(MappingProjection(), B, C) inner_composition_1._analyze_graph() inner_composition_2 = Composition(name="inner_composition_2") A2 = TransferMechanism(name="A2", function=Linear(slope=0.25)) B2 = TransferMechanism(name="B2", function=Linear(slope=1.0)) inner_composition_2.add_node(A2) inner_composition_2.add_node(B2) inner_composition_2.add_projection(MappingProjection(), A2, B2) inner_composition_2._analyze_graph() mechanism_d = TransferMechanism(name="D", function=Linear(slope=3.0)) outer_composition = Composition(name="outer_composition") outer_composition.add_node(inner_composition_1) outer_composition.add_node(inner_composition_2) outer_composition.add_node(mechanism_d) outer_composition.add_projection(projection=MappingProjection(), sender=inner_composition_1, receiver=mechanism_d) outer_composition.add_projection(projection=MappingProjection(), sender=inner_composition_2, receiver=mechanism_d) sched = Scheduler(composition=outer_composition) outer_composition._analyze_graph() # FIX: order of InputStates on inner composition 1 is not stable output = outer_composition.run(inputs={ inner_composition_1: { A: [[2.0], [1.5], [2.5]], B: [[1.0], [1.5], [1.5]] }, inner_composition_2: [[12.0], [11.5], [12.5]] }, scheduler_processing=sched, bin_execute=mode) # trial 0: # inner composition 1 = (0.5*2.0 + 2.0*1.0) * 3.0 = 9.0 # inner composition 2 = 0.25*12.0 = 3.0 # outer composition = (3.0 + 9.0) * 3.0 = 36.0 # trial 1: # inner composition 1 = (0.5*1.5 + 2.0*1.5) * 3.0 = 11.25 # inner composition 2 = 0.25*11.5 = 2.875 # outer composition = (2.875 + 11.25) * 3.0 = 42.375 # trial 2: # inner composition 1 = (0.5*2.5 + 2.0*1.5) * 3.0 = 12.75 # inner composition 2 = 0.25*12.5 = 3.125 # outer composition = (3.125 + 12.75) * 3.0 = 47.625 assert np.allclose(output, np.array([47.625]))
def test_add_input_port_with_projection_using_add_ports(self): T1 = TransferMechanism() I = InputPort(projections=[T1]) T2 = TransferMechanism() T2.add_ports([I]) assert T2.input_ports[1].path_afferents[0].sender.owner is T1
def test_mechanism_params_with_combined_conditions_for_individual_INPUT_PORT_PARAMS(self): T1 = TransferMechanism() T2 = TransferMechanism() P = MappingProjection(sender=T1, receiver=T2, name='MY PROJECTION') C = Composition(pathways=[[T1,P,T2]]) T1.function.slope = 5 T2.input_port.function.scale = 4 # Run 0: Test INPUT_PORT_PARAMS for InputPort function directly (scale) and in FUNCTION_PARAMS dict (weights) C.run(inputs={T1: 2.0}, runtime_params={ T1: {'slope': (3, AtTrial(1))}, # Condition on Mechanism's function (Linear) parameter T2: { 'noise': 0.5, 'intercept': (1, AtTrial(2)), # Condition on Mechanism's function parameter INPUT_PORT_PARAMS: { 'weight':5, # FIX 5/8/20 [JDC] ADD TEST FOR THIS ERROR: # 'scale': (20, AtTrial(3), 3 ), 'scale': (20, AtTrial(3)), FUNCTION_PARAMS:{'weights':(10, AtTrial(4))}, } }, }, num_trials=5 ) # Run 1: Test INPUT_PORT_PARAMS override by Never() Condition C.run(inputs={T1: 2.0}, runtime_params={ T2: { 'noise': 0.5, INPUT_PORT_PARAMS: ({ 'scale': (20, AtTrial(0)), FUNCTION_PARAMS:{'weights':(10, AtTrial(1))} }, Never()) }, }, num_trials=2 ) # Run 2: Test INPUT_PORT_PARAMS constraint to Trial 1 assignements C.run(inputs={T1: 2.0}, runtime_params={ T2: { 'noise': 0.5, 'intercept': (1, AtTrial(0)), INPUT_PORT_PARAMS: ({ 'scale': (20, AtTrial(0)), FUNCTION_PARAMS:{'weights':(10, AtTrial(1))}, }, AtTrial(1)) }, }, num_trials=2 ) # Run 3: Test Projection params C.run(inputs={T1: 2.0}, runtime_params={ T2: { 'noise': 0.5, INPUT_PORT_PARAMS: { MAPPING_PROJECTION_PARAMS:{ 'variable':(1000, AtTrial(0)), 'value':(2000, AtTrial(1)), }, P:{'value':(3000, AtTrial(2))}, 'MY PROJECTION':{'value':(4000, AtTrial(3))} } } }, num_trials=4 ) # all parameters restored to previous values (assigned or defaults) assert T1.function.parameters.slope.get(C) == 5.0 assert T1.parameter_ports['slope'].parameters.value.get(C) == 5.0 assert T2.parameters.noise.get(C) == 0.0 assert T2.parameter_ports['noise'].parameters.value.get(C) == 0.0 assert T2.function.intercept == 0.0 assert T2.function.parameters.intercept.get(C) == 0.0 assert T2.input_port.weight is None assert T2.input_port.function.scale == 4.0 assert T2.input_port.function.parameters.scale.get(C) == 4.0 assert T2.input_port.function.weights is None assert T2.input_port.function.parameters.weights.get(C) is None # Final Run: insure restored default for noise after last run C.run(inputs={T1: 2.0}, ) assert np.allclose(C.results,[ # Conditions satisfied: np.array([[40.5]]), # Run 0 Trial 0: no conditions (2*5*4)+0.5 np.array([[24.5]]), # Run 0 Trial 1: only T1.slope condition (2*3*4)+0.5 np.array([[41.5]]), # Run 0 Trial 2: only T2.intercept condition (2*5*4)+1+0.5 np.array([[200.5]]), # Run 0 Trial 3: only T2 scale condition (2*5*20) + 0.5 np.array([[400.5]]), # Run 0 Trial 4: only T2.function.weights condition (2*5*4*10)+0.5 np.array([[40.5]]), # Run 1 Tria1 0: INPUT_PORT_PARAMS Never() takes precedence over scale (2*5*4)+0.5 np.array([[40.5]]), # Run 1 Trial 1: INPUT_PORT_PARAMS Never() takes precedence over weights (2*5*4)+0.5 np.array([[41.5]]), # Run 2 Tria1 0: INPUT_PORT_PARAMS AtTrial(1) takes precedence over scale (2*5*4)+1+0.5 np.array([[400.5]]), # Run 2 Trial 1: INPUT_PORT_PARAMS AtTrial(1) consistent with weights (2*5*4*10)+0.5 np.array([[4000.5]]), # Run 3 Trial 0: INPUT_PORT_PARAMS AtTrial(0) Projection variable (2*5*4*1000)+0.5 np.array([[8000.5]]), # Run 3 Trial 1: INPUT_PORT_PARAMS AtTrial(0) Projection variable (2*5*4*2000)+0.5 np.array([[12000.5]]),# Run 3 Trial 2: INPUT_PORT_PARAMS AtTrial(0) Projection variable (2*5*4*3000)+0.5 np.array([[16000.5]]),# Run 3 Trial 3: INPUT_PORT_PARAMS AtTrial(0) Projection variable (2*5*4*4000)+0.5 np.array([[40.]]) # Final run: revert to assignments before previous run (2*5*4) ])
def test_add_input_port_with_projection_by_assigning_owner(self): T1 = TransferMechanism() T2 = TransferMechanism() InputPort(owner=T2, projections=[T1]) assert T2.input_ports[1].path_afferents[0].sender.owner is T1
def test_composition_runtime_param_errors(self): T1 = TransferMechanism() T2 = TransferMechanism() CM = ComparatorMechanism() P1 = MappingProjection(sender=T1, receiver=CM.input_ports[SAMPLE], name='SAMPLE PROJECTION') P2 = MappingProjection(sender=T2, receiver=CM.input_ports[TARGET], name='TARGET PROJECTION') C = Composition(nodes=[T1,T2,CM], projections=[P1,P2]) T1.function.slope = 3 T2.input_port.function.scale = 4 # Bad param specified for Mechanism with pytest.raises(ComponentError) as error_text: C.run(inputs={T1: 2.0}, runtime_params={ T2: { 'noise': 0.5, 'glorp': 22, # Bad Mechanism arg 'intercept': 1, INPUT_PORT_PARAMS: { 'weight':5, 'scale':20, FUNCTION_PARAMS:{'weights':10}} } }) assert ("Invalid specification in runtime_params arg for TransferMechanism" in str(error_text.value) and "'glorp'" in str(error_text.value)) # Bad param specified in INPUT_PORT_PARAMS with pytest.raises(ComponentError) as error_text: C.run(inputs={T1: 2.0}, runtime_params={ T1: {'slope': 3}, T2: { 'noise': 0.5, 'intercept': 1, INPUT_PORT_PARAMS: { 'weight':5, 'scale':20, 'trigot':16, # Bad InputPort arg FUNCTION_PARAMS:{'weights':10, }} } }) assert ("Invalid specification in runtime_params arg for InputPort" in str(error_text.value) and "of TransferMechanism" in str(error_text.value) and "'trigot'" in str(error_text.value)) # Bad param specified in FUNCTION_PARAMS of INPUT_PORT_PARAMS with pytest.raises(ComponentError) as error_text: C.run(inputs={T1: 2.0}, runtime_params={ T1: {'slope': 3}, T2: { 'noise': 0.5, 'intercept': 1, INPUT_PORT_PARAMS: { 'weight':5, 'scale':20, FUNCTION_PARAMS:{'weights':10, 'flurb': 12, # Bad InputPort function arg }} } }) assert ("Invalid specification in runtime_params arg for InputPort" in str(error_text.value) and "of TransferMechanism" in str(error_text.value) and "'flurb'" in str(error_text.value)) # Bad param specified in <TYPE>_PROJECTION_PARAMS with pytest.raises(ComponentError) as error_text: C.run(inputs={T1: 2.0, T2: 4.0}, # runtime_params=rt_dict, runtime_params={ CM: { # 'variable' : 1000 CM.input_ports[TARGET] : {'variable':(1000, AtTrial(0))}, CM.output_port : {'value':(1000, AtTrial(0))}, INPUT_PORT_PARAMS: { MAPPING_PROJECTION_PARAMS:{'value':(2000, AtTrial(0)), 'glarfip' : 2, # Bad arg in Projection type P1:{'value':(3000, AtTrial(2))}, 'MY PROJECTION':{'value':(4000, AtTrial(3))} } } } }, num_trials=2 ) assert ("Invalid specification in runtime_params arg for matrix of SAMPLE PROJECTION: 'glarfip'." in str(error_text.value)) # Bad param specified for Projection specified within <TYPE>_PROJECTION_PARAMS with pytest.raises(ComponentError) as error_text: C.run(inputs={T1: 2.0, T2: 4.0}, runtime_params={ CM: { # 'variable' : 1000 CM.input_ports[TARGET] : {'variable':(1000, AtTrial(0))}, CM.output_port : {'value':(1000, AtTrial(0))}, INPUT_PORT_PARAMS: { MAPPING_PROJECTION_PARAMS:{'value':(2000, AtTrial(0)), P1:{'value':(3000, AtTrial(2)), 'scrulip' : 2, # Bad Projection specific arg }, 'MY PROJECTION':{'value':(4000, AtTrial(3))} } } } }, num_trials=2 ) assert ("Invalid specification in runtime_params arg for matrix of SAMPLE PROJECTION: 'scrulip'." in str(error_text.value)) # Bad param specified in Projection specified by name within <TYPE>_PROJECTION_PARAMS with pytest.raises(ComponentError) as error_text: C.run(inputs={T1: 2.0, T2: 4.0}, runtime_params={ CM: { CM.input_ports[TARGET] : {'variable':(1000, AtTrial(0))}, CM.output_port : {'value':(1000, AtTrial(0))}, INPUT_PORT_PARAMS: { MAPPING_PROJECTION_PARAMS:{'value':(2000, AtTrial(0)), P1:{'value':(3000, AtTrial(2)), }, 'TARGET PROJECTION':{'value':(4000, AtTrial(3)), 'amiby': 4} # Bad Projection param } } } }, num_trials=2 ) assert ("Invalid specification in runtime_params arg for matrix of TARGET PROJECTION: 'amiby'." in str(error_text.value))
def test_input_ports_arg_no_list(self): T = TransferMechanism(input_ports={VARIABLE: [0, 0, 0]}) np.testing.assert_array_equal(T.defaults.variable, np.array([[0, 0, 0]])) assert len(T.input_ports) == 1
def test_LCAMechanism_length_2(self, benchmark, mode): # Note: since the LCAMechanism's threshold is not specified in this test, each execution only updates # the Mechanism once. T = TransferMechanism(function=Linear(slope=1.0), size=2) L = LCAMechanism(function=Linear(slope=2.0), size=2, self_excitation=3.0, leak=0.5, competition=1.0, time_step_size=0.1) C = Composition() C.add_linear_processing_pathway([T, L]) L.reset_stateful_function_when = Never() # - - - - - - - Equations to be executed - - - - - - - # new_transfer_input = # previous_transfer_input # + (leak * previous_transfer_input_1 + self_excitation * result1 + competition * result2 + outside_input1) * dt # + noise # result = new_transfer_input*2.0 # recurrent_matrix = [[3.0]] # - - - - - - - - - - - - - - - - - - - - - - - - - - C.run(inputs={T: [1.0, 2.0]}, num_trials=3, bin_execute=mode) # - - - - - - - TRIAL 1 - - - - - - - # new_transfer_input_1 = 0.0 + ( 0.5 * 0.0 + 3.0 * 0.0 - 1.0*0.0 + 1.0)*0.1 + 0.0 = 0.1 # f(new_transfer_input_1) = 0.1 * 2.0 = 0.2 # new_transfer_input_2 = 0.0 + ( 0.5 * 0.0 + 3.0 * 0.0 - 1.0*0.0 + 2.0)*0.1 + 0.0 = 0.2 # f(new_transfer_input_2) = 0.2 * 2.0 = 0.4 # - - - - - - - TRIAL 2 - - - - - - - # new_transfer_input = 0.1 + ( 0.5 * 0.1 + 3.0 * 0.2 - 1.0*0.4 + 1.0)*0.1 + 0.0 = 0.225 # f(new_transfer_input) = 0.265 * 2.0 = 0.45 # new_transfer_input_2 = 0.2 + ( 0.5 * 0.2 + 3.0 * 0.4 - 1.0*0.2 + 2.0)*0.1 + 0.0 = 0.51 # f(new_transfer_input_2) = 0.1 * 2.0 = 1.02 # - - - - - - - TRIAL 3 - - - - - - - # new_transfer_input = 0.225 + ( 0.5 * 0.225 + 3.0 * 0.45 - 1.0*1.02 + 1.0)*0.1 + 0.0 = 0.36925 # f(new_transfer_input) = 0.36925 * 2.0 = 0.7385 # new_transfer_input_2 = 0.51 + ( 0.5 * 0.51 + 3.0 * 1.02 - 1.0*0.45 + 2.0)*0.1 + 0.0 = 0.9965 # f(new_transfer_input_2) = 0.9965 * 2.0 = 1.463 assert np.allclose(C.results, [[[0.2, 0.4]], [[0.43, 0.98]], [[0.6705, 1.833]]]) if benchmark.enabled: benchmark(C.run, inputs={T: [1.0, 2.0]}, num_trials=3, bin_execute=mode)
def test_input_ports_params_no_list(self): T = TransferMechanism(params={INPUT_PORTS: {VARIABLE: [0, 0, 0]}}) np.testing.assert_array_equal(T.defaults.variable, np.array([[0, 0, 0]])) assert len(T.input_ports) == 1
def test_mod_param_error(self): T = TransferMechanism() with pytest.raises(ComponentError) as error_text: T.function.slope.modulated = 20.0 assert "directly because it is computed by the ParameterPort" in str(error_text.value)
def test_connect_compositions_with_simple_states(self, mode): comp1 = Composition(name="first_composition") A = TransferMechanism(name="A", function=Linear(slope=2.0)) B = TransferMechanism(name="B", function=Linear(slope=3.0)) comp1.add_node(A) comp1.add_node(B) comp1.add_projection(MappingProjection(sender=A, receiver=B), A, B) comp1._analyze_graph() inputs_dict = { A: [[5.]], } sched = Scheduler(composition=comp1) comp2 = Composition(name="second_composition") A2 = TransferMechanism(name="A2", function=Linear(slope=2.0)) B2 = TransferMechanism(name="B2", function=Linear(slope=3.0)) comp2.add_node(A2) comp2.add_node(B2) comp2.add_projection(MappingProjection(sender=A2, receiver=B2), A2, B2) comp2._analyze_graph() sched = Scheduler(composition=comp2) comp3 = Composition(name="outer_composition") comp3.add_node(comp1) comp3.add_node(comp2) comp3.add_projection(MappingProjection(), comp1, comp2) # comp1: # input = 5.0 # mechA: 2.0*5.0 = 10.0 # mechB: 3.0*10.0 = 30.0 # output = 30.0 # comp2: # input = 30.0 # mechA2: 2.0*30.0 = 60.0 # mechB2: 3.0*60.0 = 180.0 # output = 180.0 # comp3: # input = 5.0 # output = 180.0 res = comp3.run(inputs={comp1: [[5.]]}, bin_execute=mode) assert np.allclose(res, [[[180.0]]]) if mode == 'Python': assert np.allclose(comp1.output_state.parameters.value.get(comp3), [30.0]) assert np.allclose(comp2.output_state.parameters.value.get(comp3), [180.0]) assert np.allclose(comp3.output_state.parameters.value.get(comp3), [180.0])
def test_configurable_params(self): old_value = 0.2 new_value = 0.7 T = TransferMechanism(function=Linear(slope=old_value, intercept=old_value), noise=old_value, integration_rate=old_value) # SLOPE - - - - - - - - assert np.allclose(T.function.slope.base, old_value) assert np.allclose(T.function.slope.modulated, old_value) T.function.slope.base = new_value assert np.allclose(T.function.slope.base, new_value) assert np.allclose(T.function.slope.modulated, old_value) # INTERCEPT - - - - - - - - assert np.allclose(T.function.intercept.base, old_value) assert np.allclose(T.function.intercept.modulated, old_value) T.function.intercept.base = new_value assert np.allclose(T.function.intercept.base, new_value) assert np.allclose(T.function.intercept.modulated, old_value) # SMOOTHING FACTOR - - - - - - - - assert np.allclose(T.integration_rate.base, old_value) assert np.allclose(T.integration_rate.modulated, old_value) T.integration_rate.base = new_value # KAM changed 3/2/18 -- # function_params looks at ParameterPort value, so this will not update until next execution assert np.allclose(T.integration_rate.base, new_value) assert np.allclose(T.integration_rate.modulated, old_value) # NOISE - - - - - - - - assert np.allclose(T.noise.base, old_value) assert np.allclose(T.noise.modulated, old_value) T.noise.base = new_value # KAM changed 3/2/18 -- # function_params looks at ParameterPort value, so this will not update until next execution assert np.allclose(T.noise.base, new_value) assert np.allclose(T.noise.modulated, old_value) T.execute(1.0) assert np.allclose(T.function.slope.base, new_value) assert np.allclose(T.function.slope.modulated, new_value) assert np.allclose(T.function.intercept.base, new_value) assert np.allclose(T.function.intercept.modulated, new_value) assert np.allclose(T.integration_rate.base, new_value) assert np.allclose(T.integration_rate.modulated, new_value) assert np.allclose(T.noise.base, new_value) assert np.allclose(T.noise.modulated, new_value)
def test_connect_compositions_with_complicated_states(self, mode): inner_composition_1 = Composition(name="comp1") A = TransferMechanism(name="A1", default_variable=[[0.0], [0.0]], function=Linear(slope=2.0)) B = TransferMechanism(name="B1", default_variable=[[0.0], [0.0]], function=Linear(slope=3.0)) inner_composition_1.add_node(A) inner_composition_1.add_node(B) inner_composition_1.add_projection( MappingProjection(sender=A, receiver=B), A, B) inner_composition_1.add_projection( MappingProjection(sender=A.output_states[1], receiver=B.input_states[1]), A, B) inner_composition_1._analyze_graph() inner_composition_2 = Composition(name="comp2") A2 = TransferMechanism(name="A2", default_variable=[[0.0], [0.0]], function=Linear(slope=2.0)) B2 = TransferMechanism(name="B2", default_variable=[[0.0], [0.0]], function=Linear(slope=3.0)) inner_composition_2.add_node(A2) inner_composition_2.add_node(B2) inner_composition_2.add_projection( MappingProjection(sender=A2, receiver=B2), A2, B2) inner_composition_2.add_projection( MappingProjection(sender=A2.output_states[1], receiver=B2.input_states[1]), A2, B2) inner_composition_2._analyze_graph() outer_composition = Composition(name="outer_composition") outer_composition.add_node(inner_composition_1) outer_composition.add_node(inner_composition_2) outer_composition.add_projection(projection=MappingProjection(), sender=inner_composition_1, receiver=inner_composition_2) outer_composition.add_projection(projection=MappingProjection( sender=inner_composition_1.output_CIM.output_states[1], receiver=inner_composition_2.input_CIM.input_states[1]), sender=inner_composition_1, receiver=inner_composition_2) sched = Scheduler(composition=outer_composition) outer_composition._analyze_graph() output = outer_composition.run( inputs={inner_composition_1: [[[5.0], [50.0]]]}, scheduler_processing=sched, bin_execute=mode) assert np.allclose(output, [[[180.], [1800.]]]) if mode == 'Python': assert np.allclose( inner_composition_1.get_output_values(outer_composition), [[30.], [300.]]) assert np.allclose( inner_composition_2.get_output_values(outer_composition), [[180.], [1800.]]) assert np.allclose( outer_composition.get_output_values(outer_composition), [[180.], [1800.]])
def test_leabra_prec_with_train(self): in_size = 4 out_size = 4 num_hidden = 1 num_trials = 4 train = True inputs = [[0, 1, .5, -.2]] * num_trials train_data = [[.2, .5, 1, -.5]] * num_trials precision = 0.000000001 # how far we accept error between PNL and Leabra output random_seed = 2 # because Leabra network initializes with small random weights random.seed(random_seed) L_spec = LeabraMechanism(input_size=in_size, output_size=out_size, hidden_layers=num_hidden, training_flag=train) random.seed(random_seed) leabra_net = build_leabra_network(in_size, out_size, num_hidden, None, train) leabra_net2 = copy.deepcopy(leabra_net) L_net = LeabraMechanism(leabra_net2) # leabra_net should be identical to the network inside L_net T1_spec = TransferMechanism(name='T1', size=in_size, function=Linear) T2_spec = TransferMechanism(name='T2', size=out_size, function=Linear) T1_net = TransferMechanism(name='T1', size=in_size, function=Linear) T2_net = TransferMechanism(name='T2', size=out_size, function=Linear) p1_spec = Process(pathway=[T1_spec, L_spec]) proj_spec = MappingProjection(sender=T2_spec, receiver=L_spec.input_ports[1]) p2_spec = Process(pathway=[T2_spec, proj_spec, L_spec]) s_spec = System(processes=[p1_spec, p2_spec]) p1_net = Process(pathway=[T1_net, L_net]) proj_net = MappingProjection(sender=T2_net, receiver=L_net.input_ports[1]) p2_net = Process(pathway=[T2_net, proj_net, L_net]) s_net = System(processes=[p1_net, p2_net]) for i in range(num_trials): out_spec = s_spec.run(inputs={ T1_spec: inputs[i], T2_spec: train_data[i] }) pnl_output_spec = out_spec[-1][0] leabra_output = train_leabra_network(leabra_net, inputs[i], train_data[i]) diffs_spec = np.abs( np.array(pnl_output_spec) - np.array(leabra_output)) out_net = s_net.run(inputs={ T1_net: inputs[i], T2_net: train_data[i] }) pnl_output_net = out_net[-1][0] diffs_net = np.abs( np.array(pnl_output_net) - np.array(leabra_output)) assert all(diffs_spec < precision) and all(diffs_net < precision) out_spec = s_spec.run(inputs={T1_spec: inputs, T2_spec: train_data}) pnl_output_spec = np.array(out_spec[-1][0]) for i in range(len(inputs)): leabra_output = np.array( train_leabra_network(leabra_net, inputs[i], train_data[i])) diffs_spec = np.abs(pnl_output_spec - leabra_output) out_net = s_net.run(inputs={T1_net: inputs, T2_net: train_data}) pnl_output_net = np.array(out_net[-1][0]) diffs_net = np.abs(pnl_output_net - leabra_output) assert all(diffs_spec < precision) and all(diffs_net < precision)
def test_predator_prey(benchmark, mode, samples): if len(samples) > 10 and mode not in {"LLVMRun", "Python-PTX"}: pytest.skip("This test takes too long") # OCM default mode is Python mode, ocm_mode = (mode + "-Python").split('-')[0:2] benchmark.group = "Predator-Prey " + str(len(samples)) obs_len = 3 obs_coords = 2 player_idx = 0 player_obs_start_idx = player_idx * obs_len player_value_idx = player_idx * obs_len + obs_coords player_coord_slice = slice(player_obs_start_idx, player_value_idx) predator_idx = 1 predator_obs_start_idx = predator_idx * obs_len predator_value_idx = predator_idx * obs_len + obs_coords predator_coord_slice = slice(predator_obs_start_idx, predator_value_idx) prey_idx = 2 prey_obs_start_idx = prey_idx * obs_len prey_value_idx = prey_idx * obs_len + obs_coords prey_coord_slice = slice(prey_obs_start_idx, prey_value_idx) player_len = prey_len = predator_len = obs_coords # Perceptual Mechanisms player_obs = ProcessingMechanism(size=prey_len, function=GaussianDistort, name="PLAYER OBS") prey_obs = ProcessingMechanism(size=prey_len, function=GaussianDistort, name="PREY OBS") predator_obs = TransferMechanism(size=predator_len, function=GaussianDistort, name="PREDATOR OBS") # Action Mechanism # Use ComparatorMechanism to compute direction of action as difference of coordinates between player and prey: # note: unitization is done in main loop, to allow compilation of LinearCombination function) (TBI) greedy_action_mech = ComparatorMechanism(name='ACTION', sample=player_obs, target=prey_obs) # Create Composition agent_comp = Composition(name='PREDATOR-PREY COMPOSITION') agent_comp.add_node(player_obs) agent_comp.add_node(predator_obs) agent_comp.add_node(prey_obs) agent_comp.add_node(greedy_action_mech) agent_comp.exclude_node_roles(predator_obs, NodeRole.OUTPUT) ocm = OptimizationControlMechanism( features={SHADOW_INPUTS: [player_obs, predator_obs, prey_obs]}, agent_rep=agent_comp, function=GridSearch(direction=MINIMIZE, save_values=True), objective_mechanism=ObjectiveMechanism( function=Distance(metric=NORMED_L0_SIMILARITY), monitor=[player_obs, prey_obs]), control_signals=[ ControlSignal(modulates=(VARIANCE, player_obs), allocation_samples=samples), ControlSignal(modulates=(VARIANCE, predator_obs), allocation_samples=samples), ControlSignal(modulates=(VARIANCE, prey_obs), allocation_samples=samples) ], ) agent_comp.add_controller(ocm) agent_comp.enable_controller = True ocm.comp_execution_mode = ocm_mode input_dict = { player_obs: [[1.1576537, 0.60782117]], predator_obs: [[-0.03479106, -0.47666293]], prey_obs: [[-0.60836214, 0.1760381]], } run_results = agent_comp.run(inputs=input_dict, num_trials=2, bin_execute=mode) if len(samples) == 2: # KDM 12/4/19: modified results due to global seed offset of # GaussianDistort assignment. # to produce old numbers, run get_global_seed once before creating # each Mechanism with GaussianDistort above assert np.allclose(run_results[0], [[-10.06333025, 2.4845505]]) if mode == 'Python': assert np.allclose( ocm.feature_values, [[1.1576537, 0.60782117], [-0.03479106, -0.47666293], [-0.60836214, 0.1760381]]) if benchmark.enabled: benchmark(agent_comp.run, inputs=input_dict, bin_execute=mode)