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

Threshold condition #2305

Merged
merged 3 commits into from
Mar 8, 2022
Merged

Threshold condition #2305

merged 3 commits into from
Mar 8, 2022

Conversation

kmantel
Copy link
Collaborator

@kmantel kmantel commented Feb 4, 2022

No description provided.

@kmantel kmantel requested a review from jvesely February 4, 2022 06:37
@github-actions
Copy link

github-actions bot commented Feb 4, 2022

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

diff -r docs-base/Condition.html docs-head/Condition.html
1895a1896,1955
> <dl class="py class">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold">
> <em class="property"><span class="pre">class</span> </em><span class="sig-prename descclassname"><span class="pre">psyneulink.core.scheduling.condition.</span></span><span class="sig-name descname"><span class="pre">Threshold</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">dependency</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">parameter</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">threshold</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">comparator</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">indices</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">atol</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">0</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">rtol</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">0</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold" title="Permalink to this definition">¶</a></dt>
> <dd><dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.dependency">
> <span class="sig-name descname"><span class="pre">dependency</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.dependency" title="Permalink to this definition">¶</a></dt>
> <dd><p>the node on which the Condition depends</p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.parameter">
> <span class="sig-name descname"><span class="pre">parameter</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.parameter" title="Permalink to this definition">¶</a></dt>
> <dd><p>the name of the parameter of <strong>dependency</strong> whose value is
> to be compared to <strong>threshold</strong></p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.threshold">
> <span class="sig-name descname"><span class="pre">threshold</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.threshold" title="Permalink to this definition">¶</a></dt>
> <dd><p>the fixed value compared to the value of the <strong>parameter</strong></p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.comparator">
> <span class="sig-name descname"><span class="pre">comparator</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.comparator" title="Permalink to this definition">¶</a></dt>
> <dd><p>the string comparison operator determining the direction or
> type of comparison of the value of the <strong>parameter</strong>
> relative to <strong>threshold</strong></p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.indices">
> <span class="sig-name descname"><span class="pre">indices</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.indices" title="Permalink to this definition">¶</a></dt>
> <dd><p>if specified, a series of indices that reach the desired
> number given an iterable value for <strong>parameter</strong></p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.atol">
> <span class="sig-name descname"><span class="pre">atol</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.atol" title="Permalink to this definition">¶</a></dt>
> <dd><p>absolute tolerance for the comparison</p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.rtol">
> <span class="sig-name descname"><span class="pre">rtol</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.rtol" title="Permalink to this definition">¶</a></dt>
> <dd><p>relative tolerance (to <strong>threshold</strong>) for the comparison</p>
> </dd></dl>
> 
> <p>Satisfied when:</p>
> <blockquote>
> <div><p>The comparison between the value of the <strong>parameter</strong> and
> <strong>threshold</strong> using <strong>comparator</strong> is true</p>
> </div></blockquote>
> <p class="rubric">Notes</p>
> <p>The comparison must be done with single numbers. If the value of
> <strong>parameter</strong> contains more than one item, <strong>indices</strong> must be
> specified.</p>
> </dd></dl>
> 
diff -r docs-base/_downloads/08bdb54817a4817ad8e274272625aa24/Cohen_Huston1994_horse_race.py docs-head/_downloads/08bdb54817a4817ad8e274272625aa24/Cohen_Huston1994_horse_race.py
188,196d187
< # Create threshold function -------------------------------------------------------------------------------------------
< # context is automatically passed into Conditions, and references the execution context in which they are being run,
< # which in this case is simply the Bidirectional_Stroop system
< def pass_threshold(response_layer, thresh, context):
<     results1 = response_layer.get_output_values(context)[0][0] #red response
<     results2 = response_layer.get_output_values(context)[0][1] #green response
<     if results1  >= thresh or results2 >= thresh:
<         return True
<     return False
198,207c189,190
< # 2nd threshold function
< def pass_threshold2(response_layer, thresh, terminate, context):
<     results1 = response_layer.get_output_values(context)[0][0] #red response
<     results2 = response_layer.get_output_values(context)[0][1] #green response
<     length = response_layer.log.nparray_dictionary()[context.execution_id]['value'].shape[0]
<     if results1  >= thresh or results2 >= thresh:
<         return True
<     if length ==terminate:
<         return True
<     return False
---
> def terminate_num_executions(length, context):
>     return response_layer.log.nparray_dictionary()[context.execution_id]['value'].shape[0] == length
212c195,198
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold, response_layer, threshold)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>     )
215c201,205
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold2, response_layer, threshold, terminate2)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>         pnl.While(terminate_num_executions, terminate2),
>     )
218c208,212
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold2, response_layer, threshold, terminate3)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>         pnl.While(terminate_num_executions, terminate3),
>     )
221c215,219
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold2, response_layer, threshold, terminate4)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>         pnl.While(terminate_num_executions, terminate4),
>     )
224c222,226
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold2, response_layer, threshold, terminate5)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>         pnl.While(terminate_num_executions, terminate5),
>     )
diff -r docs-base/_downloads/0e250fd5f7fdb8f2faa472e6658bed55/Cohen_Huston1994.py docs-head/_downloads/0e250fd5f7fdb8f2faa472e6658bed55/Cohen_Huston1994.py
275,283d274
< 
< def pass_threshold(response_layer, thresh):
<     results1 = response_layer.get_output_values(Bidirectional_Stroop)[0][0]  # red response
<     results2 = response_layer.get_output_values(Bidirectional_Stroop)[0][1]  # green response
<     if results1 >= thresh or results2 >= thresh:
<         return True
<     return False
< 
< 
285c276,279
<     pnl.TimeScale.TRIAL: pnl.While(pass_threshold, response_layer, threshold)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>     )
diff -r docs-base/_downloads/11ac9c80f617b4258b7c7c95505a6a38/Kalanthroff_PCTC_2018.py docs-head/_downloads/11ac9c80f617b4258b7c7c95505a6a38/Kalanthroff_PCTC_2018.py
293,303c293
< # Create threshold function -------------------------------------------------------------------------------------------
< 
< def pass_threshold(response_layer, thresh, context):
<     results1 = response_layer.get_output_values(context)[0][0]  # red response
<     results2 = response_layer.get_output_values(context)[0][1]  # green response
<     # print(results1)
<     # print(results2)
<     if results1 >= thresh or results2 >= thresh:
<         return True
<     return False
< 
---
> # Create threshold condition -------------------------------------------------------------------------------------------
306c296,299
<     pnl.TimeScale.TRIAL: pnl.While(pass_threshold, response_layer, threshold)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer.output_ports['SPECIAL_LOGISTIC'], 'value', threshold, '>=', 0),
>         pnl.Threshold(response_layer.output_ports['SPECIAL_LOGISTIC'], 'value', threshold, '>=', 1),
>     )
diff -r docs-base/genindex.html docs-head/genindex.html
1253,1254d1252
<   </ul></td>
<   <td style="width: 33%; vertical-align: top;"><ul>
1256a1255,1256
>   </ul></td>
>   <td style="width: 33%; vertical-align: top;"><ul>
1352a1353,1354
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.atol">atol (psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
1516a1519,1520
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.comparator">comparator (psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
1802a1807,1808
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.dependency">dependency (psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
2385a2392,2394
> 
>       <ul>
>         <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.indices">(psyneulink.core.scheduling.condition.Threshold attribute)</a>
2386a2396
>       </ul></li>
3793a3804,3805
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.parameter">parameter (psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
4806,4807d4817
<   </ul></td>
<   <td style="width: 33%; vertical-align: top;"><ul>
4809a4820,4821
>   </ul></td>
>   <td style="width: 33%; vertical-align: top;"><ul>
4923a4936,4937
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.rtol">rtol (psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
5311a5326,5327
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold">Threshold (class in psyneulink.core.scheduling.condition)</a>
> </li>
5318a5335,5336
>         <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.threshold">(psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
5324,5325d5341
<       <li><a href="IntegratorFunctions.html#psyneulink.core.components.functions.stateful.integratorfunctions.FitzHughNagumoIntegrator.time_constant_v">time_constant_v (psyneulink.core.components.functions.stateful.integratorfunctions.FitzHughNagumoIntegrator attribute)</a>
< </li>
5327a5344,5345
>       <li><a href="IntegratorFunctions.html#psyneulink.core.components.functions.stateful.integratorfunctions.FitzHughNagumoIntegrator.time_constant_v">time_constant_v (psyneulink.core.components.functions.stateful.integratorfunctions.FitzHughNagumoIntegrator attribute)</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","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","EVC","EVCAuxiliary","EVCControlMechanism","EpisodicMemoryMechanism","Function","Functions","GatingMechanism","GatingMechanisms","GatingProjection","GatingProjections","GatingSignal","GilzenratModel","InputPort","IntegratorFunctions","IntegratorMechanism","IntegratorMechanisms","KWTAMechanism","Keywords","KohonenMechanism","LCAMechanism","LCControlMechanism","LCMechanism","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","json"],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","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","EVC.rst","EVCAuxiliary.rst","EVCControlMechanism.rst","EpisodicMemoryMechanism.rst","Function.rst","Functions.rst","GatingMechanism.rst","GatingMechanisms.r
...

