Skip to content

Commit

Permalink
Merge pull request #683 from PrincetonUniversity/devel
Browse files Browse the repository at this point in the history
Devel
  • Loading branch information
KristenManning authored Feb 28, 2018
2 parents 3d2fc31 + 76a9c96 commit ba8dacb
Show file tree
Hide file tree
Showing 13 changed files with 303 additions and 127 deletions.
6 changes: 4 additions & 2 deletions psyneulink/components/functions/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -1128,8 +1128,10 @@ def __init__(self,

def function(self,
**kwargs):
return self.custom_function(**kwargs)

try:
return self.custom_function(**kwargs)
except TypeError:
return self.custom_function(kwargs[VARIABLE])

# region ********************************** COMBINATION FUNCTIONS ****************************************************
# endregion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -899,7 +899,8 @@ class LearningMechanism(AdaptiveMechanism_Base):

@tc.typecheck
def __init__(self,
default_variable:tc.any(list, np.ndarray),
# default_variable:tc.any(list, np.ndarray),
default_variable=None,
size=None,
error_sources:tc.optional(tc.any(Mechanism, list))=None,
function:is_function_type=BackPropagation,
Expand Down
29 changes: 24 additions & 5 deletions psyneulink/components/mechanisms/mechanism.py
Original file line number Diff line number Diff line change
Expand Up @@ -1856,11 +1856,30 @@ def reinitialize(self, *args):
# (1) reinitialize it, (2) run the primary function with the new "previous_value" as input
# (3) update value, (4) update output states
elif hasattr(self, "integrator_function"):
new_input = self.integrator_function.reinitialize(*args)
if hasattr(self, "initial_value"):
self.initial_value = np.atleast_1d(*args)[0]
self.value = self.function(new_input, context="REINITIALIZING")
self._update_output_states(context="REINITIALIZING")
if isinstance(self.integrator_function, Integrator):
new_input = self.integrator_function.reinitialize(*args)
if hasattr(self, "initial_value"):
self.initial_value = np.atleast_2d(*args)
self.value = self.function(new_input, context="REINITIALIZING")
self._update_output_states(context="REINITIALIZING")

elif self.integrator_function is None:
if hasattr(self, "integrator_mode"):
raise MechanismError("Reinitializing {} is not allowed because this Mechanism is not stateful. "
"(It does not have an accumulator to reinitialize.) If this Mechanism "
"should be stateful, try setting the integrator_mode argument to True. "
.format(self.name))
else:
raise MechanismError("Reinitializing {} is not allowed because this Mechanism is not stateful. "
"(It does not have an accumulator to reinitialize).".format(self.name))

else:
raise MechanismError("Reinitializing {} is not allowed because its integrator_function is not an "
"Integrator type function, therefore the Mechanism does not have an accumulator to"
" reinitialize.".format(self.name))
else:
raise MechanismError("Reinitializing {} is not allowed because this Mechanism is not stateful. "
"(It does not have an accumulator to reinitialize).".format(self.name))

def get_current_mechanism_param(self, param_name):
try:
Expand Down
67 changes: 24 additions & 43 deletions psyneulink/components/mechanisms/processing/transfermechanism.py
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ class TransferMechanism(ProcessingMechanism_Base):
noise=0.0, \
smoothing_factor=0.5, \
integrator_mode=False, \
clip=(float:min, float:max), \
clip=[float:min, float:max], \
output_states=RESULTS \
params=None, \
name=None, \
Expand Down Expand Up @@ -491,10 +491,10 @@ class TransferMechanism(ProcessingMechanism_Base):
result = (smoothing_factor * current input) + ((1-smoothing_factor) * result on previous time_step)
clip : Optional[Tuple[float, float]]
specifies the allowable range for the result of `function <TransferMechanism.function>`:
the first item specifies the minimum allowable value of the result, and the second its maximum allowable value;
any element of the result that exceeds the specified minimum or maximum value is set to the value of
clip : list [float, float] : default None (Optional)
specifies the allowable range for the result of `function <TransferMechanism.function>`. The item in index 0
specifies the minimum allowable value of the result, and the item in index 1 specifies the maximum allowable
value; any element of the result that exceeds the specified minimum or maximum value is set to the value of
`clip <TransferMechanism.clip>` that it exceeds.
output_states : str, list or np.ndarray : default RESULTS
Expand Down Expand Up @@ -594,11 +594,12 @@ class TransferMechanism(ProcessingMechanism_Base):
`integrator_function <TransferMechanism.integrator_function>` is skipped entirely, and all related arguments (*noise*, *leak*,
*initial_value*, and *time_step_size*) are ignored.
clip : Optional[Tuple[float, float]]
determines the allowable range of the result: the first value specifies the minimum allowable value
and the second the maximum allowable value; any element of the result that exceeds minimum or maximum
is set to the value of `clip <TransferMechanism.clip>` it exceeds. If `function <TransferMechanism.function>`
is `Logistic`, `clip <TransferMechanism.clip>` is set by default to (0,1).
clip : list [float, float] : default None (Optional)
specifies the allowable range for the result of `function <TransferMechanism.function>`
the item in index 0 specifies the minimum allowable value of the result, and the item in index 1 specifies the
maximum allowable value; any element of the result that exceeds the specified minimum or maximum value is set to
the value of `clip <TransferMechanism.clip>` that it exceeds.
value : 2d np.array [array(float64)]
result of executing `function <TransferMechanism.function>`.
Expand Down Expand Up @@ -739,19 +740,11 @@ def _validate_params(self, request_set, target_set=None, context=None):
initial_value = target_set[INITIAL_VALUE]
if initial_value is not None:
if not iscompatible(initial_value, self.instance_defaults.variable):
raise Exception(
"initial_value is {}, type {}\nself.instance_defaults.variable is {}, type {}".format(
initial_value,
type(initial_value).__name__,
self.instance_defaults.variable,
type(self.instance_defaults.variable).__name__,
)
)
raise TransferError(
"The format of the initial_value parameter for {} ({}) must match its input ({})".format(
"The format of the initial_value parameter for {} ({}) must match its variable ({})".format(
append_type_to_name(self),
initial_value,
self.instance_defaults.variable[0],
self.instance_defaults.variable,
)
)

Expand All @@ -768,7 +761,7 @@ def _validate_params(self, request_set, target_set=None, context=None):
# Validate SMOOTHING_FACTOR:
if SMOOTHING_FACTOR in target_set:
smoothing_factor = target_set[SMOOTHING_FACTOR]
if (not (isinstance(smoothing_factor, float) and 0 <= smoothing_factor <= 1)) and (smoothing_factor != None):
if (not (isinstance(smoothing_factor, (int, float)) and 0 <= smoothing_factor <= 1)) and (smoothing_factor != None):
raise TransferError("smoothing_factor parameter ({}) for {} must be a float between 0 and 1".
format(smoothing_factor, self.name))

Expand Down Expand Up @@ -967,35 +960,23 @@ def _execute(self,
if isinstance(self.function_object, TransferFunction):

outputs = self.function(variable=current_input, params= runtime_params)
# if clip is not None:
# print(clip)
# minCapIndices = np.where(outputs < clip[0])
# print(minCapIndices)
# maxCapIndices = np.where(outputs > clip[1])
# print(maxCapIndices)
# outputs[minCapIndices] = np.min(clip)
# outputs[maxCapIndices] = np.max(clip)
if clip is not None:
minCapIndices = np.where(outputs < clip[0])
maxCapIndices = np.where(outputs > clip[1])
outputs[minCapIndices] = np.min(clip)
outputs[maxCapIndices] = np.max(clip)
else:
# Apply TransferMechanism's function to each input state separately
outputs = []
for elem in current_input:
output_item = self.function(variable=elem, params=runtime_params)
# if clip is not None:
# minCapIndices = np.where(output_item < clip[0])
# maxCapIndices = np.where(output_item > clip[1])
# output_item[minCapIndices] = np.min(clip)
# output_item[maxCapIndices] = np.max(clip)
if clip is not None:
minCapIndices = np.where(output_item < clip[0])
maxCapIndices = np.where(output_item > clip[1])
output_item[minCapIndices] = np.min(clip)
output_item[maxCapIndices] = np.max(clip)
outputs.append(output_item)

# outputs = []
# for elem in current_input:
# output_item = self.function(variable=elem, params=runtime_params)
# if clip is not None:
# minCapIndices = np.where(output_item < clip[0])
# maxCapIndices = np.where(output_item > clip[1])
# output_item[minCapIndices] = np.min(clip)
# output_item[maxCapIndices] = np.max(clip)
# outputs.append(output_item)
return outputs
#endregion

Expand Down
21 changes: 10 additions & 11 deletions psyneulink/library/mechanisms/processing/transfer/kwta.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,10 +287,10 @@ class KWTA(RecurrentTransferMechanism):
is allowed, including positive offsets; if set to `True`, a positive offset will be re-assigned the value of 0
(see `inhibition_only <KWTA_inhibition_only>` for additional information).
clip : Optional[Tuple[float, float]]
specifies the allowable range for the result of `function <KWTA.function>`:
the first item specifies the minimum allowable value of the result, and the second its maximum allowable value;
any element of the result that exceeds the specified minimum or maximum value is set to the value of
clip : list [float, float] : default None (Optional)
specifies the allowable range for the result of `function <KWTA.function>` the item in index 0 specifies the
minimum allowable value of the result, and the item in index 1 specifies the maximum allowable value; any
element of the result that exceeds the specified minimum or maximum value is set to the value of
`clip <KWTA.clip>` that it exceeds.
params : Dict[param keyword: param value] : default None
Expand Down Expand Up @@ -378,11 +378,12 @@ class KWTA(RecurrentTransferMechanism):
"clipped" at (that is, any positive value is replaced by) 0. Otherwise, any offset is allowed (see
`inhibition_only <KWTA_inhibition_only>` for additional information).
clip : Tuple[float, float]
determines the allowable range of the result: the first value specifies the minimum allowable value
and the second the maximum allowable value; any element of the result that exceeds minimum or maximum
is set to the value of `clip <KWTA.clip>` it exceeds. If `function <KWTA.function>`
is `Logistic`, `clip <KWTA.clip>` is set by default to (0,1).
clip : list [float, float] : default None (Optional)
specifies the allowable range for the result of `function <KWTA.function>`
the item in index 0 specifies the minimum allowable value of the result, and the item in index 1 specifies the
maximum allowable value; any element of the result that exceeds the specified minimum or maximum value is set to
the value of `clip <KWTA.clip>` that it exceeds.
integrator_function:
When *integrator_mode* is set to True, the KWTA executes its `integrator_function <KWTA.integrator_function>`,
Expand Down Expand Up @@ -647,9 +648,7 @@ def _execute(self,
variable, self, self.__class__.__name__
)
)

variable = self._update_variable(self._kwta_scale(variable, context=context))

return super()._execute(variable=variable,
runtime_params=runtime_params,
context=context)
Expand Down
29 changes: 16 additions & 13 deletions psyneulink/library/mechanisms/processing/transfer/lca.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ class LCA(RecurrentTransferMechanism):
noise=0.0, \
integrator_mode = True \
time_step_size = 0.1 \
clip=(float:min, float:max), \
clip=[float:min, float:max], \
params=None, \
name=None, \
prefs=None)
Expand Down Expand Up @@ -329,11 +329,12 @@ class LCA(RecurrentTransferMechanism):
sets the time_step_size used by the mechanism's `integrator_function <LCA.integrator_function>`. See
`integrator_mode <LCA.integrator_mode>` for more details.
clip : Optional[Tuple[float, float]]
specifies the allowable range for the result of `function <TransferMechanism.function>`:
the first item specifies the minimum allowable value of the result, and the second its maximum allowable value;
any element of the result that exceeds the specified minimum or maximum value is set to the value of
`clip <TransferMechanism.clip>` that it exceeds.
clip : list [float, float] : default None (Optional)
specifies the allowable range for the result of `function <LCA.function>` the item in index 0 specifies the
minimum allowable value of the result, and the item in index 1 specifies the maximum allowable value; any
element of the result that exceeds the specified minimum or maximum value is set to the value of
`clip <LCA.clip>` that it exceeds.
params : Dict[param keyword: param value] : default None
a `parameter dictionary <ParameterState_Specification>` that can be used to specify the parameters for
Expand Down Expand Up @@ -431,11 +432,13 @@ class LCA(RecurrentTransferMechanism):
its distribution on each execution. If noise is specified as a float or as a function with a fixed output, then
the noise will simply be an offset that remains the same across all executions.
clip : Tuple[float, float]
determines the allowable range of the result: the first value specifies the minimum allowable value
and the second the maximum allowable value; any element of the result that exceeds minimum or maximum
is set to the value of `clip <TransferMechanism.clip>` it exceeds. If `function <TransferMechanism.function>`
is `Logistic`, `clip <TransferMechanism.clip>` is set by default to (0,1).
clip : list [float, float] : default None (Optional)
specifies the allowable range for the result of `function <LCA.function>`
the item in index 0 specifies the minimum allowable value of the result, and the item in index 1 specifies the
maximum allowable value; any element of the result that exceeds the specified minimum or maximum value is set to
the value of `clip <LCA.clip>` that it exceeds.
value : 2d np.array [array(float64)]
result of executing `function <TransferMechanism.function>`; same value as fist item of
Expand Down Expand Up @@ -664,10 +667,10 @@ def _execute(self,
# (MODIFIED 7/13/17 CW) this if/else below is hacky: just allows a nicer error message
# when the input is given as a string.
if (np.array(noise) != 0).any():
current_input = variable[0] + noise
current_input = variable + noise
else:

current_input = variable[0]
current_input = variable

# Apply TransferMechanism function
output_vector = self.function(variable=current_input, params=runtime_params)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ class RecurrentTransferMechanism(TransferMechanism):
initial_value=None, \
noise=0.0, \
smoothing_factor=0.5, \
clip=(float:min, float:max), \
clip=[float:min, float:max], \
learning_rate=None, \
learning_function=Hebbian, \
integrator_mode=False, \
Expand Down Expand Up @@ -390,11 +390,12 @@ class RecurrentTransferMechanism(TransferMechanism):
result = (smoothing_factor * variable) +
(1-smoothing_factor * input to mechanism's function on the previous time step)
clip : Optional[Tuple[float, float]]
specifies the allowable range for the result of `function <RecurrentTransferMechanism.function>`:
the first item specifies the minimum allowable value of the result, and the second its maximum allowable value;
any element of the result that exceeds the specified minimum or maximum value is set to the value of
`clip <RecurrentTransferMechanism.clip>` that it exceeds.
clip : list [float, float] : default None (Optional)
specifies the allowable range for the result of `function <RecurrentTransferMechanism.function>` the item in
index 0 specifies the minimum allowable value of the result, and the item in index 1 specifies the maximum
allowable value; any element of the result that exceeds the specified minimum or maximum value is set to the
value of `clip <RecurrentTransferMechanism.clip>` that it exceeds.
enable_learning : boolean : default False
specifies whether the Mechanism should be configured for learning; if it is not (the default), then learning
Expand Down Expand Up @@ -501,12 +502,12 @@ class RecurrentTransferMechanism(TransferMechanism):
result = (smoothing_factor * current input) + (1-smoothing_factor * result on previous time_step)
clip : Tuple[float, float]
determines the allowable range of the result: the first value specifies the minimum allowable value
and the second the maximum allowable value; any element of the result that exceeds minimum or maximum
is set to the value of `clip <RecurrentTransferMechanism.clip>` it exceeds. If
`function <RecurrentTransferMechanism.function>`
is `Logistic`, `clip <RecurrentTransferMechanism.clip>` is set by default to (0,1).
clip : list [float, float] : default None (Optional)
specifies the allowable range for the result of `function <RecurrentTransferMechanism.function>`
the item in index 0 specifies the minimum allowable value of the result, and the item in index 1 specifies the
maximum allowable value; any element of the result that exceeds the specified minimum or maximum value is set to
the value of `clip <RecurrentTransferMechanism.clip>` that it exceeds.
previous_input : 1d np.array of floats
the value of the input on the previous execution, including the value of `recurrent_projection`.
Expand Down
Loading

0 comments on commit ba8dacb

Please sign in to comment.