def test_four_integrators_mixed(self): A = IntegratorMechanism(name='A', default_variable=[0], function=SimpleIntegrator(rate=1)) B = IntegratorMechanism(name='B', default_variable=[0], function=SimpleIntegrator(rate=1)) C = IntegratorMechanism(name='C', default_variable=[0], function=SimpleIntegrator(rate=1)) D = IntegratorMechanism(name='D', default_variable=[0], function=SimpleIntegrator(rate=1)) p = Process(default_variable=[0], pathway=[A, C], name='p') p1 = Process(default_variable=[0], pathway=[A, D], name='p1') q = Process(default_variable=[0], pathway=[B, C], name='q') q1 = Process(default_variable=[0], pathway=[B, D], name='q1') s = System(processes=[p, p1, q, q1], name='s') term_conds = { TimeScale.TRIAL: All(AfterNCalls(C, 1), AfterNCalls(D, 1)) } stim_list = {A: [[1]], B: [[1]]} sched = Scheduler(system=s) sched.add_condition(B, EveryNCalls(A, 2)) sched.add_condition(C, EveryNCalls(A, 1)) sched.add_condition(D, EveryNCalls(B, 1)) s.scheduler_processing = sched s.run(inputs=stim_list, termination_processing=term_conds) mechs = [A, B, C, D] expected_output = [ [ numpy.array([2.]), ], [ numpy.array([1.]), ], [ numpy.array([4.]), ], [ numpy.array([3.]), ], ] for m in range(len(mechs)): for i in range(len(expected_output[m])): numpy.testing.assert_allclose(expected_output[m][i], mechs[m].get_output_values(s)[i])
def test_two_ABB(self): A = TransferMechanism( name='A', default_variable=[0], function=Linear(slope=2.0), ) B = IntegratorMechanism(name='B', default_variable=[0], function=SimpleIntegrator(rate=.5)) p = Process(default_variable=[0], pathway=[A, B], name='p') s = System(processes=[p], name='s') term_conds = {TimeScale.TRIAL: AfterNCalls(B, 2)} stim_list = {A: [[1]]} sched = Scheduler(system=s) sched.add_condition(A, Any(AtPass(0), AfterNCalls(B, 2))) sched.add_condition(B, Any(JustRan(A), JustRan(B))) s.scheduler_processing = sched s.run(inputs=stim_list, termination_processing=term_conds) terminal_mech = B expected_output = [ numpy.array([2.]), ] for i in range(len(expected_output)): numpy.testing.assert_allclose( expected_output[i], terminal_mech.get_output_values(s)[i])
def test_converging_pathways(self): a = TransferMechanism(name="a", default_variable=[0, 0, 0]) b = TransferMechanism(name="b") c = TransferMechanism(name="c", default_variable=[0, 0, 0, 0, 0]) LC = LCControlMechanism(modulated_mechanisms=[a,b], objective_mechanism=ObjectiveMechanism(function=Linear, monitor=[b], name='lc_om'), name="lc" ) p = Process(name="p", pathway=[a, c]) p2 = Process(name="p2", pathway=[b, c]) s = System(name="s", processes=[p, p2]) a_label = s._get_label(a, ALL) b_label = s._get_label(b, ALL) c_label = s._get_label(c, ALL) assert "out (3)" in a_label and "in (3)" in a_label assert "out (1)" in b_label and "in (1)" in b_label assert "out (5)" in c_label and "in (5)" in c_label
def test_buffer_as_function_of_origin_mech_in_system(self): P = ProcessingMechanism(function=Buffer(default_variable=[[0.0]], initializer=[[0.0]], history=3)) process = Process(pathway=[P]) system = System(processes=[process]) P.reinitialize_when = Never() full_result = [] def assemble_full_result(): full_result.append(P.parameters.value.get(system)) result = system.run(inputs={P: [[1.0], [2.0], [3.0], [4.0], [5.0]]}, call_after_trial=assemble_full_result) # only returns index 0 item of the deque on each trial (output state value) assert np.allclose(result, [[[0.0]], [[0.0]], [[1.0]], [[2.0]], [[3.0]]]) # stores full mechanism value (full deque) on each trial expected_full_result = [np.array([[0.], [1.]]), np.array([[0.], [1.], [2.]]), np.array([[1.], [2.], [3.]]), # Shape change np.array([[2.], [3.], [4.]]), np.array([[3.], [4.], [5.]])] for i in range(5): assert np.allclose(expected_full_result[i], full_result[i])
def test_previous_value_stored(self): G = LCAMechanism(integrator_mode=True, leak=-1.0, noise=0.0, time_step_size=0.02, function=Linear(slope=2.0), self_excitation=1.0, competition=-1.0, initial_value=np.array([[1.0]])) P = Process(pathway=[G]) S = System(processes=[P]) G.output_state.value = [0.0] # - - - - - LCAMechanism integrator functions - - - - - # X = previous_value + (rate * previous_value + variable) * self.time_step_size + noise # f(X) = 2.0*X + 0 # - - - - - starting values - - - - - # variable = G.output_state.value + stimulus = 0.0 + 1.0 = 1.0 # previous_value = initial_value = 1.0 # single_run = S.execute([[1.0]]) # np.testing.assert_allclose(single_run, np.array([[2.0]])) np.testing.assert_allclose(S.execute([[1.0]]), np.array([[2.0]])) # X = 1.0 + (-1.0 + 1.0)*0.02 + 0.0 # X = 1.0 + 0.0 + 0.0 = 1.0 <--- previous value 1.0 # f(X) = 2.0*1.0 <--- return 2.0, recurrent projection 2.0 np.testing.assert_allclose(S.execute([[1.0]]), np.array([[2.08]])) # X = 1.0 + (-1.0 + 3.0)*0.02 + 0.0 # X = 1.0 + 0.04 = 1.04 <--- previous value 1.04 # f(X) = 2.0*1.04 <--- return 2.08 np.testing.assert_allclose(S.execute([[1.0]]), np.array([[2.1616]]))
def test_reinitialize_one_mechanism_at_trial_2_condition(self): A = TransferMechanism(name='A') B = TransferMechanism(name='B', integrator_mode=True, integration_rate=0.5) C = TransferMechanism(name='C') abc_process = Process(pathway=[A, B, C]) abc_system = System(processes=[abc_process]) # Set reinitialization condition B.reinitialize_when = AtTrial(2) C.log.set_log_conditions('value') abc_system.run(inputs={A: [1.0]}, reinitialize_values={B: [0.]}, num_trials=5) # Trial 0: 0.5, Trial 1: 0.75, Trial 2: 0.5, Trial 3: 0.75. Trial 4: 0.875 assert np.allclose( C.log.nparray_dictionary('value')[ abc_system.default_execution_id]['value'], [[np.array([0.5])], [np.array([0.75])], [np.array([0.5])], [np.array([0.75])], [np.array([0.875])]])
def test_2_target_mechanisms_fn_spec(self): A = TransferMechanism(name="learning-process-mech-A") B = TransferMechanism(name="learning-process-mech-B") C = TransferMechanism(name="learning-process-mech-C") LP = Process(name="learning-process", pathway=[A, B], learning=ENABLED) LP2 = Process(name="learning-process2", pathway=[A, C], learning=ENABLED) S = System( name="learning-system", processes=[LP, LP2], ) def target_function(): val_1 = NormalDist(mean=3.0)() val_2 = NormalDist(mean=3.0)() return [val_1, val_2] with pytest.raises(RunError) as error_text: S.run(inputs={A: [[[1.0]]]}, targets=target_function) assert 'Target values for' in str(error_text.value) and \ 'must be specified in a dictionary' in str(error_text.value)
def test_change_termination_condition(self): D = DDM(function=DriftDiffusionIntegrator(threshold=10)) P = Process(pathway=[D]) S = System(processes=[P]) D.set_log_conditions(VALUE) def change_termination_processing(): if S.termination_processing is None: S.scheduler_processing.termination_conds = {TimeScale.TRIAL: WhenFinished(D)} S.termination_processing = {TimeScale.TRIAL: WhenFinished(D)} elif isinstance(S.termination_processing[TimeScale.TRIAL], AllHaveRun): S.scheduler_processing.termination_conds = {TimeScale.TRIAL: WhenFinished(D)} S.termination_processing = {TimeScale.TRIAL: WhenFinished(D)} else: S.scheduler_processing.termination_conds = {TimeScale.TRIAL: AllHaveRun()} S.termination_processing = {TimeScale.TRIAL: AllHaveRun()} change_termination_processing() S.run(inputs={D: [[1.0], [2.0]]}, # termination_processing={TimeScale.TRIAL: WhenFinished(D)}, call_after_trial=change_termination_processing, num_trials=4) # Trial 0: # input = 1.0, termination condition = WhenFinished # 10 passes (value = 1.0, 2.0 ... 9.0, 10.0) # Trial 1: # input = 2.0, termination condition = AllHaveRun # 1 pass (value = 2.0) expected_results = [[np.array([[10.]]), np.array([[10.]])], [np.array([[2.]]), np.array([[1.]])], [np.array([[10.]]), np.array([[10.]])], [np.array([[2.]]), np.array([[1.]])]] assert np.allclose(expected_results, S.results)
def cyclic_extended_loop(self): a = TransferMechanism(name='a', default_variable=[0, 0]) b = TransferMechanism(name='b') c = TransferMechanism(name='c') d = TransferMechanism(name='d') e = TransferMechanism(name='e', default_variable=[0]) f = TransferMechanism(name='f') p1 = Process(pathway=[a, b, c, d], name='p1') p2 = Process(pathway=[e, c, f, b, d], name='p2') s = System( processes=[p1, p2], name='Cyclic System with Extended Loop', initial_values={a: [1, 1]}, ) inputs = {a: [2, 2], e: [0]} s.run(inputs=inputs) assert set([a, c]) == set(s.origin_mechanisms.mechanisms) assert [d] == s.terminal_mechanisms.mechanisms assert a.systems[s] == ORIGIN assert b.systems[s] == CYCLE assert c.systems[s] == INTERNAL assert d.systems[s] == TERMINAL assert e.systems[s] == ORIGIN assert f.systems[s] == INITIALIZE_CYCLE
def test_convergent(self): a = TransferMechanism(name='a', default_variable=[0, 0]) b = TransferMechanism(name='b') c = TransferMechanism(name='c') c = TransferMechanism(name='c', default_variable=[0]) d = TransferMechanism(name='d') e = TransferMechanism(name='e') p1 = Process(pathway=[a, b, e], name='p1') p2 = Process(pathway=[c, d, e], name='p2') s = System( processes=[p1, p2], name='Convergent System', initial_values={a: [1, 1]}, ) inputs = {a: [[2, 2]], c: [[0]]} s.run(inputs=inputs) assert set([a, c]) == set(s.origin_mechanisms.mechanisms) assert [e] == s.terminal_mechanisms.mechanisms assert a.systems[s] == ORIGIN assert b.systems[s] == INTERNAL assert c.systems[s] == ORIGIN assert d.systems[s] == INTERNAL assert e.systems[s] == TERMINAL
def test_dict_of_subdicts(self): input_labels_dict_M1 = {"red": [1, 1], "green": [0, 0]} output_labels_dict_M2 = {0: {"red": [0, 0], "green": [1, 1]}} M1 = ProcessingMechanism( size=2, params={INPUT_LABELS_DICT: input_labels_dict_M1}) M2 = ProcessingMechanism( size=2, params={OUTPUT_LABELS_DICT: output_labels_dict_M2}) P = Process(pathway=[M1, M2], learning=ENABLED, learning_rate=0.25) S = System(processes=[P]) learned_matrix = [] count = [] def record_matrix_after_trial(): learned_matrix.append(M2.path_afferents[0].get_mod_matrix(S)) count.append(1) S.run(inputs=['red', 'green', 'green', 'red'], targets=['red', 'green', 'green', 'red'], call_after_trial=record_matrix_after_trial) assert np.allclose(S.results, [[[1, 1]], [[0., 0.]], [[0., 0.]], [[0.5, 0.5]]]) assert np.allclose(learned_matrix, [ np.array([[0.75, -0.25], [-0.25, 0.75]]), np.array([[0.75, -0.25], [-0.25, 0.75]]), np.array([[0.75, -0.25], [-0.25, 0.75]]), np.array([[0.625, -0.375], [-0.375, 0.625]]) ])
def test_not_all_output_port_values_have_label(self): input_labels_dict = { "red": [1.0, 0.0], "green": [0.0, 1.0], "blue": [2.0, 2.0] } output_labels_dict = {"red": [1.0, 0.0], "green": [0.0, 1.0]} M = ProcessingMechanism(size=2, params={ INPUT_LABELS_DICT: input_labels_dict, OUTPUT_LABELS_DICT: output_labels_dict }) P = Process(pathway=[M]) S = System(processes=[P]) store_output_labels = [] def call_after_trial(): store_output_labels.append(M.get_output_labels(S)) S.run(inputs=['red', 'blue', 'green', 'blue'], call_after_trial=call_after_trial) assert np.allclose( S.results, [[[1.0, 0.0]], [[2.0, 2.0]], [[0.0, 1.0]], [[2.0, 2.0]]]) assert store_output_labels[0] == ['red'] assert np.allclose(store_output_labels[1], [[2.0, 2.0]]) assert store_output_labels[2] == ['green'] assert np.allclose(store_output_labels[3], [[2.0, 2.0]])
def test_bypass(self): a = TransferMechanism(name='a', default_variable=[0, 0]) b = TransferMechanism(name='b', default_variable=[0, 0]) c = TransferMechanism(name='c') d = TransferMechanism(name='d') p1 = Process(pathway=[a, b, c, d], name='p1') p2 = Process(pathway=[a, b, d], name='p2') s = System( processes=[p1, p2], name='Bypass System', initial_values={a: [1, 1]}, ) inputs = {a: [[2, 2], [0, 0]]} s.run(inputs=inputs) assert [a] == s.origin_mechanisms.mechanisms assert [d] == s.terminal_mechanisms.mechanisms assert a.systems[s] == ORIGIN assert b.systems[s] == INTERNAL assert c.systems[s] == INTERNAL assert d.systems[s] == TERMINAL
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)
def test_reinforcement_fixed_targets(): input_layer = TransferMechanism( size=2, name='Input Layer', ) action_selection = pnl.DDM(input_format=pnl.ARRAY, function=pnl.DriftDiffusionAnalytical(), output_states=[pnl.SELECTED_INPUT_ARRAY], name='DDM') p = Process(pathway=[input_layer, action_selection], learning=LearningProjection(learning_function=Reinforcement( learning_rate=0.05))) input_list = {input_layer: [[1, 1], [1, 1]]} s = System(processes=[p], # learning_rate=0.05, ) targets = [[10.], [10.]] # logged_mechanisms = [input_layer, action_selection] # for mech in s.learning_mechanisms: # logged_mechanisms.append(mech) # # for mech in logged_mechanisms: # mech.log.set_log_conditions(items=[pnl.VALUE]) results = s.run(inputs=input_list, targets=targets) assert np.allclose(action_selection.value, [[1.], [2.30401336], [0.97340301], [0.02659699], [2.30401336], \ [2.08614798], [1.85006765], [2.30401336], [2.08614798], [1.85006765]])
def test_udf_system_origin(self): def myFunction(variable, params, context): return [variable[0][1], variable[0][0]] myMech = ProcessingMechanism(function=myFunction, size=3, name='myMech') T = TransferMechanism(size=2, function=Linear) p = Process(pathway=[myMech, T]) s = System(processes=[p]) s.run(inputs = {myMech: [[1, 3, 5]]}) assert np.allclose(s.results[0][0], [3, 1])
def test_udf_system_terminal(self): def myFunction(variable, params, context): return [variable[0][2], variable[0][0]] myMech = ProcessingMechanism(function=myFunction, size=3, name='myMech') T2 = TransferMechanism(size=3, function=Linear) p2 = Process(pathway=[T2, myMech]) s2 = System(processes=[p2]) s2.run(inputs = {T2: [[1, 2, 3]]}) assert(np.allclose(s2.results[0][0], [3, 1]))
def run_twice_in_system(mech, input1, input2=None): if input2 is None: input2 = input1 simple_prefs = {REPORT_OUTPUT_PREF: False, VERBOSE_PREF: False} simple_process = Process(size=mech.size[0], pathway=[mech], name='simple_process') simple_system = System(processes=[simple_process], name='simple_system', prefs=simple_prefs) first_output = simple_system.run(inputs={mech: [input1]}) second_output = simple_system.run(inputs={mech: [input2]}) return second_output[1][0]
def test_kwta_threshold_float(self): K = KWTAMechanism(name='K', size=4, threshold=0.5) p = Process(pathway=[K], prefs=TestKWTARatio.simple_prefs) s = System(processes=[p], prefs=TestKWTARatio.simple_prefs) s.run(inputs={K: [1, 2, 3, 3]}) assert np.allclose( K.parameters.value.get(s), [[0.2689414213699951, 0.5, 0.7310585786300049, 0.7310585786300049] ])
def test_kwta_threshold_int(self): K = KWTAMechanism(name='K', size=4, threshold=-1) p = Process(pathway=[K], prefs=TestKWTAThreshold.simple_prefs) s = System(processes=[p], prefs=TestKWTAThreshold.simple_prefs) s.run(inputs={K: [1, 2, 3, 4]}) assert np.allclose(K.parameters.value.get(s), [[ 0.07585818002124355, 0.18242552380635635, 0.3775406687981454, 0.6224593312018546 ]])
def test_heterogeneous_variables(self): # from psyneulink.core.components.mechanisms.processing.objectivemechanism import ObjectiveMechanism a = TransferMechanism(name='a', default_variable=[[0.0], [0.0, 0.0]]) p1 = Process(pathway=[a]) s = System(processes=[p1]) inputs = {a: [[[1.1], [2.1, 2.1]], [[1.2], [2.2, 2.2]]]} s.run(inputs)
def test_is_finished_stops_system(self): D = DDM(name='DDM', function=DriftDiffusionIntegrator(threshold=10.0)) P = Process(pathway=[D]) S = System(processes=[P], reinitialize_mechanisms_when=Never()) S.run(inputs={D: 2.0}, termination_processing={TimeScale.TRIAL: WhenFinished(D)}) # decision variable's value should match threshold assert D.parameters.value.get(S)[0] == 10.0 # it should have taken 5 executions (and time_step_size = 1.0) assert D.parameters.value.get(S)[1] == 5.0
def test_kwta_k_value_empty_size_4(self): K = KWTAMechanism( name='K', size=4 ) assert K.k_value == 0.5 p = Process(pathway=[K], prefs=TestKWTARatio.simple_prefs) s = System(processes=[p], prefs=TestKWTARatio.simple_prefs) s.run(inputs={K: [1, 2, 3, 4]}) assert np.allclose(K.parameters.value.get(s), [[0.18242552380635635, 0.3775406687981454, 0.6224593312018546, 0.8175744761936437]])
def test_kwta_average_k_1(self): K = KWTAMechanism(name='K', size=4, k_value=1, threshold=0, function=Linear, average_based=True) p = Process(pathway=[K], prefs=TestKWTAAverageBased.simple_prefs) s = System(processes=[p], prefs=TestKWTAAverageBased.simple_prefs) kwta_input = {K: [[1, 2, 3, 4]]} s.run(inputs=kwta_input) assert np.allclose(K.parameters.value.get(s), [[-2, -1, 0, 1]])
def test_input_not_provided_to_run(self): T = TransferMechanism(name='T', default_variable=[[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]) T2 = TransferMechanism(name='T2', function=Linear(slope=2.0), default_variable=[[0.0, 0.0]]) P = Process(pathway=[T, T2]) S = System(processes=[P]) run_result = S.run() assert np.allclose(T.parameters.value.get(S), [[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]) assert np.allclose(run_result, [[np.array([2.0, 4.0])]])
def test_ris_simple(self): R2 = RecurrentTransferMechanism(default_variable=[[0.0, 0.0, 0.0]], matrix=[[1.0, 2.0, 3.0], [2.0, 1.0, 2.0], [3.0, 2.0, 1.0]], has_recurrent_input_state=True) R2.execute(input=[1, 3, 2]) p2 = Process(pathway=[R2]) s2 = System(processes=[p2]) s2.run(inputs=[[1, 3, 2]]) np.testing.assert_allclose(R2.parameters.value.get(s2), [[14., 12., 13.]]) assert len(R2.input_states) == 2 assert "Recurrent Input State" not in R2.input_state.name # make sure recurrent input state isn't primary
def test_LCAMechanism_length_1(self): T = TransferMechanism(function=Linear(slope=1.0)) L = LCAMechanism( function=Linear(slope=2.0), self_excitation=3.0, leak=0.5, competition= 1.0, # competition does not matter because we only have one unit 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][0]) S.run(inputs={T: [1.0]}, num_trials=3, call_after_trial=record_execution) # - - - - - - - TRIAL 1 - - - - - - - # new_transfer_input = 0.0 + ( 0.5 * 0.0 + 3.0 * 0.0 + 0.0 + 1.0)*0.1 + 0.0 = 0.1 # f(new_transfer_input) = 0.1 * 2.0 = 0.2 # - - - - - - - TRIAL 2 - - - - - - - # new_transfer_input = 0.1 + ( 0.5 * 0.1 + 3.0 * 0.2 + 0.0 + 1.0)*0.1 + 0.0 = 0.265 # f(new_transfer_input) = 0.265 * 2.0 = 0.53 # - - - - - - - TRIAL 3 - - - - - - - # new_transfer_input = 0.265 + ( 0.5 * 0.265 + 3.0 * 0.53 + 0.0 + 1.0)*0.1 + 0.0 = 0.53725 # f(new_transfer_input) = 0.53725 * 2.0 = 1.0745 assert np.allclose(results, [0.2, 0.53, 1.0745])
def test_recurrent_mech_auto_associative_projection(self): T = TransferMechanism(default_variable=[[0.0, 0.0, 0.0]]) recurrent_mech = RecurrentTransferMechanism(default_variable=[[0.0, 0.0, 0.0]], matrix=AutoAssociativeProjection) p = Process(pathway=[T, recurrent_mech]) s = System(processes=[p]) results = [] def record_trial(): results.append(recurrent_mech.parameters.value.get(s)) s.run(inputs=[[1.0, 1.0, 1.0], [2.0, 2.0, 2.0]], call_after_trial=record_trial)
def test_dict_of_arrays(self): input_labels_dict = { "red": [1, 0, 0], "green": [0, 1, 0], "blue": [0, 0, 1] } M = ProcessingMechanism(default_variable=[[0, 0, 0]], params={INPUT_LABELS_DICT: input_labels_dict}) P = Process(pathway=[M]) S = System(processes=[P]) store_input_labels = [] def call_after_trial(): store_input_labels.append(M.get_input_labels(S)) S.run(inputs=['red', 'green', 'blue', 'red'], call_after_trial=call_after_trial) assert np.allclose( S.results, [[[1, 0, 0]], [[0, 1, 0]], [[0, 0, 1]], [[1, 0, 0]]]) assert store_input_labels == [['red'], ['green'], ['blue'], ['red']] S.run(inputs='red') assert np.allclose( S.results, [[[1, 0, 0]], [[0, 1, 0]], [[0, 0, 1]], [[1, 0, 0]], [[1, 0, 0]]]) S.run(inputs=['red']) assert np.allclose(S.results, [[[1, 0, 0]], [[0, 1, 0]], [[0, 0, 1]], [[1, 0, 0]], [[1, 0, 0]], [[1, 0, 0]]])
def test_dict_list_and_function(self): A = TransferMechanism(name="diverging-learning-pathways-mech-A") B = TransferMechanism(name="diverging-learning-pathways-mech-B") C = TransferMechanism(name="diverging-learning-pathways-mech-C") D = TransferMechanism(name="diverging-learning-pathways-mech-D") E = TransferMechanism(name="diverging-learning-pathways-mech-E") P1 = Process(name="learning-pathway-1", pathway=[A, B, C], learning=ENABLED) P2 = Process(name="learning-pathway-2", pathway=[A, D, E], learning=ENABLED) S = System(name="learning-system", processes=[P1, P2]) def target_function(): val_1 = NormalDist(mean=3.0)() return val_1 S.run(inputs={A: 1.0}, targets={C: 2.0, E: target_function}) S.run(inputs={A: 1.0}, targets={C: [2.0], E: target_function}) S.run(inputs={A: 1.0}, targets={C: [[2.0]], E: target_function})