dfddm {fddm} | R Documentation |
Density of Ratcliff Diffusion Decision Model
Description
Density function for the Ratcliff diffusion decision model (DDM) with
following parameters: v
(drift rate), a
(threshold
separation), t0
(non-decision time/response time constant), w
(relative starting point), sv
(inter-trial variability of drift), and
sigma
(diffusion coefficient of underlying Wiener process). If you
are looking to fit the DDM, see ddm()
.
Usage
dfddm(
rt,
response,
v,
a,
t0,
w = 0.5,
sv = 0,
sigma = 1,
err_tol = 1e-06,
log = FALSE,
switch_mech = "eff_rt",
switch_thresh = 0.8,
n_terms_small = "SWSE",
summation_small = "2017"
)
Arguments
rt |
A vector of response times (in seconds). If a response time is
non-positve, then its density will evaluate to |
response |
Binary response(s) that correspond(s) to either the "lower" or "upper" threshold. This model parameter can either be a singular value or a vector. The value(s) in 'response' can be of the following data types:
|
v |
Drift rate. Average slope of the information accumulation process.
The drift gives information about the speed and direction of the
accumulation of information. Large (absolute) values of drift indicate a
good performance. If received information supports the response linked to
the upper threshold, then the sign will be positive; similarly a negative
value indicates that the received information supports the response linked
to the lower threshold. Allowed range: |
a |
Threshold separation. Amount of information that is considered for
a decision. Large values indicate a conservative decisional style. Allowed
range: |
t0 |
Non-decision time or response time constant (in seconds). Lower
bound for the duration of all non-decisional processes (encoding and
response execution). If this value is greater than |
w |
Relative starting point. Indicator of an a priori bias in decision
making. When the relative starting point |
sv |
Inter-trial-variability of drift rate. Standard deviation of a
normal distribution with mean |
sigma |
Diffusion coefficient of the underlying Wiener process. Allowed
range:
. |
err_tol |
Allowed error tolerance of the density function. The density
function contains an infinite sum that must be approximated; this
parameter is the upper bound of the total error incurred from this
approximation (in absolute value). See Details for more information.
Default is |
log |
Logical; if |
switch_mech |
Which switching mechanism to use in the choice of the
"large-time" or "small-time" density function. Can be one of
{ |
switch_thresh |
Threshold for determining whether the effective
response time ( |
n_terms_small |
Which method to use for calculating the "small-time"
approximation to the density function. Only applicable if
|
summation_small |
Which style of summation to use for the small-time
approximation to the infinite sum. Can be one of { |
Details
All of the model inputs and parameters (rt
, response
,
v
, a
, t0
, w
, sv
, sigma
) can be
input as a single value or as a vector of values. If input as a vector of
values, then the standard R
recycling rules apply to ensure all
inputs are of the same length.
The default settings of switch_mech = "eff_rt"
,
switch_thresh = "0.8"
, n_terms_small = "SWSE"
,
summation_small = "2017"
produce the fastest and most accurate
results, as shown in our associated paper.
sv
- Both the "small-time" and "large-time" variants of the density
function have two further variants: one with a constant drift rate v
(i.e., sv
= 0
), and one with a variable drift rate v
(i.e., sv
> 0
). The details of the differences between these
two density functions can be found in our associated paper. To use the
density function with a constant drift rate, leave the parameter sv
to its default value of sv = 0
, as this will indicate no drift to the
function. To use the density function with a variable drift rate, set the
parameter sv
to some non-negative value, i.e., sv
> 0
.
sigma
- The default value of this parameter is 1
because it
only scales the parameters v
, a
, and sv
, as shown
above. However, other formulations of the DDM may set sigma = 0.1
(see Ratcliff (1978), the fourth reference), so care must be taken when
comparing the results of different formulations.
err_tol
- The density function is composed of an infinite sum (that
must be approximated) and a multiplicative term outside the infinite sum,
m
. The total error of the approximation is the error incurred from
truncating the infinite sum multiplied by m
. Thus, to ensure that the
total error is bounded by the user-provided error tolerance, err_tol
,
the approximation to the infinite sum uses a modified error tolerance
(err_tol
/ m
). If the error tolerance is small and m
is
large, the modified error tolerance can underflow to 0
. To protect
against this, we check that the modified error tolerance is at least
1e-300
(near the smallest value that is representable by a floating
point number with double precision). If the modified error tolerance is
smaller than this threshold, then we silently change it to 1e-300
.
This case should only be encountered if extreme values of error tolerance
are used (i.e., on the scale of 1e-300
).
switch_mech
- The density function for the DDM has traditionally been
written in two forms: a "large-time" variant, and a "small-time" variant
(Navarro and Fuss, 2009). These two forms are more
efficient at calculating the density for large and small response times,
respectively. The parameter switch_mech
determines how dfddm
decides which of these two variants is used.
switch_mech = "small"
uses
only the "small-time" variant, and switch_mech = "large"
uses only
the "large-time" variant. The "large-time" variant is unstable for small
effective response times ((
rt
-
t0
)
/
(
a
*
a
) < 0.009
) and may produce inaccurate
densities; thus, we do not recommend using the switch_mech = "large"
option if the inputs may contain such small effective response times. To
circumvent this accuracy issue and resolve the differing efficiencies of the
"large-time" and "small-time" variants, there are three switching mechanisms
that can be used to determine which of the two variants is more efficient.
First, switch_mech = "terms"
is the traditional approach and
pre-calculates the number of terms required for the "large-time" and
"small-time" sums, and then uses whichever variant requires fewer terms.
This is the mechanism used in the Navarro and Fuss (2009) and Gondan,
Blurton, and Kesselmeier (2014) papers.
Second, switch_mech = "terms_large"
pre-calculates the number of
terms only for the "large-time" variant, and compares that to the constant
value of ceil(
switch_thresh
)
(default value of
ceil(0.8) = 1
) to determine if the "large-time" variant is
sufficiently efficient.
Third, switch_mech = "eff_rt"
determines whether a given effective
response time ((
rt
-
t0
)
/(
a
*
a
)
) is considered "large" or "small" by
comparing it to the value of the parameter switch_thresh
(default
value of 0.8
); it then uses the corresponding variant.
Both switch_mech = "terms_large"
and switch_mech = "eff_rt"
only use the SWSE "small-time" approximation in the case that the
"small-time" variant is more efficient. switch_mech = "eff_rt"
is the
most efficient method to determine which variant of the density function
should be used.
switch_thresh
- This parameter determines what effective response
times (rt
/(
a
*
a
)
) are "large" and
"small". The paper_analysis
folder in the fddm
GitHub
repository contains plots showing the relative efficiencies of a range of
values for the switch_thresh
parameter when used with
switch_mech = "eff_rt"
and also switch_mech = "terms_large"
.
Note that this parameter changed name and purpose with the release of
fddm
version 0.5-0.
n_terms_small
- The "small-time" variant has three different methods
for how to truncate the infinite sum in the density function. These
different methods are discussed extensively in our associated paper, but the
key distinction is that n_terms_small = "SWSE"
uses a new method of
truncating the infinite sum. The n_terms_small = "SWSE"
method is
currently recommended (when possible) because it is the fastest and most
stable algorithm when used with switch_mech = "eff_rt"
.
summation_small
- The "large-time" variant of the density function
does not have any further variants, but the "small-time" variant has more
options with respect to evaluating the infinite sum. There are two
equivalent styles of summation, summation_small = "2017"
and
summation_small = "2014"
, of which the "2017"
version
evaluates slightly faster and thus earns our recommendation. These different
styles of summation are discussed in our associated paper.
Value
A vector containing the densities of the DDM with precision
err_tol
whose length matches that of the longest input parameter
(usually rt
).
References
Navarro, D. J., & Fuss, I. G. (2009). Fast and accurate calculations for first-passage times in Wiener diffusion models. Journal of Mathematical Psychology, 53(4), 222-230.
Gondan, M., Blurton, S. P., & Kesselmeier, M. (2014). Even faster and even more accurate first-passage time densities and distributions for the Wiener diffusion model. Journal of Mathematical Psychology, 60, 20-22.
Blurton, S. P., Kesselmeier, M., & Gondan, M. (2017). The first-passage time distribution for the diffusion model with variable drift. Journal of Mathematical Psychology, 76, 7-12.
Ratcliff, R. (1978). A theory of memory retrieval. Psychological review, 85(2), 59.
See Also
Examples
# minimal example
dfddm(rt = 1.2, response = "lower", a = 1, v = -1, t0 = 0.3)
# example with all function parameters set to default or a practical value
dfddm(rt = c(1.2, 0.9, 1.1, 1.4, 0.8, 1.3),
response = c("lower", "upper", "upper", "lower", "upper", "lower"),
a = 1, v = -1, t0 = 0.2, w = 0.5, sv = 0, sigma = 1,
err_tol = 1e-6, log = FALSE, switch_mech = "eff_rt", switch_thresh = 0.8,
n_terms_small = "SWSE", summation_small = "2017")
# example of mismatched input lengths
dfddm(rt = c(1.2, 0.9, 1.1, 1.4, 0.8, 1.3),
response = c("lower", "upper", "upper", "lower", "upper", "lower"),
a = c(1, 3), v = c(-2, 2, 2, -2, 2, -2),
t0 = 0.3, w = c(0.4, 0.5, 0.6), sv = 0.9,
err_tol = 1e-10, log = FALSE, switch_mech = "large",
summation_small = "2017")
# example with Wiener diffusion coefficient (sigma) not equal to 1
dfddm(rt = c(1.2, 0.9, 1.1, 1.4, 0.8, 1.3),
response = c("lower", "upper", "upper", "lower", "upper", "lower"),
a = 1, v = -1, t0 = 0.3, w = 0.5, sv = 0, sigma = 0.1,
err_tol = 1e-10, log = TRUE, switch_mech = "terms_large",
switch_thresh = 1, summation_small = "2017")
### examples of different response inputs
# integer
resp_int <- as.integer(c(1, 2, 2, 1, 2, 1))
dfddm(rt = c(1.2, 0.9, 1.1, 1.4, 0.8, 1.3), response = resp_int,
a = 1, v = -2, t0 = 0.3, w = 0.5, sv = 0.1,
err_tol = 1e-10, log = FALSE, switch_mech = "eff_rt",
summation_small = "2017")
# double
resp_dbl <- as.double(c(1, 2, 2, 1, 2, 1))
dfddm(rt = c(1.2, 0.9, 1.1, 1.4, 0.8, 1.3), response = resp_dbl,
a = 1, v = -2, t0 = 0.3, w = 0.5, sv = 0.1,
err_tol = 1e-10, log = FALSE, switch_mech = "eff_rt",
summation_small = "2017")
# factor (first level is mapped to "lower")
days <- c("Monday", "Friday", "Friday", "Monday", "Friday", "Monday")
resp_fac <- factor(days, levels = c("Monday", "Friday"))
dfddm(rt = c(1.2, 0.9, 1.1, 1.4, 0.8, 1.3), response = resp_fac,
a = 1, v = -2, t0 = 0.3, w = 0.5, sv = 0.1,
err_tol = 1e-10, log = FALSE, switch_mech = "eff_rt",
summation_small = "2017")
# string
resp_str <- c("lower", "upper", "upper", "lower", "upper", "lower")
dfddm(rt = c(1.2, 0.9, 1.1, 1.4, 0.8, 1.3), response = resp_str,
a = 1, v = -2, t0 = 0.3, w = 0.5, sv = 0.1,
err_tol = 1e-10, log = FALSE, switch_mech = "eff_rt",
summation_small = "2017")
# logical
resp_log <- c(FALSE, TRUE, TRUE, FALSE, TRUE, FALSE)
dfddm(rt = c(1.2, 0.9, 1.1, 1.4, 0.8, 1.3), response = resp_log,
a = 1, v = -2, t0 = 0.3, w = 0.5, sv = 0.1,
err_tol = 1e-10, log = FALSE, switch_mech = "eff_rt",
summation_small = "2017")