See CI logs for the full diff.

Copy link
Collaborator

@jvesely jvesely left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than the specific comments in the code, I have two high-level concerns.
1.) The attempt to handle int vs float values is incomplete. The only state params of int type should be execution counters, so we can just merge all special cases into one:
indices == TimeScale => value has is of type int => tolerance == 0.

2.) I'm don't quite like the custom handling of absolute and relative tolerance. The comparator logic would IMO be eaiser to explain if it used numpy's is_close.

==  -- is_close
!=  --  not is_close
>=  -- '>' or is_close
>  -- '>' and not is_close
<= -- '<' or is_close
< -- '<' and not is_close

This should also help with weird corner cases like:
val == threshold-epsilon # epsilon < tolerance

under the current semantics val > threshold returns true (i.e. threshold - epsilon > threshold - tolerance) which is confusing.
The above semantics with 'is_close' would return false.
You can construct a reverse example (val == threshold + epsilon) to point to a disrepance there, but I think it's easier to explain that values within tolerance are considered equal and the user should use '>=' in that case.
The main benefit of implementing semantics based on is_close is that it maintains traditional comparison invariants (e.g a > b => a != b) which is not true in the current version.

psyneulink/core/llvm/helpers.py Outdated Show resolved Hide resolved
psyneulink/core/llvm/helpers.py Outdated Show resolved Hide resolved
psyneulink/core/llvm/helpers.py Outdated Show resolved Hide resolved
param_ptr,
[self.ctx.int32_ty(x) for x in ([0] + list(indices))]
)
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The above can be drastically shortened by reducing it to preprocessing indices,
The load statement would be more readable if it were reused and split into two expressions.

comparator = condition.comparator
indices = condition.indices

tolerance_value = condition.rtol * abs(threshold) + condition.atol
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'd be easier to use numpy is_close, rather than reimplementing own version of relative and absolute threshold. there are compiler helpers with the same behaviour as well (see helpers.is_close)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could replace some of the checks. I think a manual value would still need to be used for the strict inequalities, though I'm not really sure how much a tolerance even makes sense for those.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed, I think the semantics need a bit of discussion.
using is_close in all of them made sense to me because it preserves the expected comparison invariants,
but at the same time breaking 'x + epsilon > x' is not very intuitive either.
I'm not sure what the user expectations are here, and how much we can restrict them.
Allowing only shape inequalities can be one way out, users can always combine scheduling decisions themselves.

psyneulink/core/scheduling/condition.py Show resolved Hide resolved
psyneulink/core/llvm/helpers.py Outdated Show resolved Hide resolved
psyneulink/core/llvm/helpers.py Outdated Show resolved Hide resolved
return cmp_method(comparator, val, threshold)
else:
abs_method = self.ctx.get_builtin(abs_method_name, [val.type])
val_thresh_diff = builder.call(abs_method, [builder.fsub(val, threshold)])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this unravels the attempt to have general handling of ints vs floats. The abs method might be general, but you're using fsub which will fail for integers anyway.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, is it better to handle int/float separately instead of just converting int to float? If any/all of the comparisons are to be done with helpers.is_close, I think that just takes floats.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking about it too. with the current default of fp64 it should be ok (all int32 values can be represented in fp64).
Switching to fp32 will introduce problems for values above 16.7M, which might be too low for lifetime execution count.
I think it'd make sense to special case execution counts as the only integer codepath and maybe restrict allowed tolerances (e.g. only integer absolute tolerance?)
similarly to above, I don't have a good idea about what the users would expect here.
Conversion to fp64 and using is_close should be safe, for all situations, but might be unnecessary.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with writing a special case for execution count if it's faster or otherwise better, but for now I've just converted

@kmantel kmantel force-pushed the threshold branch 2 times, most recently from 96b06cf to fd6af0f Compare February 22, 2022 03:21
@github-actions
Copy link

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

