def test_AtPass_in_middle(self): comp = Composition() A = TransferMechanism(function=Linear(slope=5.0, intercept=2.0), name='A') comp.add_node(A) sched = Scheduler(composition=comp) sched.add_condition(A, AtPass(2)) termination_conds = {} termination_conds[TimeScale.RUN] = AfterNTrials(1) termination_conds[TimeScale.TRIAL] = AtPass(5) output = list(sched.run(termination_conds=termination_conds)) expected_output = [set(), set(), A, set(), set()] assert output == pytest.helpers.setify_expected_output( expected_output)
def test_termination_conditions_reset(self): A = IntegratorMechanism(name='A', default_variable=[0], function=SimpleIntegrator(rate=.5)) B = TransferMechanism( name='B', default_variable=[0], function=Linear(slope=2.0), ) c = Composition(pathways=[[A, B]]) term_conds = {TimeScale.TRIAL: AfterNCalls(B, 2)} stim_list = {A: [[1]]} sched = Scheduler(composition=c) sched.add_condition(B, EveryNCalls(A, 2)) c.scheduler = sched c.run(inputs=stim_list, termination_processing=term_conds) # A should run four times terminal_mech = B expected_output = [ numpy.array([4.]), ] for i in range(len(expected_output)): numpy.testing.assert_allclose( expected_output[i], terminal_mech.get_output_values(c)[i]) c.run(inputs=stim_list, ) # A should run an additional two times terminal_mech = B expected_output = [ numpy.array([6.]), ] for i in range(len(expected_output)): numpy.testing.assert_allclose( expected_output[i], terminal_mech.get_output_values(c)[i])
def test_All_end_after_one_finished(self): comp = Composition() A = TransferMechanism(function=Linear(slope=5.0, intercept=2.0), name='A') for m in [A]: comp.add_node(m) sched = Scheduler(composition=comp) sched.add_condition(A, EveryNPasses(1)) termination_conds = {} termination_conds[TimeScale.RUN] = AfterNTrials(1) termination_conds[TimeScale.TRIAL] = Any(AfterNCalls(A, 5), AtPass(10)) output = list(sched.run(termination_conds=termination_conds)) expected_output = [A for _ in range(5)] assert output == pytest.helpers.setify_expected_output( expected_output)
def test_AfterTrial(self): comp = Composition() A = TransferMechanism(function=Linear(slope=5.0, intercept=2.0), name='A') comp.add_node(A) sched = Scheduler(composition=comp) sched.add_condition(A, Always()) termination_conds = {} termination_conds[TimeScale.RUN] = AfterTrial(4) termination_conds[TimeScale.TRIAL] = AtPass(1) comp.run(inputs={A: range(6)}, scheduler=sched, termination_processing=termination_conds) output = sched.execution_list[comp.default_execution_id] expected_output = [A, A, A, A, A] assert output == pytest.helpers.setify_expected_output( expected_output)
def test_BeforeTimeStep_2(self): comp = Composition() A = TransferMechanism(function=Linear(slope=5.0, intercept=2.0), name='A') B = TransferMechanism(name='B') comp.add_node(A) comp.add_node(B) comp.add_projection(MappingProjection(), A, B) sched = Scheduler(composition=comp) sched.add_condition(A, BeforeTimeStep(2)) sched.add_condition(B, Always()) termination_conds = {} termination_conds[TimeScale.RUN] = AfterNTrials(1) termination_conds[TimeScale.TRIAL] = AtPass(5) output = list(sched.run(termination_conds=termination_conds)) expected_output = [A, B, B, B, B, B] assert output == pytest.helpers.setify_expected_output( expected_output)
def test_WhileNot_AtPass_in_middle(self): comp = Composition() A = TransferMechanism(function=Linear(slope=5.0, intercept=2.0), name='A') comp.add_node(A) sched = Scheduler(composition=comp) sched.add_condition( A, WhileNot( lambda sched: sched.get_clock( sched.default_execution_id).get_total_times_relative( TimeScale.PASS, TimeScale.TRIAL) == 2, sched)) termination_conds = {} termination_conds[TimeScale.RUN] = AfterNTrials(1) termination_conds[TimeScale.TRIAL] = AtPass(5) output = list(sched.run(termination_conds=termination_conds)) expected_output = [A, A, set(), A, A] assert output == pytest.helpers.setify_expected_output( expected_output)
def test_three_2_ABCx2(self): A = IntegratorMechanism(name='A', default_variable=[0], function=SimpleIntegrator(rate=.5)) B = IntegratorMechanism(name='B', default_variable=[0], function=SimpleIntegrator(rate=1)) C = TransferMechanism( name='C', default_variable=[0], function=Linear(slope=2.0), ) c = Composition(pathways=[[A, C], [B, C]]) term_conds = {TimeScale.TRIAL: AfterNCalls(C, 2)} stim_list = {A: [[1]], B: [[2]]} sched = Scheduler(composition=c) sched.add_condition(C, All(EveryNCalls(A, 1), EveryNCalls(B, 1))) c.scheduler = sched c.run(inputs=stim_list, termination_processing=term_conds) terminal_mechs = [C] expected_output = [ [ numpy.array([10.]), ], ] for m in range(len(terminal_mechs)): for i in range(len(expected_output[m])): numpy.testing.assert_allclose( expected_output[m][i], terminal_mechs[m].get_output_values(c)[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]])) C = Composition(pathways=[G]) G.output_port.parameters.value.set([0.0], override=True) # - - - - - 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_port.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(C.execute(inputs={G: [[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(C.execute(inputs={G: [[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(C.execute(inputs={G: [[1.0]]}), np.array([[2.1616]]))
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_compositions_as_origin_nodes_multiple_trials(self, comp_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_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) 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) inner_composition_1._analyze_graph() outer_composition.add_projection(projection=MappingProjection(), sender=inner_composition_1, receiver=mechanism_d) inner_composition_2._analyze_graph() outer_composition.add_projection(projection=MappingProjection(), sender=inner_composition_2, receiver=mechanism_d) sched = Scheduler(composition=outer_composition) # FIX: order of InputPorts 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=sched, execution_mode=comp_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_compositions_as_origin_nodes(self, comp_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_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) 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) # FIX: order of InputPorts 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=sched, execution_mode=comp_mode) assert np.allclose(output, [[[36.]]]) if comp_mode is pnlvm.ExecutionMode.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_connect_compositions_with_complicated_states(self, comp_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_ports[1], receiver=B.input_ports[1]), A, B) 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_ports[1], receiver=B2.input_ports[1]), A2, B2) 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_ports[1], receiver=inner_composition_2.input_CIM.input_ports[1]), sender=inner_composition_1, receiver=inner_composition_2) sched = Scheduler(composition=outer_composition) output = outer_composition.run( inputs={inner_composition_1: [[[5.0], [50.0]]]}, scheduler=sched, execution_mode=comp_mode) assert np.allclose(output, [[[180.], [1800.]]]) if comp_mode is pnlvm.ExecutionMode.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_connect_compositions_with_simple_states(self, comp_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) 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) 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.]]}, execution_mode=comp_mode) assert np.allclose(res, [[[180.0]]]) if comp_mode is pnlvm.ExecutionMode.Python: assert np.allclose(comp1.output_port.parameters.value.get(comp3), [30.0]) assert np.allclose(comp2.output_port.parameters.value.get(comp3), [180.0]) assert np.allclose(comp3.output_port.parameters.value.get(comp3), [180.0])
def test_LCAMechanism_length_2(self, benchmark, comp_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, execution_mode=comp_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, execution_mode=comp_mode)