DDM¶
Contents¶
Overview¶
The DDM Mechanism implements the “Drift Diffusion Model” (also know as the Diffusion Decision, Accumulation to Bound, Linear IntegratorFunction, and First Passage Time Model for a Wiener Process. This corresponds to a continuous version of the sequential probability ratio test (SPRT), that is the statistically optimal procedure for two alternative forced choice (TAFC) decision making (see drift-diffusion model in partciular).
The DDM Mechanism may be constructed with a choice of several functions that fall into to general categories: analytic solutions and path integration (see DDM Function Types below for more about these options.)
Creating a DDM Mechanism¶
A DDM Mechanism can be instantiated directly by calling its constructor, or by using the mechanism
command and
specifying DDM as its mech_spec argument. The model implementation is selected using the function
argument. The function selection can be simply the name of a DDM function:
>>> import psyneulink as pnl
>>> my_DDM = pnl.DDM(function=pnl.DriftDiffusionAnalytical)
or a call to the function with arguments specifying its parameters:
>>> my_DDM = pnl.DDM(function=pnl.DriftDiffusionAnalytical(drift_rate=0.2, threshold=1.0))
Structure¶
The DDM Mechanism implements a general form of the decision process.
Input¶
The input to the function
of a DDM Mechanism is always a scalar, irrespective of type of function that is used. Accordingly, the default InputPort for a DDM takes a single scalar value as its input,
that represents the stimulus for the decision process. However, this can be configured using the input_format
argument of the DDM’s consructor, to accomodate use of the DDM with other Mechanisms that generate a stimulus array
(e.g., representing the stimuli associated with each of the two choices). By default, the input_format is
SCALAR. However, if it is specified as ARRAY, the DDM’s InputPort is configured to accept a 1d 2-item vector,
and to use Reduce
as its Function, which subtracts the 2nd element of the vector from the 1st, and provides this as
the input to the DDM’s function
. If ARRAY is specified, two Standard OutputPorts
are added to the DDM, that allow the result of the decision process to be represented
as an array corresponding to the input array (see below).
Output¶
The DDM Mechanism can generate two different types of results depending on which function is selected. When a function representing an analytic solution is selected, the mechanism generates a single estimation for the process. When the path integration function is selected, the mechanism carries out step-wise integration of the process; each execution of the mechanism computes one step. (see DDM Function Types and Execution for additional details).
The value
of the DDM Mechanism may have up to ten items. The first two of these are always assigned, and
are represented by the DDM Mechanism’s two default OutputPorts`
: DECISION_VARIABLE and
RESPONSE_TIME. Other output_ports
may be automatically assigned,
depending on the function
that has been assigned to the DDM, as shown in the table below:
OutputPorts: |
|
|
X |
X |
|
X |
X |
|
X |
||
X |
||
X |
||
X |
||
X |
||
X |
||
X |
||
X |
The output_ports
assigned to a DDM can explicilty determined by specifying ones from its list
of standard_output_ports
in the output_ports argument of its constructor, or the
OUTPUT_PORTS entry of an OutputPort specification dictionary. This
can include any of the OutputPorts listed above `DDM_Default_OutputPorts
, as well as two additional ones –
– DECISION_VARIABLE_ARRAY and SELECTED_INPUT_ARRAY –
that are available if the ARRAY option is specified in its input_format argument (see Input). All of
these Standard OutputPorts are listed in the DDM’s standard_output_ports
attribute. As with any Mechanism, customized OutputPorts
can also be created and assigned.
DDM Function Types¶
Analytic Solutions¶
The Drift Diffusion Model Functions that calculate analytic solutions
[Bogacz et al (2006), Srivastava et al. (2016)] is DriftDiffusionAnalytical
function
, the mechanism generates a single estimate of the outcome for the decision process (see
Execution for details). In addition to DECISION_VARIABLE and
RESPONSE_TIME, the Function returns an accuracy value (represented in the
PROBABILITY_UPPER_THRESHOLD OutputPort), and an error rate value (in the
PROBABIILITY_LOWER_THRESHOLD OutputPort, and moments (mean, variance, and skew)
for conditional (correctpositive or incorrectnegative) response time distributions. These are; the mean RT for
correct responses (RT_CORRECT_MEAN, the RT variance for correct responses
(RT_CORRECT_VARIANCE, the RT skew for correct responses
(RT_CORRECT_SKEW, the mean RT for incorrect responses (RT_INCORRECT_MEAN, the RT variance for incorrect responses (RT_INCORRECT_VARIANCE, the RT skew for incorrect responses (RT_INCORRECT_SKEW.
An example that illustrate all of the parameters is shown below:
DriftDiffusionAnalytical Function:
>>> my_DDM_DriftDiffusionAnalytical = pnl.DDM(
... function=pnl.DriftDiffusionAnalytical(
... drift_rate=0.08928,
... starting_value=0.5,
... threshold=0.2645,
... noise=0.5,
... non_decision_time=0.15
... ),
... name='my_DDM_DriftDiffusionAnalytical'
... )
Path Integration¶
The Drift Diffusion Model Function that calculates a path integration is DriftDiffusionIntegrator. The DDM Mechanism uses the Euler method to carry out numerical step-wise integration of the decision process (see Execution below). In this mode, only the DECISION_VARIABLE and RESPONSE_TIME are available.
IntegratorFunction
Function:
>>> my_DDM_path_integrator = pnl.DDM(
... function=pnl.DriftDiffusionIntegrator(
... noise=0.5,
... initializer=1.0,
... non_decision_time=2.0,
... rate=3.0
... ),
... name='my_DDM_path_integrator'
... )
Execution¶
When a DDM Mechanism is executed, it computes the decision process either analytically or by
numerical step-wise integration of its path. The method used is determined by its function
(see DDM Function Types). The DDM’s function
always returns values for the DECISION_VARIABLE and RESPONSE_TIME, and assigns these as the first two items of its value
attribute, irrespective of its function.
When an analytic function is selected, the same set of values is returned for every execution.
The returned values are determined entirely by the set of parameters passed to its function
.
When the path integration, function is selected, a single step of integration is conducted each time the Mechanism is executed. The returned values accumulate on every execution.
The analytic functions return a final positon and time of the model, along with other statistics, where as the path integration function returns intermediate position and time values. The two types of functions can be thought of as happening on different time scales: trial (analytic) and time step (path integration).
References
Bogacz, R., Brown, E., Moehlis, J., Holmes, P., & Cohen, J. D. (2006). The physics of optimal decision making: A formal analysis of models of performance in two-alternative forced-choice tasks. Psychological Review, 113(4), 700-765. http://dx.doi.org/10.1037/0033-295X.113.4.700
Srivastava, V., Holmes, P., Simen., P. (2016). Explicit moments of decision times for single- and double-threshold drift-diffusion processes, Journal of Mathematical Psychology, 75, 96-109, ISSN 0022-2496, https://doi.org/10.1016/j.jmp.2016.03.005. (http://www.sciencedirect.com/science/article/pii/S0022249616000341)
Class Reference¶
- class psyneulink.library.components.mechanisms.processing.integrator.ddm.DDM(default_variable=None, input_shapes=None, input_format=None, function=None, input_ports=None, output_ports=None, seed=None, params=None, name=None, prefs=None, **kwargs)¶
Implements a drift diffusion process (also known as the Diffusion Decision Model, either by calculating an analytic solution or carrying out step-wise numerical integration. See Mechanism for additional arguments and attributes.
The default behaviour for the DDM is to reset its integration state on each new trial, this can be overridden by setting the
reset_stateful_function_when
attribute to a different condition. In addition, unlike TransferMechanism, the DDM’sexecute_until_finished
attribute is set toTrue
by default. This will cause the DDM to execute multiple time steps per call to itsexecute
method until the decision threshold is reached. This default behavior can be changed by settingexecute_until_finished
toFalse
.- Parameters
default_variable (value, list or np.ndarray : default FUNCTION_PARAMS[STARTING_VALUE]) – the input to the Mechanism used if none is provided in a call to its
execute
orrun
methods; also serves as a template to specify the length of thevariable
for itsfunction
, and theprimary OutputPort
of the DDM (seeInput
<DDM_Creation>` for how an input with a length of greater than 1 is handled).function (IntegratorFunction : default DriftDiffusionAnalytical) – specifies the function to use to execute the decision process; determines the mode of execution (see
function
and DDM Function Types for additional information).
- variable¶
the input to Mechanism’s execute method. Serves as the “stimulus” component of the
function
’s drift_rate parameter.- Type
value : default FUNCTION_PARAMS[STARTING_VALUE]
- function¶
the function used to execute the decision process; determines the mode of execution. If it is DriftDiffusionAnalytical, an analytic solution is calculated (note: the latter requires that the MatLab engine is installed); if it is an
IntegratorFunction
Function with anintegration_type
of DIFFUSION, then numerical step-wise integration is carried out. See DDM Function Types and Execution for additional information.- Type
IntegratorFunction : default DriftDiffusionAnalytical
- value¶
result of executing DDM
function
; has six items, that are assigned based on thefunction
attribute. The first two items are always assigned the values of DECISION_VARIABLE and RESPONSE_TIME (though their interpretation depends on thefunction
and corresponding mode of of operation). See DDM Function Types, Execution, and Output for additional information about other values that can be reported and their interpretation.- Type
2d np.array[array(float64),array(float64),array(float64),array(float64)]
- random_state¶
private pseudorandom number generator
- Type
numpy.RandomState
- output_ports¶
list of the DDM’s OutputPorts. There are always two OutputPorts, DECISION_VARIABLE and RESPONSE_TIME; additional ones may be included based on the
function
and/or any specifications made in the output_ports argument of the DDM’s constructor (see Output for additional details).- Type
ContentAddressableList[OutputPort]
- output_values¶
each item is the
value
of the corresponding OutputPort inoutput_ports
. The first two items are always thevalue
s of the DECISION_VARIABLE and RESPONSE_TIME OutputPorts; additional ones may be included, based on thefunction
and any specifications made in the output_ports argument of the DDM’s constructor (see Output for additional details).- Type
List[array(float64)]
- standard_output_ports¶
list of Standard OutputPorts that includes the following addition to the
standard_output_ports
of a Mechanism:- DECISION_VARIABLEfloat
analytic mode: the value of the threshold crossed by the decision variable on the current TRIAL (which is either the value of the DDM
function
’s threshold attribute or its negative);integration mode: the value of the decision variable at the current TIME_STEP of execution.
Corresponds to the 1st item of the DDM’s
value
.
- DECISION_VARIABLE_ARRAY1d nparray
Note
This is available only if input_format is specified as ARRAY in the DDM Mechanism’s constructor (see Input).
analytic mode: two element array, with the decision variable (1st item of the DDM’s
value
) as the 1st element if the decision process crossed the upper threshold, and the 2nd element if it is closer to the lower threshold; the other element is set to 0.integration mode: the value of the decision variable at the current TIME_STEP of execution, assigned to the 1st element if the decision variable is closer to the upper threshold, and to the 2nd element if it is closer to the lower threshold; the other element is set to 0.
- Type
list[str]
- SELECTED_INPUT_ARRAY1d nparray
Note
This is available only if input_format is specified as ARRAY in the DDM Mechanism’s constructor (see Input).
analytic mode: two element array, with one (“selected”) element – determined by the outcome of the decision process – set to the value of the corresponding element in the stimulus array (i.e., the DDM’s input_port
variable
). The “selected” element is the 1st one if the decision process resulted in crossing the upper threshold, and the 2nd if it crossed the lower threshold; the other element is set to 0.integration mode: the value of the element in the stimulus array based on the decision variable (1st item of the DDM’s
value
) at the current TIME_STEP of execution: it is assigned to the 1st element if the decision variable is closer to the upper threshold, and to the 2nd element if the decision variable is closer to the lower threshold; the other element is set to 0.
- RESPONSE_TIMEfloat
analytic mode: mean time (in seconds) for the decision variable to reach the positive or negative value of the DDM
function
’s threshold attribute as estimated by the analytic solution calculated by thefunction
);integration mode: the number of
TIME_STEP
s that have occurred since the DDM began to execute in the currentTRIAL
or, if it has reached the positive or negative value of the DDMfunction
’s threshold attribute, theTIME_STEP
at which that occurred.Corresponds to the 2nd item of the DDM’s
value
.
- DECISION_OUTCOMEfloat
analytic mode: 1.0 if the value of the threshold crossed by the decision variable on the current TRIAL (which is either the value of the DDM
function
’s threshold attribute or its negative) is positive, 0 otherwise.integration mode: 1if the value of the decision variable at the current TIME_STEP of execution is positive, 0 otherwise.
- PROBABILITY_UPPER_THRESHOLDfloat
analytic mode: the probability of the decision variable reaching the positive value of the DDM
function
’s threshold attribute as estimated by the analytic solution calculated by thefunction
; often, by convention, the positive (upper) threshold is associated with the correct response, in which case PROBABILITY_UPPER_THRESHOLD corresponds to the accuracy of the decision process.integration mode:
None
.
Corresponds to the 3rd item of the DDM’s
value
.
- PROBABILITY_LOWER_THRESHOLDfloat
analytic mode: the probability of the decision variable reaching the negative value of the DDM
function
’s threshold attribute as estimated by the analytic solution calculate by thefunction
); often, by convention, the negative (lower) threshold is associated with an error response, in which case PROBABILITY_LOWER_THRESHOLD corresponds to the error rate of the decision process;integration mode:
None
.
Corresponds to the 4th item of the DDM’s
value
.
- RT_CORRECT_MEANfloa
(only applicable if
function
isDriftDiffusionAnalytical
)analytic mode: the mean reaction time (in seconds) for responses in which the decision variable reached the positive value of the DDM
function
’s threshold attribute as estimated by closed form analytic solutions from Srivastava et al. (https://arxiv.org/abs/1601.06420)integration mode:
None
.
Corresponds to the 5th item of the DDM’s
value
.
- RT_CORRECT_VARIANCEfloat
(only applicable if
function
isDriftDiffusionAnalytical
)analytic mode: the variance of reaction time (in seconds) for responses in which the decision variable reached the positive value of the DDM
function
’s threshold attribute as estimated by closed form analytic solutions from Srivastava et al. (https://arxiv.org/abs/1601.06420)integration mode:
None
.
Corresponds to the 6th item of the DDM’s
value
.
- RT_CORRECT_SKEWfloat
(only applicable if
function
isDriftDiffusionAnalytical
)analytic mode: the skew of decision time (in seconds) for responses in which the decision variable reached the positive value of the DDM
function
’s threshold attribute as estimated by closed form analytic solutions from Srivastava et al. (https://arxiv.org/abs/1601.06420)integration mode:
None
.
Corresponds to the 7th item of the DDM’s
value
.
- RT_INCORRECT_MEANfloat
(only applicable if
function
isDriftDiffusionAnalytical
)analytic mode: the mean reaction time (in seconds) for responses in which the decision variable reached the negative value of the DDM
function
’s threshold attribute as estimated by closed form analytic solutions from Srivastava et al. (https://arxiv.org/abs/1601.06420)integration mode:
None
.
Corresponds to the 5th item of the DDM’s
value
.
- RT_INCORRECT_VARIANCEfloat
(only applicable if
function
isDriftDiffusionAnalytical
)analytic mode: the variance of reaction time (in seconds) for responses in which the decision variable reached the negative value of the DDM
function
’s threshold attribute as estimated by closed form analytic solutions from Srivastava et al. (https://arxiv.org/abs/1601.06420)integration mode:
None
.
Corresponds to the 6th item of the DDM’s
value
.
- RT_INCORRECT_SKEWfloat
(only applicable if
function
isDriftDiffusionAnalytical
)analytic mode: the skew of decision time (in seconds) for responses in which the decision variable reached the negative value of the DDM
function
’s threshold attribute as estimated by closed form analytic solutions from Srivastava et al. (https://arxiv.org/abs/1601.06420)integration mode:
None
.
Corresponds to the 7th item of the DDM’s
value
.
- plot(stimulus=1.0, threshold=10.0)¶
Generate a dynamic plot of the DDM integrating over time towards a threshold.
Note
The plot method is only available when the DriftDiffusionIntegrator function is in use. The plot method does not represent the results of this DDM mechanism in particular, and does not affect the current state of this mechanism’s DriftDiffusionIntegrator. The plot method is only meant to visualize a possible path of a DDM mechanism with these function parameters.
- Parameters
stimulus (float: default 1.0) – specify a stimulus value for the AdaptiveIntegrator function
threshold (float: default 10.0) – specify the threshold at which the DDM will stop integrating
- Returns
Mechanism’s function plot – Matplotlib window of the Mechanism’s function plotting dynamically over time with specified parameters towards a specified threshold
- Return type
Matplotlib window
- _validate_variable(variable, context=None)¶
Ensures that input to DDM is a single value. Remove when MULTIPROCESS DDM is implemented.
- _validate_params(request_set, target_set=None, context=None)¶
validate TimeScale, INPUT_PORTS, FUNCTION_PARAMS, OUTPUT_PORTS and MONITOR_FOR_CONTROL
- Go through target_set params (populated by Component._validate_params) and validate values for:
- INPUT_PORTS:
<MechanismsInputPort or Projection object or class, specification dict for one, 2-item tuple, or numeric value(s)>; if it is missing or not one of the above types, it is set to self.defaults.variable
- FUNCTION_PARAMS: <dict>, every entry of which must be one of the following:
ParameterPort or Projection object or class, specification dict for one, 2-item tuple, or numeric value(s); if invalid, default is assigned
- OUTPUT_PORTS:
<MechanismsOutputPort object or class, specification dict, or numeric value(s); if it is missing or not one of the above types, it is set to None here;
and then to default value of value (output of execute method) in instantiate_output_port (since execute method must be instantiated before self.defaults.value is known)
if OUTPUT_PORTS is a list or OrderedDict, it is passed along (to instantiate_output_ports) if it is a OutputPort class ref, object or specification dict, it is placed in a list
- MONITORED_PORTS:
** DOCUMENT
Note: PARAMETER_PORTS are validated separately – ** DOCUMENT WHY
- TBI - Generalize to go through all params, reading from each its type (from a registry),
and calling on corresponding subclass to get default values (if param not found) (as PROJECTION_TYPE and PROJECTION_SENDER are currently handled)
- _execute(variable=None, context=None, runtime_params=None)¶
Execute DDM function (currently only trial-level, analytic solution) Execute DDM and estimate outcome or calculate trajectory of decision variable Currently implements only trial-level DDM (analytic solution) and returns:
stochastically estimated decion outcome (convert mean ER into value between 1 and -1)
mean ER
mean RT
mean, variance, and skew of RT for correct (posititive threshold) responses
mean, variance, and skew of RT for incorrect (negative threshold) responses
Return current decision variable (self.outputPort.value) and other output values (self.output_ports[].value Arguments: # CONFIRM: variable (float): set to self.value (= self.input_value) - params (dict): runtime_params passed from Mechanism, used as one-time value for current execution:
DRIFT_RATE (float)
THRESHOLD (float)
kwDDM_Bias (float)
NON_DECISION_TIME (float)
NOISE (float)
context (str)
- Returns the following values in self.value (2D np.array) and in
the value of the corresponding outputPort in the self.output_ports dict: - decision variable (float) - mean error rate (float) - mean RT (float) - mean, variance, and skew of RT for correct (posititive threshold) responses - mean, variance, and skew of RT for incorrect (negative threshold) responses
- Parameters
self –
:param variable (float) :param params: (dict) :param context: (str) :rtype self.outputPort.value: (number)
- reset(*args, force=False, context=None, **kwargs)¶
Reset
value
if Mechanisms is stateful.If the mechanism’s
function
is anIntegratorFunction
, or if the mechanism has andintegrator_function
(see TransferMechanism), this method effectively begins the function’s accumulation over again at the specified value, and updates related attributes on the mechanism. It also clears thevalue
history
, thus effectively setting the previous value toNone
.If the mechanism’s
function
is anIntegratorFunction
, itsreset
method:Calls the function’s own
reset
method (see Note below for details)Sets the mechanism’s
value
to the output of the function’s reset methodUpdates its
output ports
based on its newvalue
If the mechanism has an
integrator_function
, itsreset
method:(1) Calls the `integrator_function's <TransferMechanism.integrator_function>` own `reset <IntegratorFunction.reset>` method (see Note below for details) (2) Executes its `function <Mechanism_Base.function>` using the output of the `integrator_function's <TransferMechanism.integrator_function>` `reset <IntegratorFunction.reset>` method as the function's variable (3) Sets the mechanism's `value <Mechanism_Base.value>` to the output of its function (4) Updates its `output ports <Mechanism_Base.output_port>` based on its new `value <Mechanism_Base.value>`
Note
The reset method of an IntegratorFunction Function typically resets the function’s
previous_value
(and any otherstateful_attributes
) andvalue
to the quantity (or quantities) specified. Ifreset
is called without arguments, theinitializer
value (or the values of each of the attributes ininitializers
) is used instead. Thereset
method may vary across different Integrators. See individual functions for details on theirstateful_attributes
, as well as other reinitialization steps that the reset method may carry out.
- exception psyneulink.library.components.mechanisms.processing.integrator.ddm.DDMError(message, component=None)¶