diff -r docs-base/Condition.html docs-head/Condition.html
1895a1896,1955
> <dl class="py class">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold">
> <em class="property"><span class="pre">class</span> </em><span class="sig-prename descclassname"><span class="pre">psyneulink.core.scheduling.condition.</span></span><span class="sig-name descname"><span class="pre">Threshold</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">dependency</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">parameter</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">threshold</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">comparator</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">indices</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">atol</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">0</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">rtol</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">0</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold" title="Permalink to this definition">¶</a></dt>
> <dd><dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.dependency">
> <span class="sig-name descname"><span class="pre">dependency</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.dependency" title="Permalink to this definition">¶</a></dt>
> <dd><p>the node on which the Condition depends</p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.parameter">
> <span class="sig-name descname"><span class="pre">parameter</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.parameter" title="Permalink to this definition">¶</a></dt>
> <dd><p>the name of the parameter of <strong>dependency</strong> whose value is
> to be compared to <strong>threshold</strong></p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.threshold">
> <span class="sig-name descname"><span class="pre">threshold</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.threshold" title="Permalink to this definition">¶</a></dt>
> <dd><p>the fixed value compared to the value of the <strong>parameter</strong></p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.comparator">
> <span class="sig-name descname"><span class="pre">comparator</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.comparator" title="Permalink to this definition">¶</a></dt>
> <dd><p>the string comparison operator determining the direction or
> type of comparison of the value of the <strong>parameter</strong>
> relative to <strong>threshold</strong></p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.indices">
> <span class="sig-name descname"><span class="pre">indices</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.indices" title="Permalink to this definition">¶</a></dt>
> <dd><p>if specified, a series of indices that reach the desired
> number given an iterable value for <strong>parameter</strong></p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.atol">
> <span class="sig-name descname"><span class="pre">atol</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.atol" title="Permalink to this definition">¶</a></dt>
> <dd><p>absolute tolerance for the comparison</p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.rtol">
> <span class="sig-name descname"><span class="pre">rtol</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.rtol" title="Permalink to this definition">¶</a></dt>
> <dd><p>relative tolerance (to <strong>threshold</strong>) for the comparison</p>
> </dd></dl>
> 
> <p>Satisfied when:</p>
> <blockquote>
> <div><p>The comparison between the value of the <strong>parameter</strong> and
> <strong>threshold</strong> using <strong>comparator</strong> is true</p>
> </div></blockquote>
> <p class="rubric">Notes</p>
> <p>The comparison must be done with single numbers. If the value of
> <strong>parameter</strong> contains more than one item, <strong>indices</strong> must be
> specified.</p>
> </dd></dl>
> 
diff -r docs-base/_downloads/08bdb54817a4817ad8e274272625aa24/Cohen_Huston1994_horse_race.py docs-head/_downloads/08bdb54817a4817ad8e274272625aa24/Cohen_Huston1994_horse_race.py
188,196d187
< # Create threshold function -------------------------------------------------------------------------------------------
< # context is automatically passed into Conditions, and references the execution context in which they are being run,
< # which in this case is simply the Bidirectional_Stroop system
< def pass_threshold(response_layer, thresh, context):
<     results1 = response_layer.get_output_values(context)[0][0] #red response
<     results2 = response_layer.get_output_values(context)[0][1] #green response
<     if results1  >= thresh or results2 >= thresh:
<         return True
<     return False
198,207c189,190
< # 2nd threshold function
< def pass_threshold2(response_layer, thresh, terminate, context):
<     results1 = response_layer.get_output_values(context)[0][0] #red response
<     results2 = response_layer.get_output_values(context)[0][1] #green response
<     length = response_layer.log.nparray_dictionary()[context.execution_id]['value'].shape[0]
<     if results1  >= thresh or results2 >= thresh:
<         return True
<     if length ==terminate:
<         return True
<     return False
---
> def terminate_num_executions(length, context):
>     return response_layer.log.nparray_dictionary()[context.execution_id]['value'].shape[0] == length
212c195,198
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold, response_layer, threshold)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>     )
215c201,205
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold2, response_layer, threshold, terminate2)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>         pnl.While(terminate_num_executions, terminate2),
>     )
218c208,212
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold2, response_layer, threshold, terminate3)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>         pnl.While(terminate_num_executions, terminate3),
>     )
221c215,219
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold2, response_layer, threshold, terminate4)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>         pnl.While(terminate_num_executions, terminate4),
>     )
224c222,226
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold2, response_layer, threshold, terminate5)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>         pnl.While(terminate_num_executions, terminate5),
>     )
diff -r docs-base/_downloads/0e250fd5f7fdb8f2faa472e6658bed55/Cohen_Huston1994.py docs-head/_downloads/0e250fd5f7fdb8f2faa472e6658bed55/Cohen_Huston1994.py
275,283d274
< 
< def pass_threshold(response_layer, thresh):
<     results1 = response_layer.get_output_values(Bidirectional_Stroop)[0][0]  # red response
<     results2 = response_layer.get_output_values(Bidirectional_Stroop)[0][1]  # green response
<     if results1 >= thresh or results2 >= thresh:
<         return True
<     return False
< 
< 
285c276,279
<     pnl.TimeScale.TRIAL: pnl.While(pass_threshold, response_layer, threshold)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>     )
diff -r docs-base/_downloads/11ac9c80f617b4258b7c7c95505a6a38/Kalanthroff_PCTC_2018.py docs-head/_downloads/11ac9c80f617b4258b7c7c95505a6a38/Kalanthroff_PCTC_2018.py
293,303c293
< # Create threshold function -------------------------------------------------------------------------------------------
< 
< def pass_threshold(response_layer, thresh, context):
<     results1 = response_layer.get_output_values(context)[0][0]  # red response
<     results2 = response_layer.get_output_values(context)[0][1]  # green response
<     # print(results1)
<     # print(results2)
<     if results1 >= thresh or results2 >= thresh:
<         return True
<     return False
< 
---
> # Create threshold condition -------------------------------------------------------------------------------------------
306c296,299
<     pnl.TimeScale.TRIAL: pnl.While(pass_threshold, response_layer, threshold)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer.output_ports['SPECIAL_LOGISTIC'], 'value', threshold, '>=', 0),
>         pnl.Threshold(response_layer.output_ports['SPECIAL_LOGISTIC'], 'value', threshold, '>=', 1),
>     )
diff -r docs-base/genindex.html docs-head/genindex.html
1261,1262d1260
<   </ul></td>
<   <td style="width: 33%; vertical-align: top;"><ul>
1264a1263,1264
>   </ul></td>
>   <td style="width: 33%; vertical-align: top;"><ul>
1360a1361,1362
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.atol">atol (psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
1524a1527,1528
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.comparator">comparator (psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
1813c1817
<       <li><a href="Composition.html#psyneulink.core.compositions.composition.Graph.dependency_dict">dependency_dict (psyneulink.core.compositions.composition.Graph attribute)</a>
---
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.dependency">dependency (psyneulink.core.scheduling.condition.Threshold attribute)</a>
1816a1821,1822
>       <li><a href="Composition.html#psyneulink.core.compositions.composition.Graph.dependency_dict">dependency_dict (psyneulink.core.compositions.composition.Graph attribute)</a>
> </li>
2411a2418,2420
> 
>       <ul>
>         <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.indices">(psyneulink.core.scheduling.condition.Threshold attribute)</a>
2412a2422
>       </ul></li>
3819a3830,3831
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.parameter">parameter (psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
4832,4833d4843
<   </ul></td>
<   <td style="width: 33%; vertical-align: top;"><ul>
4835a4846,4847
>   </ul></td>
>   <td style="width: 33%; vertical-align: top;"><ul>
4949a4962,4963
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.rtol">rtol (psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
5337a5352,5353
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold">Threshold (class in psyneulink.core.scheduling.condition)</a>
> </li>
5344a5361,5362
>         <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.threshold">(psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
5350,5351d5367
<       <li><a href="IntegratorFunctions.html#psyneulink.core.components.functions.stateful.integratorfunctions.FitzHughNagumoIntegrator.time_constant_v">time_constant_v (psyneulink.core.components.functions.stateful.integratorfunctions.FitzHughNagumoIntegrator attribute)</a>
< </li>
5353a5370,5371
>       <li><a href="IntegratorFunctions.html#psyneulink.core.components.functions.stateful.integratorfunctions.FitzHughNagumoIntegrator.time_constant_v">time_constant_v (psyneulink.core.components.functions.stateful.integratorfunctions.FitzHughNagumoIntegrator attribute)</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","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","EVC","EVCAuxiliary","EVCControlMechanism","EpisodicMemoryMechanism","Function","Functions","GatingMechanism","GatingMechanisms","GatingProjection","GatingProjections","GatingSignal","GilzenratModel","InputPort","IntegratorFunctions","IntegratorMechanism","IntegratorMechanisms","KWTAMechanism","Keywords","KohonenMechanism","LCAMechanism","LCControlMechanism","LCMechanism","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","json"],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","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",
...

See CI logs for the full diff.

1 similar comment
@github-actions
Copy link

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

