def test_recurrent_mech_function_logistic(self): R = RecurrentTransferMechanism(name='R', size=10, function=Logistic(gain=2, offset=1)) val = R.execute(np.ones(10)) np.testing.assert_allclose(val, [np.full(10, 0.7310585786300049)])
def test_recurrent_mech_inputs_list_of_strings(self): with pytest.raises(UtilitiesError) as error_text: R = RecurrentTransferMechanism(name='R', default_variable=[0, 0, 0, 0], integrator_mode=True) R.execute(["one", "two", "three", "four"]) assert "has non-numeric entries" in str(error_text.value)
def test_recurrent_mech_function_psyneulink(self): a = Logistic(gain=2, offset=1) R = RecurrentTransferMechanism(name='R', size=7, function=a) val = R.execute(np.zeros(7)) np.testing.assert_allclose(val, [np.full(7, 0.2689414213699951)])
def test_recurrent_mech_inputs_list_of_ints(self): R = RecurrentTransferMechanism(name='R', default_variable=[0, 0, 0, 0]) val = R.execute([10, 12, 0, -1]) np.testing.assert_allclose(val, [[10.0, 12.0, 0, -1]]) val = R.execute([1, 2, 3, 0]) np.testing.assert_allclose( val, [[1, 2, 3, 0]] ) # because recurrent projection is not used when executing: mech is reset each time
def test_recurrent_mech_matrix_auto_hetero_spec_size_4(self): R = RecurrentTransferMechanism(name='R', size=4, auto=2.2, hetero=-3) val = R.execute([10, 10, 10, 10]) np.testing.assert_allclose(val, [[10., 10., 10., 10.]]) np.testing.assert_allclose(R.matrix, [[2.2, -3, -3, -3], [-3, 2.2, -3, -3], [-3, -3, 2.2, -3], [-3, -3, -3, 2.2]]) assert isinstance(R.matrix, np.ndarray)
def test_clip_2d_array(self): R = RecurrentTransferMechanism(default_variable=[[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]], clip=[-2.0, 2.0]) assert np.allclose( R.execute([[-5.0, -1.0, 5.0], [5.0, -5.0, 1.0], [1.0, 5.0, 5.0]]), [[-2.0, -1.0, 2.0], [2.0, -2.0, 1.0], [1.0, 2.0, 2.0]])
def test_recurrent_mech_reinforcement_fun(self): with pytest.raises(TransferError) as error_text: R = RecurrentTransferMechanism(name='R', default_variable=[0, 0, 0, 0], function=Reinforcement(), smoothing_factor=1.0, integrator_mode=True) R.execute([0, 0, 0, 0]) assert "must be a TRANSFER FUNCTION TYPE" in str(error_text.value)
def test_recurrent_mech_reduce_fun(self): with pytest.raises(TransferError) as error_text: R = RecurrentTransferMechanism(name='R', default_variable=[0, 0, 0, 0], function=Reduce(), time_constant=1.0, integrator_mode=True) R.execute([0, 0, 0, 0]) assert "must be a TRANSFER FUNCTION TYPE" in str(error_text.value)
def test_recurrent_mech_auto_array_matrix_spec(self): R = RecurrentTransferMechanism(name='R', size=4, auto=[1.1, 2.2, 3.3, 4.4], matrix=[[1, 2, 3, 4]] * 4) val = R.execute([10, 11, 12, 13]) np.testing.assert_allclose(val, [[10., 11., 12., 13.]]) np.testing.assert_allclose( R.matrix, [[1.1, 2, 3, 4], [1, 2.2, 3, 4], [1, 2, 3.3, 4], [1, 2, 3, 4.4]])
def test_recurrent_mech_matrix_keyword_spec(self): for m in MATRIX_KEYWORD_VALUES: if m == RANDOM_CONNECTIVITY_MATRIX: continue R = RecurrentTransferMechanism(name='R', size=4, matrix=m) val = R.execute([10, 10, 10, 10]) np.testing.assert_allclose(val, [[10., 10., 10., 10.]]) np.testing.assert_allclose(R.recurrent_projection.matrix, get_matrix(m, R.size[0], R.size[0]))
def test_recurrent_mech_time_constant_0_8(self): R = RecurrentTransferMechanism(name='R', default_variable=[0, 0, 0, 0], function=Linear(), time_constant=0.8, integrator_mode=True) val = R.execute([1, 1, 1, 1]) np.testing.assert_allclose(val, [[0.8, 0.8, 0.8, 0.8]]) val = R.execute([1, 1, 1, 1]) np.testing.assert_allclose(val, [[.96, .96, .96, .96]])
def test_recurrent_mech_auto_hetero_matrix_spec_v3(self): R = RecurrentTransferMechanism(name='R', size=4, auto=[3], hetero=2, matrix=[[1, 2, 3, 4]] * 4) val = R.execute([1, 2, 3, 4]) np.testing.assert_allclose(val, [[1., 2., 3., 4.]]) np.testing.assert_allclose( R.matrix, [[3, 2, 2, 2], [2, 3, 2, 2], [2, 2, 3, 2], [2, 2, 2, 3]])
def test_recurrent_mech_hetero_matrix_matrix_spec(self): R = RecurrentTransferMechanism(name='R', size=4, hetero=np.array([[-4, -3, -2, -1]] * 4), matrix=[[1, 2, 3, 4]] * 4) val = R.execute([1, 2, 3, 4]) np.testing.assert_allclose(val, [[1., 2., 3., 4.]]) np.testing.assert_allclose(R.matrix, [[1, -3, -2, -1], [-4, 2, -2, -1], [-4, -3, 3, -1], [-4, -3, -2, 4]])
def test_recurrent_mech_auto_matrix_spec(self): # auto should override the diagonal only R = RecurrentTransferMechanism(name='R', size=4, auto=2.2, matrix=[[1, 2, 3, 4]] * 4) val = R.execute([10, 11, 12, 13]) np.testing.assert_allclose(val, [[10., 11., 12., 13.]]) np.testing.assert_allclose( R.matrix, [[2.2, 2, 3, 4], [1, 2.2, 3, 4], [1, 2, 2.2, 4], [1, 2, 3, 2.2]])
def test_recurrent_mech_matrix_hetero_spec(self): R = RecurrentTransferMechanism(name='R', size=3, hetero=-1) # (7/28/17 CW) these numbers assume that execute() leaves its value in the outputState of the mechanism: if # the behavior of execute() changes, feel free to change these numbers val = R.execute([-1, -2, -3]) np.testing.assert_allclose(val, [[-1, -2, -3]]) assert isinstance(R.matrix, np.ndarray) np.testing.assert_allclose(R.matrix, [[1, -1, -1], [-1, 1, -1], [-1, -1, 1]]) np.testing.assert_allclose( run_twice_in_system(R, [1, 2, 3], [10, 11, 12]), [8, 7, 6])
def test_reinitialize_run(self): R = RecurrentTransferMechanism(name="R", initial_value=0.5, integrator_mode=True, smoothing_factor=0.1, auto=1.0, noise=0.0) P = Process(name="P", pathway=[R]) S = System(name="S", processes=[P]) assert np.allclose(R.previous_value, 0.5) assert np.allclose(R.initial_value, 0.5) assert np.allclose(R.integrator_function.initializer, 0.5) S.run(inputs={R: 1.0}, num_trials=2, initialize=True, initial_values={R: 0.0}) # Trial 1 | variable = 1.0 + 0.0 # integration: 0.9*0.5 + 0.1*1.0 + 0.0 = 0.55 ---> previous value = 0.55 # linear fn: 0.55*1.0 = 0.55 # Trial 2 | variable = 1.0 + 0.55 # integration: 0.9*0.55 + 0.1*1.55 + 0.0 = 0.65 ---> previous value = 0.65 # linear fn: 0.65*1.0 = 0.65 assert np.allclose(R.previous_value, 0.65) assert np.allclose(R.initial_value, 0.5) assert np.allclose(R.integrator_function.initializer, 0.5) R.integrator_function.reinitialize(0.9) assert np.allclose(R.previous_value, 0.9) assert np.allclose(R.initial_value, 0.5) assert np.allclose(R.integrator_function.initializer, 0.9) assert np.allclose(R.value, 0.65) R.reinitialize(0.5) assert np.allclose(R.previous_value, 0.5) assert np.allclose(R.initial_value, 0.5) assert np.allclose(R.integrator_function.initializer, 0.5) assert np.allclose(R.value, 0.5) S.run(inputs={R: 1.0}, num_trials=2) # Trial 3 # integration: 0.9*0.5 + 0.1*1.5 + 0.0 = 0.6 ---> previous value = 0.6 # linear fn: 0.6*1.0 = 0.6 # Trial 4 # integration: 0.9*0.6 + 0.1*1.6 + 0.0 = 0.7 ---> previous value = 0.7 # linear fn: 0.7*1.0 = 0.7 assert np.allclose(R.previous_value, 0.7) assert np.allclose(R.initial_value, 0.5) assert np.allclose(R.integrator_function.initializer, 0.5)
def test_recurrent_mech_hetero_float_matrix_spec(self): # hetero should override off-diagonal only R = RecurrentTransferMechanism(name='R', size=4, hetero=-2.2, matrix=[[1, 2, 3, 4]] * 4) val = R.execute([1, 2, 3, 4]) np.testing.assert_allclose(val, [[1., 2., 3., 4.]]) np.testing.assert_allclose( R.matrix, [[1, -2.2, -2.2, -2.2], [-2.2, 2, -2.2, -2.2], [-2.2, -2.2, 3, -2.2], [-2.2, -2.2, -2.2, 4]])
def test_recurrent_mech_time_constant_0_8_initial_1_2(self): R = RecurrentTransferMechanism(name='R', default_variable=[0, 0, 0, 0], function=Linear(), time_constant=0.8, initial_value=np.array([[-1, 1, -2, 2]]), integrator_mode=True) val = R.execute([3, 2, 1, 0]) np.testing.assert_allclose( val, [[2.2, 1.8, .40000000000000013, .3999999999999999]])
def test_recurrent_mech_auto_hetero_matrix_spec_v1(self): # auto and hetero should override matrix R = RecurrentTransferMechanism(name='R', size=4, auto=[1, 3, 5, 7], hetero=np.array([[-4, -3, -2, -1]] * 4), matrix=[[1, 2, 3, 4]] * 4) val = R.execute([1, 2, 3, 4]) np.testing.assert_allclose(val, [[1., 2., 3., 4.]]) np.testing.assert_allclose(R.matrix, [[1, -3, -2, -1], [-4, 3, -2, -1], [-4, -3, 5, -1], [-4, -3, -2, 7]])
def test_recurrent_mech_matrix_auto_hetero_matrix_spec(self): # when auto, hetero, and matrix are all specified, auto and hetero should take precedence R = RecurrentTransferMechanism(name='R', size=4, auto=2.2, hetero=-3, matrix=[[1, 2, 3, 4]] * 4) val = R.execute([10, 10, 10, 10]) np.testing.assert_allclose(val, [[10., 10., 10., 10.]]) np.testing.assert_allclose(R.matrix, [[2.2, -3, -3, -3], [-3, 2.2, -3, -3], [-3, -3, 2.2, -3], [-3, -3, -3, 2.2]]) assert isinstance(R.matrix, np.ndarray)
def test_recurrent_mech_time_constant_0_8_initial_0_5(self): R = RecurrentTransferMechanism(name='R', default_variable=[0, 0, 0, 0], function=Linear(), time_constant=0.8, initial_value=np.array( [[0.5, 0.5, 0.5, 0.5]]), integrator_mode=True) val = R.execute([1, 1, 1, 1]) np.testing.assert_allclose(val, [[0.9, 0.9, 0.9, 0.9]]) val = R.execute([1, 2, 3, 4]) np.testing.assert_allclose( val, [[.98, 1.78, 2.5800000000000005, 3.3800000000000003] ]) # due to inevitable floating point errors
def test_recurrent_mech_process_matrix_change(self): R = RecurrentTransferMechanism(size=4, auto=1, hetero=-1) T = TransferMechanism(size=4, function=Linear) p = Process(size=4, pathway=[T, R], prefs=TestRecurrentTransferMechanismInSystem.simple_prefs) R.matrix = [[2, 0, 1, 3]] * 4 p.run(inputs={T: [[1, 2, 3, 4]]}) np.testing.assert_allclose(T.value, [[1, 2, 3, 4]]) np.testing.assert_allclose(R.value, [[1, 2, 3, 4]]) p.run(inputs={T: [[1, 3, 2, 5]]}) np.testing.assert_allclose(R.recurrent_projection.matrix, [[2, 0, 1, 3]] * 4) np.testing.assert_allclose(T.value, [[1, 3, 2, 5]]) np.testing.assert_allclose(R.value, [[21, 3, 12, 35]])
def test_recurrent_mech_matrix_other_spec(self): specs = [ np.matrix('1 2; 3 4'), np.array([[1, 2], [3, 4]]), [[1, 2], [3, 4]], '1 2; 3 4' ] for m in specs: R = RecurrentTransferMechanism(name='R', size=2, matrix=m) val = R.execute([10, 10]) np.testing.assert_allclose(val, [[10., 10.]]) assert isinstance(R.matrix, np.ndarray) np.testing.assert_allclose(R.matrix, [[1, 2], [3, 4]]) np.testing.assert_allclose(R.recurrent_projection.matrix, [[1, 2], [3, 4]]) assert isinstance(R.recurrent_projection.matrix, np.ndarray)
def test_recurrent_mech_check_attrs(self): R = RecurrentTransferMechanism(name='R', size=3) assert R.value is None np.testing.assert_allclose(R.instance_defaults.variable, [[0., 0., 0.]]) np.testing.assert_allclose(R.matrix, [[1., 1., 1.], [1., 1., 1.], [1., 1., 1.]])
def test_learning_of_orthognal_inputs(self): size = 4 R = RecurrentTransferMechanism(size=size, function=Linear, enable_learning=True, auto=0, hetero=np.full((size, size), 0.0)) P = Process(pathway=[R]) S = System(processes=[P]) inputs_dict = {R: [1, 0, 1, 0]} S.run(num_trials=4, inputs=inputs_dict) np.testing.assert_allclose( R.recurrent_projection.mod_matrix, [[0.0, 0.0, 0.23700501, 0.0], [0.0, 0.0, 0.0, 0.0], [0.23700501, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0]]) np.testing.assert_allclose(R.output_state.value, [1.18518086, 0.0, 1.18518086, 0.0]) # Reset state so learning of new pattern is "uncontaminated" by activity from previous one R.output_state.value = [0, 0, 0, 0] inputs_dict = {R: [0, 1, 0, 1]} S.run(num_trials=4, inputs=inputs_dict) np.testing.assert_allclose( R.recurrent_projection.mod_matrix, [[0.0, 0.0, 0.23700501, 0.0], [0.0, 0.0, 0.0, 0.23700501], [0.23700501, 0.0, 0.0, 0.], [0.0, 0.23700501, 0.0, 0.]]) np.testing.assert_allclose(R.output_state.value, [0.0, 1.18518086, 0.0, 1.18518086])
def test_recurrent_mech_var_list_of_strings(self): with pytest.raises(UtilitiesError) as error_text: R = RecurrentTransferMechanism( name='R', default_variable=['a', 'b', 'c', 'd'], integrator_mode=True) assert "has non-numeric entries" in str(error_text.value)
def test_recurrent_mech_matrix_3d(self): with pytest.raises(FunctionError) as error_text: R = RecurrentTransferMechanism(name='R', size=2, matrix=[[[1, 3], [2, 4]], [[5, 7], [6, 8]]]) assert "more than 2d" in str(error_text.value)
def test_recurrent_mech_matrix_too_small(self): with pytest.raises(RecurrentTransferError) as error_text: R = RecurrentTransferMechanism(name='R', size=5, matrix=[[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]) assert "must be same as the size of variable" in str(error_text.value)
def test_initialize_mechanisms(self): A = TransferMechanism(name='A') B = TransferMechanism(name='B') C = RecurrentTransferMechanism(name='C', auto=1.0) abc_process = Process(pathway=[A, B, C]) abc_system = System(processes=[abc_process]) C.log.set_log_conditions('value') abc_system.run(inputs={A: [1.0, 2.0, 3.0]}, initial_values={A: 1.0, B: 1.5, C: 2.0}, initialize=True) abc_system.run(inputs={A: [1.0, 2.0, 3.0]}, initial_values={A: 1.0, B: 1.5, C: 2.0}, initialize=False) # Run 1 --> Execution 1: 1 + 2 = 3 | Execution 2: 3 + 2 = 5 | Execution 3: 5 + 3 = 8 # Run 2 --> Execution 1: 8 + 1 = 9 | Execution 2: 9 + 2 = 11 | Execution 3: 11 + 3 = 14 assert np.allclose(C.log.nparray_dictionary('value')['value'], [[[3]], [[5]], [[8]], [[9]], [[11]], [[14]]])
def test_recurrent_transfer_origin(self): R = RecurrentTransferMechanism(has_recurrent_input_state=True) P = Process(pathway=[R]) S = System(processes=[P]) S.run(inputs={R: [[1.0], [2.0], [3.0]]}) print(S.results)