Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/composition existing projections #2763

Merged
merged 6 commits into from
Aug 4, 2023

Conversation

jdcpni
Copy link
Collaborator

@jdcpni jdcpni commented Aug 4, 2023

• composition.py
  - _check_for_existing_projections():
    augment to search over all input_ports and output_ports;
NOTE: if a mechanism is specified as sender and/or receiver, then any existing Projection between the two (i.e., between any pair of input_port/output_ports) will be returned as existing;  to support multiple projections (between different pairs of Ports), must specify Ports explicitly

• combinationfunctions.py
  LinearCombination.derivative: return Jacobian for first item in variable[0] relative to others

• composition.py
  _create_non_terminal_backprop_learning_components(): modify to handle multiple args in output_source for learning_function and learning_mechanism
• combinationfunctions.py
  LinearCombination.derivative: return Jacobian for first item in variable[0] relative to others

• composition.py
  _create_non_terminal_backprop_learning_components(): modify to handle multiple args in output_source for learning_function and learning_mechanism
• composition.py
  - _check_for_existing_projections():
    augment to search over all input_ports and output_ports;
    NOTE: if a mechanism is specified as sender and/or receiver, then any existing Projection between the two (i.e., between any pair of input_port/output_ports) will be returned as existing;  to support multiple projections (between different pairs of Ports), must specify Ports explicitly
@github-actions
Copy link

github-actions bot commented Aug 4, 2023

This PR causes the following changes to the html docs (ubuntu-latest-3.7-x64):