diff -r docs-base/Condition.html docs-head/Condition.html
1895a1896,1955
> <dl class="py class">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold">
> <em class="property"><span class="pre">class</span> </em><span class="sig-prename descclassname"><span class="pre">psyneulink.core.scheduling.condition.</span></span><span class="sig-name descname"><span class="pre">Threshold</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">dependency</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">parameter</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">threshold</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">comparator</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">indices</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">atol</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">0</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">rtol</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">0</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold" title="Permalink to this definition">¶</a></dt>
> <dd><dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.dependency">
> <span class="sig-name descname"><span class="pre">dependency</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.dependency" title="Permalink to this definition">¶</a></dt>
> <dd><p>the node on which the Condition depends</p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.parameter">
> <span class="sig-name descname"><span class="pre">parameter</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.parameter" title="Permalink to this definition">¶</a></dt>
> <dd><p>the name of the parameter of <strong>dependency</strong> whose value is
> to be compared to <strong>threshold</strong></p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.threshold">
> <span class="sig-name descname"><span class="pre">threshold</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.threshold" title="Permalink to this definition">¶</a></dt>
> <dd><p>the fixed value compared to the value of the <strong>parameter</strong></p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.comparator">
> <span class="sig-name descname"><span class="pre">comparator</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.comparator" title="Permalink to this definition">¶</a></dt>
> <dd><p>the string comparison operator determining the direction or
> type of comparison of the value of the <strong>parameter</strong>
> relative to <strong>threshold</strong></p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.indices">
> <span class="sig-name descname"><span class="pre">indices</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.indices" title="Permalink to this definition">¶</a></dt>
> <dd><p>if specified, a series of indices that reach the desired
> number given an iterable value for <strong>parameter</strong></p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.atol">
> <span class="sig-name descname"><span class="pre">atol</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.atol" title="Permalink to this definition">¶</a></dt>
> <dd><p>absolute tolerance for the comparison</p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.rtol">
> <span class="sig-name descname"><span class="pre">rtol</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.rtol" title="Permalink to this definition">¶</a></dt>
> <dd><p>relative tolerance (to <strong>threshold</strong>) for the comparison</p>
> </dd></dl>
> 
> <p>Satisfied when:</p>
> <blockquote>
> <div><p>The comparison between the value of the <strong>parameter</strong> and
> <strong>threshold</strong> using <strong>comparator</strong> is true</p>
> </div></blockquote>
> <p class="rubric">Notes</p>
> <p>The comparison must be done with single numbers. If the value of
> <strong>parameter</strong> contains more than one item, <strong>indices</strong> must be
> specified.</p>
> </dd></dl>
> 
diff -r docs-base/_downloads/08bdb54817a4817ad8e274272625aa24/Cohen_Huston1994_horse_race.py docs-head/_downloads/08bdb54817a4817ad8e274272625aa24/Cohen_Huston1994_horse_race.py
188,196d187
< # Create threshold function -------------------------------------------------------------------------------------------
< # context is automatically passed into Conditions, and references the execution context in which they are being run,
< # which in this case is simply the Bidirectional_Stroop system
< def pass_threshold(response_layer, thresh, context):
<     results1 = response_layer.get_output_values(context)[0][0] #red response
<     results2 = response_layer.get_output_values(context)[0][1] #green response
<     if results1  >= thresh or results2 >= thresh:
<         return True
<     return False
198,207c189,190
< # 2nd threshold function
< def pass_threshold2(response_layer, thresh, terminate, context):
<     results1 = response_layer.get_output_values(context)[0][0] #red response
<     results2 = response_layer.get_output_values(context)[0][1] #green response
<     length = response_layer.log.nparray_dictionary()[context.execution_id]['value'].shape[0]
<     if results1  >= thresh or results2 >= thresh:
<         return True
<     if length ==terminate:
<         return True
<     return False
---
> def terminate_num_executions(length, context):
>     return response_layer.log.nparray_dictionary()[context.execution_id]['value'].shape[0] == length
212c195,198
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold, response_layer, threshold)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>     )
215c201,205
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold2, response_layer, threshold, terminate2)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>         pnl.While(terminate_num_executions, terminate2),
>     )
218c208,212
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold2, response_layer, threshold, terminate3)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>         pnl.While(terminate_num_executions, terminate3),
>     )
221c215,219
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold2, response_layer, threshold, terminate4)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>         pnl.While(terminate_num_executions, terminate4),
>     )
224c222,226
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold2, response_layer, threshold, terminate5)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>         pnl.While(terminate_num_executions, terminate5),
>     )
diff -r docs-base/_downloads/0e250fd5f7fdb8f2faa472e6658bed55/Cohen_Huston1994.py docs-head/_downloads/0e250fd5f7fdb8f2faa472e6658bed55/Cohen_Huston1994.py
275,283d274
< 
< def pass_threshold(response_layer, thresh):
<     results1 = response_layer.get_output_values(Bidirectional_Stroop)[0][0]  # red response
<     results2 = response_layer.get_output_values(Bidirectional_Stroop)[0][1]  # green response
<     if results1 >= thresh or results2 >= thresh:
<         return True
<     return False
< 
< 
285c276,279
<     pnl.TimeScale.TRIAL: pnl.While(pass_threshold, response_layer, threshold)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>     )
diff -r docs-base/_downloads/11ac9c80f617b4258b7c7c95505a6a38/Kalanthroff_PCTC_2018.py docs-head/_downloads/11ac9c80f617b4258b7c7c95505a6a38/Kalanthroff_PCTC_2018.py
293,303c293
< # Create threshold function -------------------------------------------------------------------------------------------
< 
< def pass_threshold(response_layer, thresh, context):
<     results1 = response_layer.get_output_values(context)[0][0]  # red response
<     results2 = response_layer.get_output_values(context)[0][1]  # green response
<     # print(results1)
<     # print(results2)
<     if results1 >= thresh or results2 >= thresh:
<         return True
<     return False
< 
---
> # Create threshold condition -------------------------------------------------------------------------------------------
306c296,299
<     pnl.TimeScale.TRIAL: pnl.While(pass_threshold, response_layer, threshold)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer.output_ports['SPECIAL_LOGISTIC'], 'value', threshold, '>=', 0),
>         pnl.Threshold(response_layer.output_ports['SPECIAL_LOGISTIC'], 'value', threshold, '>=', 1),
>     )
diff -r docs-base/genindex.html docs-head/genindex.html
1261,1262d1260
<   </ul></td>
<   <td style="width: 33%; vertical-align: top;"><ul>
1264a1263,1264
>   </ul></td>
>   <td style="width: 33%; vertical-align: top;"><ul>
1360a1361,1362
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.atol">atol (psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
1524a1527,1528
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.comparator">comparator (psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
1813c1817
<       <li><a href="Composition.html#psyneulink.core.compositions.composition.Graph.dependency_dict">dependency_dict (psyneulink.core.compositions.composition.Graph attribute)</a>
---
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.dependency">dependency (psyneulink.core.scheduling.condition.Threshold attribute)</a>
1816a1821,1822
>       <li><a href="Composition.html#psyneulink.core.compositions.composition.Graph.dependency_dict">dependency_dict (psyneulink.core.compositions.composition.Graph attribute)</a>
> </li>
2411a2418,2420
> 
>       <ul>
>         <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.indices">(psyneulink.core.scheduling.condition.Threshold attribute)</a>
2412a2422
>       </ul></li>
3819a3830,3831
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.parameter">parameter (psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
4832,4833d4843
<   </ul></td>
<   <td style="width: 33%; vertical-align: top;"><ul>
4835a4846,4847
>   </ul></td>
>   <td style="width: 33%; vertical-align: top;"><ul>
4949a4962,4963
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.rtol">rtol (psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
5337a5352,5353
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold">Threshold (class in psyneulink.core.scheduling.condition)</a>
> </li>
5344a5361,5362
>         <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.threshold">(psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
5350,5351d5367
<       <li><a href="IntegratorFunctions.html#psyneulink.core.components.functions.stateful.integratorfunctions.FitzHughNagumoIntegrator.time_constant_v">time_constant_v (psyneulink.core.components.functions.stateful.integratorfunctions.FitzHughNagumoIntegrator attribute)</a>
< </li>
5353a5370,5371
>       <li><a href="IntegratorFunctions.html#psyneulink.core.components.functions.stateful.integratorfunctions.FitzHughNagumoIntegrator.time_constant_v">time_constant_v (psyneulink.core.components.functions.stateful.integratorfunctions.FitzHughNagumoIntegrator attribute)</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","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","EVC","EVCAuxiliary","EVCControlMechanism","EpisodicMemoryMechanism","Function","Functions","GatingMechanism","GatingMechanisms","GatingProjection","GatingProjections","GatingSignal","GilzenratModel","InputPort","IntegratorFunctions","IntegratorMechanism","IntegratorMechanisms","KWTAMechanism","Keywords","KohonenMechanism","LCAMechanism","LCControlMechanism","LCMechanism","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","json"],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","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",
...

See CI logs for the full diff.

@github-actions
Copy link

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

diff -r docs-base/Condition.html docs-head/Condition.html
1895a1896,1955
> <dl class="py class">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold">
> <em class="property"><span class="pre">class</span> </em><span class="sig-prename descclassname"><span class="pre">psyneulink.core.scheduling.condition.</span></span><span class="sig-name descname"><span class="pre">Threshold</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">dependency</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">parameter</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">threshold</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">comparator</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">indices</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">atol</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">0</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">rtol</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">0</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold" title="Permalink to this definition">¶</a></dt>
> <dd><dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.dependency">
> <span class="sig-name descname"><span class="pre">dependency</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.dependency" title="Permalink to this definition">¶</a></dt>
> <dd><p>the node on which the Condition depends</p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.parameter">
> <span class="sig-name descname"><span class="pre">parameter</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.parameter" title="Permalink to this definition">¶</a></dt>
> <dd><p>the name of the parameter of <strong>dependency</strong> whose value is
> to be compared to <strong>threshold</strong></p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.threshold">
> <span class="sig-name descname"><span class="pre">threshold</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.threshold" title="Permalink to this definition">¶</a></dt>
> <dd><p>the fixed value compared to the value of the <strong>parameter</strong></p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.comparator">
> <span class="sig-name descname"><span class="pre">comparator</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.comparator" title="Permalink to this definition">¶</a></dt>
> <dd><p>the string comparison operator determining the direction or
> type of comparison of the value of the <strong>parameter</strong>
> relative to <strong>threshold</strong></p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.indices">
> <span class="sig-name descname"><span class="pre">indices</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.indices" title="Permalink to this definition">¶</a></dt>
> <dd><p>if specified, a series of indices that reach the desired
> number given an iterable value for <strong>parameter</strong></p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.atol">
> <span class="sig-name descname"><span class="pre">atol</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.atol" title="Permalink to this definition">¶</a></dt>
> <dd><p>absolute tolerance for the comparison</p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.rtol">
> <span class="sig-name descname"><span class="pre">rtol</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.rtol" title="Permalink to this definition">¶</a></dt>
> <dd><p>relative tolerance (to <strong>threshold</strong>) for the comparison</p>
> </dd></dl>
> 
> <p>Satisfied when:</p>
> <blockquote>
> <div><p>The comparison between the value of the <strong>parameter</strong> and
> <strong>threshold</strong> using <strong>comparator</strong> is true</p>
> </div></blockquote>
> <p class="rubric">Notes</p>
> <p>The comparison must be done with single numbers. If the value of
> <strong>parameter</strong> contains more than one item, <strong>indices</strong> must be
> specified.</p>
> </dd></dl>
> 
diff -r docs-base/_downloads/08bdb54817a4817ad8e274272625aa24/Cohen_Huston1994_horse_race.py docs-head/_downloads/08bdb54817a4817ad8e274272625aa24/Cohen_Huston1994_horse_race.py
188,196d187
< # Create threshold function -------------------------------------------------------------------------------------------
< # context is automatically passed into Conditions, and references the execution context in which they are being run,
< # which in this case is simply the Bidirectional_Stroop system
< def pass_threshold(response_layer, thresh, context):
<     results1 = response_layer.get_output_values(context)[0][0] #red response
<     results2 = response_layer.get_output_values(context)[0][1] #green response
<     if results1  >= thresh or results2 >= thresh:
<         return True
<     return False
198,207c189,190
< # 2nd threshold function
< def pass_threshold2(response_layer, thresh, terminate, context):
<     results1 = response_layer.get_output_values(context)[0][0] #red response
<     results2 = response_layer.get_output_values(context)[0][1] #green response
<     length = response_layer.log.nparray_dictionary()[context.execution_id]['value'].shape[0]
<     if results1  >= thresh or results2 >= thresh:
<         return True
<     if length ==terminate:
<         return True
<     return False
---
> def terminate_num_executions(length, context):
>     return response_layer.log.nparray_dictionary()[context.execution_id]['value'].shape[0] == length
212c195,198
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold, response_layer, threshold)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>     )
215c201,205
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold2, response_layer, threshold, terminate2)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>         pnl.While(terminate_num_executions, terminate2),
>     )
218c208,212
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold2, response_layer, threshold, terminate3)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>         pnl.While(terminate_num_executions, terminate3),
>     )
221c215,219
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold2, response_layer, threshold, terminate4)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>         pnl.While(terminate_num_executions, terminate4),
>     )
224c222,226
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold2, response_layer, threshold, terminate5)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>         pnl.While(terminate_num_executions, terminate5),
>     )
diff -r docs-base/_downloads/0e250fd5f7fdb8f2faa472e6658bed55/Cohen_Huston1994.py docs-head/_downloads/0e250fd5f7fdb8f2faa472e6658bed55/Cohen_Huston1994.py
275,283d274
< 
< def pass_threshold(response_layer, thresh):
<     results1 = response_layer.get_output_values(Bidirectional_Stroop)[0][0]  # red response
<     results2 = response_layer.get_output_values(Bidirectional_Stroop)[0][1]  # green response
<     if results1 >= thresh or results2 >= thresh:
<         return True
<     return False
< 
< 
285c276,279
<     pnl.TimeScale.TRIAL: pnl.While(pass_threshold, response_layer, threshold)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>     )
diff -r docs-base/_downloads/11ac9c80f617b4258b7c7c95505a6a38/Kalanthroff_PCTC_2018.py docs-head/_downloads/11ac9c80f617b4258b7c7c95505a6a38/Kalanthroff_PCTC_2018.py
293,303c293
< # Create threshold function -------------------------------------------------------------------------------------------
< 
< def pass_threshold(response_layer, thresh, context):
<     results1 = response_layer.get_output_values(context)[0][0]  # red response
<     results2 = response_layer.get_output_values(context)[0][1]  # green response
<     # print(results1)
<     # print(results2)
<     if results1 >= thresh or results2 >= thresh:
<         return True
<     return False
< 
---
> # Create threshold condition -------------------------------------------------------------------------------------------
306c296,299
<     pnl.TimeScale.TRIAL: pnl.While(pass_threshold, response_layer, threshold)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer.output_ports['SPECIAL_LOGISTIC'], 'value', threshold, '>=', 0),
>         pnl.Threshold(response_layer.output_ports['SPECIAL_LOGISTIC'], 'value', threshold, '>=', 1),
>     )
diff -r docs-base/genindex.html docs-head/genindex.html
1261,1262d1260
<   </ul></td>
<   <td style="width: 33%; vertical-align: top;"><ul>
1264a1263,1264
>   </ul></td>
>   <td style="width: 33%; vertical-align: top;"><ul>
1360a1361,1362
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.atol">atol (psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
1524a1527,1528
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.comparator">comparator (psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
1813c1817
<       <li><a href="Composition.html#psyneulink.core.compositions.composition.Graph.dependency_dict">dependency_dict (psyneulink.core.compositions.composition.Graph attribute)</a>
---
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.dependency">dependency (psyneulink.core.scheduling.condition.Threshold attribute)</a>
1816a1821,1822
>       <li><a href="Composition.html#psyneulink.core.compositions.composition.Graph.dependency_dict">dependency_dict (psyneulink.core.compositions.composition.Graph attribute)</a>
> </li>
2411a2418,2420
> 
>       <ul>
>         <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.indices">(psyneulink.core.scheduling.condition.Threshold attribute)</a>
2412a2422
>       </ul></li>
3819a3830,3831
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.parameter">parameter (psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
4832,4833d4843
<   </ul></td>
<   <td style="width: 33%; vertical-align: top;"><ul>
4835a4846,4847
>   </ul></td>
>   <td style="width: 33%; vertical-align: top;"><ul>
4949a4962,4963
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.rtol">rtol (psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
5337a5352,5353
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold">Threshold (class in psyneulink.core.scheduling.condition)</a>
> </li>
5344a5361,5362
>         <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.threshold">(psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
5350,5351d5367
<       <li><a href="IntegratorFunctions.html#psyneulink.core.components.functions.stateful.integratorfunctions.FitzHughNagumoIntegrator.time_constant_v">time_constant_v (psyneulink.core.components.functions.stateful.integratorfunctions.FitzHughNagumoIntegrator attribute)</a>
< </li>
5353a5370,5371
>       <li><a href="IntegratorFunctions.html#psyneulink.core.components.functions.stateful.integratorfunctions.FitzHughNagumoIntegrator.time_constant_v">time_constant_v (psyneulink.core.components.functions.stateful.integratorfunctions.FitzHughNagumoIntegrator attribute)</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","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","EVC","EVCAuxiliary","EVCControlMechanism","EpisodicMemoryMechanism","Function","Functions","GatingMechanism","GatingMechanisms","GatingProjection","GatingProjections","GatingSignal","GilzenratModel","InputPort","IntegratorFunctions","IntegratorMechanism","IntegratorMechanisms","KWTAMechanism","Keywords","KohonenMechanism","LCAMechanism","LCControlMechanism","LCMechanism","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","json"],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","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",
...

See CI logs for the full diff.

Copy link
Collaborator

@jvesely jvesely left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, other than a few nits about comments.

psyneulink/core/scheduling/condition.py Outdated Show resolved Hide resolved
psyneulink/core/scheduling/condition.py Outdated Show resolved Hide resolved
psyneulink/core/llvm/helpers.py Show resolved Hide resolved
@jvesely jvesely linked an issue Mar 1, 2022 that may be closed by this pull request
35 tasks
@github-actions
Copy link

github-actions bot commented Mar 5, 2022

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

diff -r docs-base/Condition.html docs-head/Condition.html
1895a1896,1957
> <dl class="py class">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold">
> <em class="property"><span class="pre">class</span> </em><span class="sig-prename descclassname"><span class="pre">psyneulink.core.scheduling.condition.</span></span><span class="sig-name descname"><span class="pre">Threshold</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">dependency</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">parameter</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">threshold</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">comparator</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">indices</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">atol</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">0</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">rtol</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">0</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold" title="Permalink to this definition">¶</a></dt>
> <dd><dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.dependency">
> <span class="sig-name descname"><span class="pre">dependency</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.dependency" title="Permalink to this definition">¶</a></dt>
> <dd><p>the node on which the Condition depends</p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.parameter">
> <span class="sig-name descname"><span class="pre">parameter</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.parameter" title="Permalink to this definition">¶</a></dt>
> <dd><p>the name of the parameter of <strong>dependency</strong> whose value is
> to be compared to <strong>threshold</strong></p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.threshold">
> <span class="sig-name descname"><span class="pre">threshold</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.threshold" title="Permalink to this definition">¶</a></dt>
> <dd><p>the fixed value compared to the value of the <strong>parameter</strong></p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.comparator">
> <span class="sig-name descname"><span class="pre">comparator</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.comparator" title="Permalink to this definition">¶</a></dt>
> <dd><p>the string comparison operator determining the direction or
> type of comparison of the value of the <strong>parameter</strong>
> relative to <strong>threshold</strong></p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.indices">
> <span class="sig-name descname"><span class="pre">indices</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.indices" title="Permalink to this definition">¶</a></dt>
> <dd><p>if specified, a series of indices that reach the desired
> number given an iterable value for <strong>parameter</strong></p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.atol">
> <span class="sig-name descname"><span class="pre">atol</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.atol" title="Permalink to this definition">¶</a></dt>
> <dd><p>absolute tolerance for the comparison</p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.rtol">
> <span class="sig-name descname"><span class="pre">rtol</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.rtol" title="Permalink to this definition">¶</a></dt>
> <dd><p>relative tolerance (to <strong>threshold</strong>) for the comparison</p>
> </dd></dl>
> 
> <p>Satisfied when:</p>
> <blockquote>
> <div><p>The comparison between the value of the <strong>parameter</strong> and
> <strong>threshold</strong> using <strong>comparator</strong> is true. If <strong>comparator</strong> is
> an equality (==, !=), the comparison will be considered equal
> within tolerances <strong>atol</strong> and <strong>rtol</strong>.</p>
> </div></blockquote>
> <p class="rubric">Notes</p>
> <p>The comparison must be done with scalars. If the value of
> <strong>parameter</strong> contains more than one item, <strong>indices</strong> must be
> specified.</p>
> </dd></dl>
> 
diff -r docs-base/_downloads/08bdb54817a4817ad8e274272625aa24/Cohen_Huston1994_horse_race.py docs-head/_downloads/08bdb54817a4817ad8e274272625aa24/Cohen_Huston1994_horse_race.py
188,196d187
< # Create threshold function -------------------------------------------------------------------------------------------
< # context is automatically passed into Conditions, and references the execution context in which they are being run,
< # which in this case is simply the Bidirectional_Stroop system
< def pass_threshold(response_layer, thresh, context):
<     results1 = response_layer.get_output_values(context)[0][0] #red response
<     results2 = response_layer.get_output_values(context)[0][1] #green response
<     if results1  >= thresh or results2 >= thresh:
<         return True
<     return False
198,207c189,190
< # 2nd threshold function
< def pass_threshold2(response_layer, thresh, terminate, context):
<     results1 = response_layer.get_output_values(context)[0][0] #red response
<     results2 = response_layer.get_output_values(context)[0][1] #green response
<     length = response_layer.log.nparray_dictionary()[context.execution_id]['value'].shape[0]
<     if results1  >= thresh or results2 >= thresh:
<         return True
<     if length ==terminate:
<         return True
<     return False
---
> def terminate_num_executions(length, context):
>     return response_layer.log.nparray_dictionary()[context.execution_id]['value'].shape[0] == length
212c195,198
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold, response_layer, threshold)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>     )
215c201,205
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold2, response_layer, threshold, terminate2)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>         pnl.While(terminate_num_executions, terminate2),
>     )
218c208,212
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold2, response_layer, threshold, terminate3)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>         pnl.While(terminate_num_executions, terminate3),
>     )
221c215,219
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold2, response_layer, threshold, terminate4)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>         pnl.While(terminate_num_executions, terminate4),
>     )
224c222,226
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold2, response_layer, threshold, terminate5)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>         pnl.While(terminate_num_executions, terminate5),
>     )
diff -r docs-base/_downloads/0e250fd5f7fdb8f2faa472e6658bed55/Cohen_Huston1994.py docs-head/_downloads/0e250fd5f7fdb8f2faa472e6658bed55/Cohen_Huston1994.py
275,283d274
< 
< def pass_threshold(response_layer, thresh):
<     results1 = response_layer.get_output_values(Bidirectional_Stroop)[0][0]  # red response
<     results2 = response_layer.get_output_values(Bidirectional_Stroop)[0][1]  # green response
<     if results1 >= thresh or results2 >= thresh:
<         return True
<     return False
< 
< 
285c276,279
<     pnl.TimeScale.TRIAL: pnl.While(pass_threshold, response_layer, threshold)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>     )
diff -r docs-base/_downloads/11ac9c80f617b4258b7c7c95505a6a38/Kalanthroff_PCTC_2018.py docs-head/_downloads/11ac9c80f617b4258b7c7c95505a6a38/Kalanthroff_PCTC_2018.py
293,303c293
< # Create threshold function -------------------------------------------------------------------------------------------
< 
< def pass_threshold(response_layer, thresh, context):
<     results1 = response_layer.get_output_values(context)[0][0]  # red response
<     results2 = response_layer.get_output_values(context)[0][1]  # green response
<     # print(results1)
<     # print(results2)
<     if results1 >= thresh or results2 >= thresh:
<         return True
<     return False
< 
---
> # Create threshold condition -------------------------------------------------------------------------------------------
306c296,299
<     pnl.TimeScale.TRIAL: pnl.While(pass_threshold, response_layer, threshold)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer.output_ports['SPECIAL_LOGISTIC'], 'value', threshold, '>=', 0),
>         pnl.Threshold(response_layer.output_ports['SPECIAL_LOGISTIC'], 'value', threshold, '>=', 1),
>     )
diff -r docs-base/genindex.html docs-head/genindex.html
1261,1262d1260
<   </ul></td>
<   <td style="width: 33%; vertical-align: top;"><ul>
1264a1263,1264
>   </ul></td>
>   <td style="width: 33%; vertical-align: top;"><ul>
1360a1361,1362
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.atol">atol (psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
1524a1527,1528
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.comparator">comparator (psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
1813c1817
<       <li><a href="Composition.html#psyneulink.core.compositions.composition.Graph.dependency_dict">dependency_dict (psyneulink.core.compositions.composition.Graph attribute)</a>
---
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.dependency">dependency (psyneulink.core.scheduling.condition.Threshold attribute)</a>
1816a1821,1822
>       <li><a href="Composition.html#psyneulink.core.compositions.composition.Graph.dependency_dict">dependency_dict (psyneulink.core.compositions.composition.Graph attribute)</a>
> </li>
2411a2418,2420
> 
>       <ul>
>         <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.indices">(psyneulink.core.scheduling.condition.Threshold attribute)</a>
2412a2422
>       </ul></li>
3819a3830,3831
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.parameter">parameter (psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
4832,4833d4843
<   </ul></td>
<   <td style="width: 33%; vertical-align: top;"><ul>
4835a4846,4847
>   </ul></td>
>   <td style="width: 33%; vertical-align: top;"><ul>
4949a4962,4963
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.rtol">rtol (psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
5337a5352,5353
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold">Threshold (class in psyneulink.core.scheduling.condition)</a>
> </li>
5344a5361,5362
>         <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.threshold">(psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
5350,5351d5367
<       <li><a href="IntegratorFunctions.html#psyneulink.core.components.functions.stateful.integratorfunctions.FitzHughNagumoIntegrator.time_constant_v">time_constant_v (psyneulink.core.components.functions.stateful.integratorfunctions.FitzHughNagumoIntegrator attribute)</a>
< </li>
5353a5370,5371
>       <li><a href="IntegratorFunctions.html#psyneulink.core.components.functions.stateful.integratorfunctions.FitzHughNagumoIntegrator.time_constant_v">time_constant_v (psyneulink.core.components.functions.stateful.integratorfunctions.FitzHughNagumoIntegrator attribute)</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","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","EVC","EVCAuxiliary","EVCControlMechanism","EpisodicMemoryMechanism","Function","Functions","GatingMechanism","GatingMechanisms","GatingProjection","GatingProjections","GatingSignal","GilzenratModel","InputPort","IntegratorFunctions","IntegratorMechanism","IntegratorMechanisms","KWTAMechanism","Keywords","KohonenMechanism","LCAMechanism","LCControlMechanism","LCMechanism","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","json"],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","BotvinickConflictMonitoringModel.rst","BustamanteStroopXORLVOCModel.rst","Cohen_HustonModel.rst","CombinationFunctions.rst","ComparatorMechanism.rst","Compilation.rst","Component.rst","Components.rst","Composition.rst","CompositionFunctionApproximator.rst","Comp
...

See CI logs for the full diff.

@github-actions
Copy link

github-actions bot commented Mar 5, 2022

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

diff -r docs-base/Condition.html docs-head/Condition.html
1895a1896,1957
> <dl class="py class">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold">
> <em class="property"><span class="pre">class</span> </em><span class="sig-prename descclassname"><span class="pre">psyneulink.core.scheduling.condition.</span></span><span class="sig-name descname"><span class="pre">Threshold</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">dependency</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">parameter</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">threshold</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">comparator</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">indices</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">atol</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">0</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">rtol</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">0</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold" title="Permalink to this definition">¶</a></dt>
> <dd><dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.dependency">
> <span class="sig-name descname"><span class="pre">dependency</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.dependency" title="Permalink to this definition">¶</a></dt>
> <dd><p>the node on which the Condition depends</p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.parameter">
> <span class="sig-name descname"><span class="pre">parameter</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.parameter" title="Permalink to this definition">¶</a></dt>
> <dd><p>the name of the parameter of <strong>dependency</strong> whose value is
> to be compared to <strong>threshold</strong></p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.threshold">
> <span class="sig-name descname"><span class="pre">threshold</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.threshold" title="Permalink to this definition">¶</a></dt>
> <dd><p>the fixed value compared to the value of the <strong>parameter</strong></p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.comparator">
> <span class="sig-name descname"><span class="pre">comparator</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.comparator" title="Permalink to this definition">¶</a></dt>
> <dd><p>the string comparison operator determining the direction or
> type of comparison of the value of the <strong>parameter</strong>
> relative to <strong>threshold</strong></p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.indices">
> <span class="sig-name descname"><span class="pre">indices</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.indices" title="Permalink to this definition">¶</a></dt>
> <dd><p>if specified, a series of indices that reach the desired
> number given an iterable value for <strong>parameter</strong></p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.atol">
> <span class="sig-name descname"><span class="pre">atol</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.atol" title="Permalink to this definition">¶</a></dt>
> <dd><p>absolute tolerance for the comparison</p>
> </dd></dl>
> 
> <dl class="py attribute">
> <dt class="sig sig-object py" id="psyneulink.core.scheduling.condition.Threshold.rtol">
> <span class="sig-name descname"><span class="pre">rtol</span></span><a class="headerlink" href="#psyneulink.core.scheduling.condition.Threshold.rtol" title="Permalink to this definition">¶</a></dt>
> <dd><p>relative tolerance (to <strong>threshold</strong>) for the comparison</p>
> </dd></dl>
> 
> <p>Satisfied when:</p>
> <blockquote>
> <div><p>The comparison between the value of the <strong>parameter</strong> and
> <strong>threshold</strong> using <strong>comparator</strong> is true. If <strong>comparator</strong> is
> an equality (==, !=), the comparison will be considered equal
> within tolerances <strong>atol</strong> and <strong>rtol</strong>.</p>
> </div></blockquote>
> <p class="rubric">Notes</p>
> <p>The comparison must be done with scalars. If the value of
> <strong>parameter</strong> contains more than one item, <strong>indices</strong> must be
> specified.</p>
> </dd></dl>
> 
diff -r docs-base/_downloads/08bdb54817a4817ad8e274272625aa24/Cohen_Huston1994_horse_race.py docs-head/_downloads/08bdb54817a4817ad8e274272625aa24/Cohen_Huston1994_horse_race.py
188,196d187
< # Create threshold function -------------------------------------------------------------------------------------------
< # context is automatically passed into Conditions, and references the execution context in which they are being run,
< # which in this case is simply the Bidirectional_Stroop system
< def pass_threshold(response_layer, thresh, context):
<     results1 = response_layer.get_output_values(context)[0][0] #red response
<     results2 = response_layer.get_output_values(context)[0][1] #green response
<     if results1  >= thresh or results2 >= thresh:
<         return True
<     return False
198,207c189,190
< # 2nd threshold function
< def pass_threshold2(response_layer, thresh, terminate, context):
<     results1 = response_layer.get_output_values(context)[0][0] #red response
<     results2 = response_layer.get_output_values(context)[0][1] #green response
<     length = response_layer.log.nparray_dictionary()[context.execution_id]['value'].shape[0]
<     if results1  >= thresh or results2 >= thresh:
<         return True
<     if length ==terminate:
<         return True
<     return False
---
> def terminate_num_executions(length, context):
>     return response_layer.log.nparray_dictionary()[context.execution_id]['value'].shape[0] == length
212c195,198
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold, response_layer, threshold)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>     )
215c201,205
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold2, response_layer, threshold, terminate2)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>         pnl.While(terminate_num_executions, terminate2),
>     )
218c208,212
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold2, response_layer, threshold, terminate3)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>         pnl.While(terminate_num_executions, terminate3),
>     )
221c215,219
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold2, response_layer, threshold, terminate4)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>         pnl.While(terminate_num_executions, terminate4),
>     )
224c222,226
<    pnl.TimeScale.TRIAL: pnl.While(pass_threshold2, response_layer, threshold, terminate5)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>         pnl.While(terminate_num_executions, terminate5),
>     )
diff -r docs-base/_downloads/0e250fd5f7fdb8f2faa472e6658bed55/Cohen_Huston1994.py docs-head/_downloads/0e250fd5f7fdb8f2faa472e6658bed55/Cohen_Huston1994.py
275,283d274
< 
< def pass_threshold(response_layer, thresh):
<     results1 = response_layer.get_output_values(Bidirectional_Stroop)[0][0]  # red response
<     results2 = response_layer.get_output_values(Bidirectional_Stroop)[0][1]  # green response
<     if results1 >= thresh or results2 >= thresh:
<         return True
<     return False
< 
< 
285c276,279
<     pnl.TimeScale.TRIAL: pnl.While(pass_threshold, response_layer, threshold)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 0)),
>         pnl.Threshold(response_layer, 'value', threshold, '>=', (0, 1)),
>     )
diff -r docs-base/_downloads/11ac9c80f617b4258b7c7c95505a6a38/Kalanthroff_PCTC_2018.py docs-head/_downloads/11ac9c80f617b4258b7c7c95505a6a38/Kalanthroff_PCTC_2018.py
293,303c293
< # Create threshold function -------------------------------------------------------------------------------------------
< 
< def pass_threshold(response_layer, thresh, context):
<     results1 = response_layer.get_output_values(context)[0][0]  # red response
<     results2 = response_layer.get_output_values(context)[0][1]  # green response
<     # print(results1)
<     # print(results2)
<     if results1 >= thresh or results2 >= thresh:
<         return True
<     return False
< 
---
> # Create threshold condition -------------------------------------------------------------------------------------------
306c296,299
<     pnl.TimeScale.TRIAL: pnl.While(pass_threshold, response_layer, threshold)
---
>     pnl.TimeScale.TRIAL: pnl.Or(
>         pnl.Threshold(response_layer.output_ports['SPECIAL_LOGISTIC'], 'value', threshold, '>=', 0),
>         pnl.Threshold(response_layer.output_ports['SPECIAL_LOGISTIC'], 'value', threshold, '>=', 1),
>     )
diff -r docs-base/genindex.html docs-head/genindex.html
1261,1262d1260
<   </ul></td>
<   <td style="width: 33%; vertical-align: top;"><ul>
1264a1263,1264
>   </ul></td>
>   <td style="width: 33%; vertical-align: top;"><ul>
1360a1361,1362
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.atol">atol (psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
1524a1527,1528
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.comparator">comparator (psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
1813c1817
<       <li><a href="Composition.html#psyneulink.core.compositions.composition.Graph.dependency_dict">dependency_dict (psyneulink.core.compositions.composition.Graph attribute)</a>
---
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.dependency">dependency (psyneulink.core.scheduling.condition.Threshold attribute)</a>
1816a1821,1822
>       <li><a href="Composition.html#psyneulink.core.compositions.composition.Graph.dependency_dict">dependency_dict (psyneulink.core.compositions.composition.Graph attribute)</a>
> </li>
2411a2418,2420
> 
>       <ul>
>         <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.indices">(psyneulink.core.scheduling.condition.Threshold attribute)</a>
2412a2422
>       </ul></li>
3819a3830,3831
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.parameter">parameter (psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
4832,4833d4843
<   </ul></td>
<   <td style="width: 33%; vertical-align: top;"><ul>
4835a4846,4847
>   </ul></td>
>   <td style="width: 33%; vertical-align: top;"><ul>
4949a4962,4963
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.rtol">rtol (psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
5337a5352,5353
>       <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold">Threshold (class in psyneulink.core.scheduling.condition)</a>
> </li>
5344a5361,5362
>         <li><a href="Condition.html#psyneulink.core.scheduling.condition.Threshold.threshold">(psyneulink.core.scheduling.condition.Threshold attribute)</a>
> </li>
5350,5351d5367
<       <li><a href="IntegratorFunctions.html#psyneulink.core.components.functions.stateful.integratorfunctions.FitzHughNagumoIntegrator.time_constant_v">time_constant_v (psyneulink.core.components.functions.stateful.integratorfunctions.FitzHughNagumoIntegrator attribute)</a>
< </li>
5353a5370,5371
>       <li><a href="IntegratorFunctions.html#psyneulink.core.components.functions.stateful.integratorfunctions.FitzHughNagumoIntegrator.time_constant_v">time_constant_v (psyneulink.core.components.functions.stateful.integratorfunctions.FitzHughNagumoIntegrator attribute)</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","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","EVC","EVCAuxiliary","EVCControlMechanism","EpisodicMemoryMechanism","Function","Functions","GatingMechanism","GatingMechanisms","GatingProjection","GatingProjections","GatingSignal","GilzenratModel","InputPort","IntegratorFunctions","IntegratorMechanism","IntegratorMechanisms","KWTAMechanism","Keywords","KohonenMechanism","LCAMechanism","LCControlMechanism","LCMechanism","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","json"],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","BotvinickConflictMonitoringModel.rst","BustamanteStroopXORLVOCModel.rst","Cohen_HustonModel.rst","CombinationFunctions.rst","ComparatorMechanism.rst","Compilation.rst","Component.rst","Components.rst","Composition.rst","CompositionFunctionApproximator.rst","Comp
...

See CI logs for the full diff.

@kmantel kmantel merged commit c7c172b into PrincetonUniversity:devel Mar 8, 2022
@kmantel kmantel deleted the threshold branch March 8, 2022 03:51
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.

Add compiler support for more scheduling conditions
2 participants