diff -r docs-base/CombinationFunctions.html docs-head/CombinationFunctions.html
1091a1092,1109
> <dl class="py method">
> <dt class="sig sig-object py" id="psyneulink.core.components.functions.combinationfunctions.LinearCombination.derivative">
> <span class="sig-name descname"><span class="pre">derivative</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">input</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.core.components.functions.combinationfunctions.LinearCombination.derivative" title="Permalink to this definition">¶</a></dt>
> <dd><p>Derivative of <a class="reference internal" href="#psyneulink.core.components.functions.combinationfunctions.LinearCombination._function" title="psyneulink.core.components.functions.combinationfunctions.LinearCombination._function"><code class="xref any py py-meth docutils literal notranslate"><span class="pre">function</span></code></a> at <strong>input</strong>.</p>
> <dl class="field-list simple">
> <dt class="field-odd">Parameters</dt>
> <dd class="field-odd"><p><strong>input</strong> (<em>1d</em><em> or </em><em>2d np.array : default class_defaults.variable</em>) – value of the input to the Linear transform at which derivative is to be taken.
> a single numeric array or multiple arrays being combined, and at which derivative is to be taken.</p>
> </dd>
> <dt class="field-even">Returns</dt>
> <dd class="field-even"><p><strong>Scale</strong></p>
> </dd>
> <dt class="field-odd">Return type</dt>
> <dd class="field-odd"><p>number (if input is 1d) or array (if input is 2d)</p>
> </dd>
> </dl>
> </dd></dl>
> 
diff -r docs-base/Composition.html docs-head/Composition.html
3881c3881,3883
< already specified.  If an item in the list is a list of projections, called recursively on that list.</p>
---
> already specified.  If an item in the list is a list of projections, <code class="docutils literal notranslate"><span class="pre">add_projections</span></code> is called
> recursively on that list.  See <a class="reference internal" href="#psyneulink.core.compositions.composition.Composition.add_projection" title="psyneulink.core.compositions.composition.Composition.add_projection"><code class="xref any py py-meth docutils literal notranslate"><span class="pre">add_projection</span></code></a> for additional details
> of how duplicates are determined and handled.</p>
3909c3911
< <ul class="simple">
---
> <ul>
3911,3914c3913,3922
< - if there is only one, that Projection is used;
< - if there is more than one, the last in the list (presumably the most recent) is used;
< in either case, processing continues, to activate it for the Composition,
< construct any “shadow” projections that may be specified, and assign feedback if specified.</p></li>
---
> - if there is only one, that Projection is used (it can be between any pair of the sender’s OutputPort</p>
> <blockquote>
> <div><p>and receiver’s InputPort)</p>
> </div></blockquote>
> <ul class="simple">
> <li><p>if there is more than one, the last in the list (presumably the most recent) is used;</p></li>
> </ul>
> <p>in either case, processing continues, to activate it for the Composition,
> construct any “shadow” projections that may be specified, and assign feedback if specified.</p>
> </li>
3937c3945,3949
< (to allow multiple Projections to exist between the same pair of Mechanisms using different Ports).
---
> (to allow multiple Projections to exist between the same pair of Mechanisms using different Ports);
> If the sender and/or the receiver is specified as a Mechanism, a Projection from any of a specified
> sender’s OutputPorts to any of a specified receiver’s InputPorts will be considered a match. However,
> if both sender and receiver are specified as Ports, then only a Projection from the sender to the receiver
> will be considered a match, allowing other Projections to remain between that pair of Nodes.
4003c4015
< <dd><p>Check for Projection with same sender and receiver
---
> <dd><p>Check for Projection between the same pair of Nodes
4005c4017,4025
< If <strong>in_composition</strong> is False, return only Projections that are found outside the current Composition</p>
---
> If <strong>in_composition</strong> is False, return only Projections that are found outside the current Composition
> IMPLEMENTATION NOTE:</p>
> <blockquote>
> <div><p>Currently if the sender and/or the receiver is specified as a Mechanism,
> a Projection from/to any of its OutputPorts/InputPorts will be considered a match.
> However, if both sender and receiver are specified as Ports, then only a Projection
> from the sender to the receiver will be considered a match, allowing other Projections
> to remain between that pair of Nodes.</p>
> </div></blockquote>
diff -r docs-base/genindex.html docs-head/genindex.html
1930c1930
<       <li><a href="DistributionFunctions.html#psyneulink.core.components.functions.distributionfunctions.DriftDiffusionAnalytical.derivative">derivative() (psyneulink.core.components.functions.distributionfunctions.DriftDiffusionAnalytical method)</a>
---
>       <li><a href="CombinationFunctions.html#psyneulink.core.components.functions.combinationfunctions.LinearCombination.derivative">derivative() (psyneulink.core.components.functions.combinationfunctions.LinearCombination method)</a>
1932a1933,1934
>         <li><a href="DistributionFunctions.html#psyneulink.core.components.functions.distributionfunctions.DriftDiffusionAnalytical.derivative">(psyneulink.core.components.functions.distributionfunctions.DriftDiffusionAnalytical method)</a>
> </li>
Binary files docs-base/objects.inv and docs-head/objects.inv differ
diff -r docs-base/searchindex.js docs-head/searchindex.js
1c1
< Search.setIndex({docnames:["AGT","AGTControlMechanism","AutoAssociativeLearningMechanism","AutoAssociativeProjection","AutodiffComposition","BasicsAndPrimer","BeukersNBackModel","BeukersNBackModel_NB","BotvinickConflictMonitoringModel","BustamanteStroopXORLVOCModel","Cohen_HustonModel","CombinationFunctions","ComparatorMechanism","Compilation","Component","Components","Composition","CompositionFunctionApproximator","CompositionInterfaceMechanism","Compositions","Condition","Context","ContrastiveHebbianMechanism","ContributorsGuide","ControlMechanism","ControlMechanisms","ControlProjection","ControlProjections","ControlSignal","ConventionsAndDefinitions","Core","DDM","DefaultControlMechanism","Defaults","DistributionFunctions","EMComposition","EVC","EVCAuxiliary","EVCControlMechanism","EpisodicMemoryMechanism","Function","Functions","GatingMechanism","GatingMechanisms","GatingProjection","GatingProjections","GatingSignal","GilzenratModel","InputPort","IntegratorFunctions","IntegratorMechanism","IntegratorMechanisms","KWTAMechanism","Keywords","KohonenMechanism","LCAMechanism","LCControlMechanism","LCMechanism","LLVM","LeabraMechanism","LearningFunctions","LearningMechanism","LearningMechanisms","LearningProjection","LearningProjections","LearningSignal","Library","Log","MappingProjection","MaskedMappingProjection","Mechanism","Mechanisms","MemoryFunctions","Models","ModulatoryMechanism","ModulatoryMechanisms","ModulatoryProjection","ModulatoryProjections","ModulatorySignal","MontagueModel","NieuwenhuisModel","NonStatefulFunctions","ObjectiveFunctions","ObjectiveMechanism","ObjectiveMechanisms","OptimizationControlMechanism","OptimizationFunctions","OutputPort","PCTC_model","ParameterEstimationComposition","ParameterPort","Parameters","Pathway","PathwayProjection","PathwayProjections","Port","PredictionErrorMechanism","Preferences","ProcessingMechanism","ProcessingMechanisms","Projection","Projections","QuickReference","RecurrentTransferMechanism","RefactoredLearningGuide","Registry","RegressionCFA","Report","Scheduler","Scheduling","SelectionFunctions","Services","StatefulFunction","StatefulFunctions","Subystems","Time","TransferFunctions","TransferMechanism","TransferMechanisms","UserDefinedFunction","UserGuide","UserGuide_TBD","Visualization","globals","index","index_logo_with_text","mdf","nback_nb"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":4,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,sphinx:56},filenames:["AGT.rst","AGTControlMechanism.rst","AutoAssociativeLearningMechanism.rst","AutoAssociativeProjection.rst","AutodiffComposition.rst","BasicsAndPrimer.rst","BeukersNBackModel.rst","BeukersNBackModel_NB.rst","BotvinickConflictMonitoringModel.rst","BustamanteStroopXORLVOCModel.rst","Cohen_HustonModel.rst","CombinationFunctions.rst","ComparatorMechanism.rst","Compilation.rst","Component.rst","Components.rst","Composition.rst","CompositionFunctionApproximator.rst","CompositionInterfaceMechanism.rst","Compositions.rst","Condition.rst","Context.rst","ContrastiveHebbianMechanism.rst","ContributorsGuide.rst","ControlMechanism.rst","ControlMechanisms.rst","ControlProjection.rst","ControlProjections.rst","ControlSignal.rst","ConventionsAndDefinitions.rst","Core.rst","DDM.rst","DefaultControlMechanism.rst","Defaults.rst","DistributionFunctions.rst","EMComposition.rst","EVC.rst","EVCAuxiliary.rst","EVCControlMechanism.rst","EpisodicMemoryMechanism.rst","Function.rst","Functions.rst","GatingMechanism.rst","GatingMechanisms.rst","GatingProjection.rst","GatingProjections.rst","GatingSignal.rst","GilzenratModel.rst","InputPort.rst","IntegratorFunctions.rst","IntegratorMechanism.rst","IntegratorMechanisms.rst","KWTAMechanism.rst","Keywords.rst","KohonenMechanism.rst","LCAMechanism.rst","LCControlMechanism.rst","LCMechanism.rst","LLVM.rst","LeabraMechanism.rst","LearningFunctions.rst","LearningMechanism.rst","LearningMechanisms.rst","LearningProjection.rst","LearningProjections.rst","LearningSignal.rst","Library.rst","Log.rst","MappingProjection.rst","MaskedMappingProjection.rst","Mechanism.rst","Mechanisms.rst","MemoryFunctions.rst","Models.rst","ModulatoryMechanism.rst","ModulatoryMechanisms.rst","ModulatoryProjection.rst","ModulatoryProjections.rst","ModulatorySignal.rst","MontagueModel.rst","NieuwenhuisModel.rst","NonStatefulFunctions.rst","ObjectiveFunctions.rst","ObjectiveMechanism.rst","ObjectiveMechanisms.rst","OptimizationControlMechanism.rst","OptimizationFunctions.rst","OutputPort.rst","PCTC_model.rst","ParameterEstimationComposition.rst","ParameterPort.rst","Parameters.rst","Pathway.rst","PathwayProjection.rst","PathwayProjections.rst","Port.rst","PredictionErrorMechanism.rst","Preferences.rst","ProcessingMechanism.rst","ProcessingMechanisms.rst","Projection.rst","Projections.rst","QuickReference.rst","RecurrentTransferMechanism.rst","RefactoredLearningGuide.rst","Registry.rst","RegressionCFA.rst","Report.rst","Scheduler.rst","Scheduling.rst","SelectionFunctions.rst","Services.rst","StatefulFunction.rst","StatefulFunctions.rst","Subystems.rst","Time.rst","TransferFunctions.rst","TransferMechanism.rst","TransferMechanisms.rst","UserDefinedFunction.rst","UserGuide.rst","UserGuide_TBD.rst","Visualization.rst","globals.rst","index.rst","index_logo_with_text.rst","mdf.rst","nback_nb.ipynb"],objects:{"psyneulink.core.components":{component:[14,0,0,"-"]},"psyneulink.core.components.component":{Component:[14,1,1,""]},"psyneulink.core.components.component.Component":{"function":[14,4,1,""],_check_args:[14,2,1,""],_check_for_composition:[14,2,1,""],_deferred_init:[14,2,1,""],_dependent_components:[14,3,1,""],_get_allowed_arguments:[14,2,1,""],_get_param_value_from_tuple:[14,2,1,""],_handle_default_variable:[14,2,1,""],_handle_size:[14,2,1,""],_instantiate_defaults:[14,2,1,""],_instantiate_function:[14,2,1,""],_instantiate_parameter_classes:[14,2,1,""],_model_spec_class_name_is_generic:[14,4,1,""],_model_spec_generic_type_name:[14,4,1,""],_model_spec_parameter_blacklist:[14,3,1,""],_parameter_components:[14,3,1,""],_parse_arg_generic:[14,2,1,""],_parse_arg_variable:[14,2,1,""],_parse_function_variable:[14,2,1,""],_receiver_ports:[14,3,1,""],_sender_ports:[14,3,1,""],_set_multiple_parameter_values:[14,2,1,""],_specified_variable_shape_flexibility:[14,4,1,""],_validate:[14,2,1,""],_validate_and_assign_runtime_params:[14,2,1,""],_validate_arguments:[14,2,1,""],_validate_function:[14,2,1,""],_validate_params:[14,2,1,""],_validate_variable:[14,2,1,""],all_dependent_parameters:[14,2,1,""],current_execution_time:[14,4,1,""],defaults:[14,4,1,""],execute:[14,2,1,""],execute_until_finished:[14,4,1,""],execution_count:[14,4,1,""],function_parameters:[14,3,1,""],get_afferents:[14,2,1,""],get_efferents:[14,2,1,""],initialization_status:[14,4,1,""],is_finished:[14,2,1,""],log:[14,4,1,""],log_values:[14,2,1,""],loggable_items:[14,3,1,""],logged_items:[14,3,1,""],max_executions_before_finished:[14,4,1,""],most_recent_context:[14,3,1,""],name:[14,4,1,""],num_executions:[14,4,1,""],num_executions_before_finished:[14,4,1,""],parameters:[14,4,1,""],prefs:[14,4,1,""],reset:[14,2,1,""],reset_params:[14,2,1,""],reset_stateful_function_when:[14,4,1,""],set_delivery_conditions:[14,2,1,""],set_log_conditions:[14,2,1,""],size:[14,4,1,""],stateful_parameters:[14,3,1,"id0"],value:[14,4,1,""],variable:[14,4,1,""]},"psyneulink.core.components.functions":{"function":[41,0,0,"-"],combinationfunctions:[11,0,0,"-"],distributionfunctions:[34,0,0,"-"],learningfunctions:[60,0,0,"-"],objectivefunctions:[82,0,0,"-"],optimizationfunctions:[86,0,0,"-"],selectionfunctions:[110,0,0,"-"],transferfunctions:[116,0,0,"-"],userdefinedfunction:[119,0,0,"-"]},"psyneulink.core.components.functions.combinationfunctions":{CombineMeans:[11,1,1,""],Concatenate:[11,1,1,""],LinearCombination:[11,1,1,""],PredictionErrorDeltaFunction:[11,1,1,""],Rearrange:[11,1,1,""],Reduce:[11,1,1,""]},"psyneulink.core.components.functions.combinationfunctions.CombineMeans":{_function:[11,2,1,""],_validate_params:[11,2,1,""],_validate_variable:[11,2,1,""],exponents:[11,4,1,""],name:[11,4,1,""],offset:[11,4,1,""],operation:[11,4,1,""],owner:[11,4,1,""],prefs:[11,4,1,""],scale:[11,4,1,""],variable:[11,4,1,""],weights:[11,4,1,""]},"psyneulink.core.components.functions.combinationfunctions.Concatenate":{_function:[11,2,1,""],_validate_params:[11,2,1,""],_validate_variable:[11,2,1,""],default_variable:[11,4,1,""],name:[11,4,1,""],offset:[11,4,1,""],owner:[11,4,1,""],prefs:[11,4,1,""],scale:[11,4,1,""]},"psyneulink.core.components.functions.combinationfunctions.LinearCombination":{_function:[11,2,1,""],_validate_params:[11,2,1,""],_validate_variable:[11,2,1,""],exponents:[11,4,1,""],name:[11,4,1,""],offset:[11,4,1,""],operation:[11,4,1,""],owner:[11,4,1,""],prefs:[11,4,1,""],scale:[11,4,1,""],variable:[11,4,1,""],weights:[11,4,1,""]},"psyneulink.core.components.functions.combinationfunctions.PredictionErrorDeltaFunction":{_function:[11,2,1,""],_validate_params:[11,2,1,""],_validate_variable:[11,2,1,""]},"psyneulink.core.components.functions.combinationfunctions.Rearrange":{_function:[11,2,1,""],_instantiate_attributes_before_function:[11,2,1,""],_validate_params:[11,2,1,""],_validate_variable:[11,2,1,""],arrangement:[11,4,1,""],default_variable:[11,4,1,""],name:[11,4,1,""],offset:[11,4,1,""],owner:[11,4,1,""],prefs:[11,4,1,""],scale:[11,4,1,""]},"psyneulink.core.components.functions.combinationfunctions.Reduce":{_function:[11,2,1,""],_validate_params:[11,2,1,""],_validate_variable:[11,2,1,""],default_variable:[11,4,1,""],name:[11,4,1,""],offset:[11,4,1,""],operation:[11,4,1,""],owner:[11,4,1,""],prefs:[11,4,1,""],scale:[11,4,1,""]},"psyneulink.core.components.functions.distributionfunctions":{DistributionFunction:[34,1,1,""],DriftDiffusionAnalytical:[34,1,1,""],ExponentialDist:[34,1,1,""],GammaDist:[34,1,1,""],NormalDist:[34,1,1,""],UniformDist:[34,1,1,""],UniformToNormalDist:[34,1,1,""],WaldDist:[34,1,1,""]},"psyneulink.core.components.functions.distributionfunctions.DriftDiffusionAnalytical":{_compute_conditional_rt_moments:[34,2,1,""],_function:[34,2,1,""],bias:[34,4,1,""],derivative:[34,2,1,""],drift_rate:[34,4,1,""],name:[34,4,1,""],noise:[34,4,1,""],non_decision_time:[34,4,1,""],owner:[34,4,1,""],prefs:[34,4,1,""],shenhav_et_al_compat_mode:[34,3,1,""],starting_value:[34,4,1,""],threshold:[34,4,1,""],variable:[34,4,1,""]},"psyneulink.core.components.functions.distributionfunctions.ExponentialDist":{beta:[34,4,1,""],name:[
...

See CI logs for the full diff.

@@ -46,7 +46,7 @@
PREDICTION_ERROR_DELTA_FUNCTION, PRODUCT, REARRANGE_FUNCTION, REDUCE_FUNCTION, SCALE, SUM, WEIGHTS, \
PREFERENCE_SET_NAME
from psyneulink.core.globals.utilities import convert_to_np_array, is_numeric, np_array_less_than_2d, ValidParamSpecType
from psyneulink.core.globals.context import ContextFlags
from psyneulink.core.globals.context import ContextFlags, handle_external_context

Check notice

Code scanning / CodeQL

Cyclic import Note

Import of module
psyneulink.core.globals.context
begins an import cycle.
@coveralls
Copy link

coveralls commented Aug 4, 2023

Coverage Status

coverage: 84.53% (-0.007%) from 84.537% when pulling eb76cab on fix/composition_existing_projections into 9a9ef68 on devel.

@jdcpni jdcpni merged commit 3d1ec81 into devel Aug 4, 2023
59 checks passed
@jdcpni jdcpni deleted the fix/composition_existing_projections branch August 4, 2023 21:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants