Skip to content

Add stDDM to SequentialSamplingModels #59

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

Merged
merged 11 commits into from
Mar 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
StatsAPI = "82ae8749-77ed-4fe6-ae5f-f523153014b0"
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"

[weakdeps]
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
Expand Down
1 change: 1 addition & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ makedocs(
"Muti-attribute attentional drift diffusion Model" => "maaDDM.md",
"Poisson Race" => "poisson_race.md",
"Racing Diffusion Model (RDM)" => "rdm.md",
"Starting-time Drift Diffusion Model (stDDM)" => "stDDM.md",
"Wald Model" => "wald.md",
"Wald Mixture Model" => "wald_mixture.md",
],
Expand Down
100 changes: 100 additions & 0 deletions docs/src/stDDM.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Starting-time Drift Diffusion Model (stDDM)

The relative starting time drift diffusion model (stDDM) characterizes the contributions of multiple unique attributes to the rate of evidence accumulation. Compared to the DDM, which assumes a constant evidence accumulation rate within each trial, the stDDM allows different attributes to enter the evidence accumulation process at various time points relative to one another. By doing so, the stDDM quantifies both the weights given to each attribute and their onset times (Amasino et al., 2019; Barakchian et al., 2021; Chen et al., 2022; Maier et al., 2020; Sullivan and Huettel, 2021).

# Example
In this example, we will demonstrate how to use the stDDM in a generic two-alternative forced-choice task with two arbitrary attributes.

## Load Packages
The first step is to load the required packages.

```@example stDDM
using SequentialSamplingModels
using Plots
using Random

Random.seed!(8741)
```

## Create Model Object
In the code below, we will define parameters for the stDDM and create a model object to store the parameter values.

### Drift Rate
The drift rate controls the speed and direction in which information accumulates. Here, each drift coefficient indicates the weighting strengths given to the first and second attributes (e.g., taste and health, payoff and delay, self and other), respectively, to the total drift rate in a given trial, where the drift rate accumulates relative evidence in favor of an option.
```@example stDDM
ν = [2.5,2.0]
```
### Diffusion Noise
Diffusion noise is the amount of within trial noise in the evidence accumulation process.
```@example stDDM
σ = 1.0
```

### starting time
The starting time parameter $s$ denotes how much earlier one attribute begins to affect the evidence accumulation process relative to the other(s). If $s$ is negative, attribute 1 evidence is accumulated before attribute 2 evidence; if $s$ is positive, attribute 1 evidence is accumulated after attribute 2 evidence. The absolute value of $s$ indicates the difference in starting times for the two attributes.
```@example stDDM
s = 0.10
```

### Starting Point
An indicator of an an initial bias towards a decision. The z parameter is relative to a (i.e. it ranges from 0 to 1).
```@example stDDM
z = 0.50
```

### Drift Rates Dispersion
Dispersion parameters of the drift rate are drawn from a multivariate normal distribution, with the mean vector ν describing the distribution of actual drift rates from specific trials. The standard deviation or across-trial variability is captured by the η vector, and the corresponding correlation between the two attributes is denoted by ρ.
```@example stDDM
η = [1.0,1.0]
ρ = 0.3
```

### Threshold
The threshold α represents the amount of evidence required to make a decision.
```@example stDDM
α = 1.5
```

### Non-Decision Time
Non-decision time is an additive constant representing encoding and motor response time.
```@example stDDM
τ = 0.30
```

### stDDM Constructor
Now that values have been asigned to the parameters, we will pass them to `stDDM` to generate the model object.
```@example stDDM
dist = stDDM(;ν, σ, s, z, η, ρ, α, τ,)
```

## Simulate Model
Now that the model is defined, we will generate $10,000$ choices and reaction times using `rand`.
```@example stDDM
choices,rts = rand(dist, 10_000)
```

## Compute Choice Probability
The choice probability $\Pr(C=c)$ is computed by passing the model and choice index to `cdf`.
```@example stDDM
cdf(dist, 1)
```
To compute the joint probability of choosing $c$ within $t$ seconds, i.e., $\Pr(T \leq t \wedge C=c)$, pass a third argument for $t$.

## Plot Simulation
The code below overlays the PDF on reaction time histograms for each option.
```@example stDDM
histogram(dist)
plot!(dist; t_range=range(.301, 3.0, length=100))
```

# References

Amasino, D.R., Sullivan, N.J., Kranton, R.E. et al. Amount and time exert independent influences on intertemporal choice. Nat Hum Behav 3, 383–392 (2019). https://doi.org/10.1038/s41562-019-0537-2

Barakchian, Z., Beharelle, A.R. & Hare, T.A. Healthy decisions in the cued-attribute food choice paradigm have high test-retest reliability. Sci Rep, (2021). https://doi.org/10.1038/s41598-021-91933-6

Chen, HY., Lombardi, G., Li, SC. et al. Older adults process the probability of winning sooner but weigh it less during lottery decisions. Sci Rep, (2022). https://doi.org/10.1038/s41598-022-15432-y

Maier, S.U., Raja Beharelle, A., Polanía, R. et al. Dissociable mechanisms govern when and how strongly reward attributes affect decisions. Nat Hum Behav 4, 949–963 (2020). https://doi.org/10.1038/s41562-020-0893-y

Sullivan, N.J., Huettel, S.A. Healthful choices depend on the latency and rate of information accumulation. Nat Hum Behav 5, 1698–1706 (2021). https://doi.org/10.1038/s41562-021-01154-0
6 changes: 5 additions & 1 deletion src/SequentialSamplingModels.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ module SequentialSamplingModels
import Distributions: rand
import Distributions: std
import StatsAPI: params
import StatsBase:cor2cov

export AbstractDDM
export AbstractaDDM
Expand All @@ -36,7 +37,8 @@ module SequentialSamplingModels
export AbstractLCA
export AbstractLNR
export AbstractPoissonRace
export AbstractRDM
export AbstractRDM
export AbstractstDDM
export AbstractWald
export aDDM
export CDDM
Expand All @@ -50,6 +52,7 @@ module SequentialSamplingModels
export PoissonRace
export SSM1D
export SSM2D
export stDDM
export ContinuousMultivariateSSM
export Wald
export WaldMixture
Expand Down Expand Up @@ -92,4 +95,5 @@ module SequentialSamplingModels
include("ext_functions.jl")
include("ex_gaussian.jl")
include("poisson_race.jl")
include("stDDM.jl")
end
201 changes: 201 additions & 0 deletions src/stDDM.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
"""
stDDM{T<:Real} <: AbstractstDDM

An object for the starting-time diffusion decision model.

# Parameters

- `ν`: vector of drift rate weights for attribute one and two
- `σ`: diffusion noise
- `s`: initial latency bias (positive for attribute two, negative for attribute one)
- `z`: initial evidence
- `η`: vector of variability in drift rate for attribute one and two
- `ρ`: correlation between drift rate for attributes
- `α`: evidence threshold
- `τ`: non-decision time

# Constructors

stDDM(ν, σ, s, z, η, ρ, α, τ)

stDDM(;ν = [0.5,0.6],σ = 1,s = 0.50, z = 0.50, η = [1.0,1.0], ρ = 0.00, α = 1.0, τ = .300)

# Example

```julia
using SequentialSamplingModels

ν = [0.5, 0.6]
σ = 1
s = 0.50
z = 0.50
η = [1.0, 1.0]
ρ = 0.00
α = 1.0
τ = 0.300

# Create stDDM model instance
dist = stDDM(;ν, σ, s, z, η, ρ, α, τ)

choices,rts = rand(dist, 500)
```

# References

Amasino, D.R., Sullivan, N.J., Kranton, R.E. et al. Amount and time exert independent influences on intertemporal choice. Nat Hum Behav 3, 383–392 (2019). https://doi.org/10.1038/s41562-019-0537-2

Barakchian, Z., Beharelle, A.R. & Hare, T.A. Healthy decisions in the cued-attribute food choice paradigm have high test-retest reliability. Sci Rep, (2021). https://doi.org/10.1038/s41598-021-91933-6

Chen, HY., Lombardi, G., Li, SC. et al. Older adults process the probability of winning sooner but weigh it less during lottery decisions. Sci Rep, (2022). https://doi.org/10.1038/s41598-022-15432-y

Lombardi, G., & Hare, T. Piecewise constant averaging methods allow for fast and accurate hierarchical Bayesian estimation of drift diffusion models with time-varying evidence accumulation rates. PsyArXiv, (2021). https://doi.org/10.31234/osf.io/5azyx

Sullivan, N.J., Huettel, S.A. Healthful choices depend on the latency and rate of information accumulation. Nat Hum Behav 5, 1698–1706 (2021). https://doi.org/10.1038/s41562-021-01154-0
"""

mutable struct stDDM{T<:Real} <: AbstractstDDM
ν::Vector{T}
σ::T
s::T
z::T
η::Vector{T}
ρ::T
α::T
τ::T
end

function stDDM(ν, σ, s, z, η, ρ, α, τ)
_, σ ,s ,z ,_ ,ρ , α, τ = promote(ν[1],σ, s, z, η[1], ρ, α, τ)
ν = convert(Vector{typeof(τ)}, ν)
η = convert(Vector{typeof(τ)}, η)
return stDDM(ν, σ, s, z, η, ρ, α, τ)
end

function stDDM(;ν = [0.5,0.6],
σ = 1,
s = 0.50,
z = 0.50,
η = fill(1.0, length(ν)),
ρ = 0.0,
α = 1.0,
τ = .300
)
return stDDM(ν, σ, s, z, η, ρ, α, τ)
end

function params(d::AbstractstDDM)
(d.ν, d.σ, d.s, d.z, d.η, d.ρ, d.α, d.τ)
end

get_pdf_type(d::AbstractstDDM) = Approximate

"""
rand(dist::AbstractstDDM)

Generate a random choice-rt pair for starting-time diffusion decision model.

# Arguments
- `rng`: a random number generator
- `dist`: model object for the starting-time diffusion decision model.
- `Δt`: time-step for simulation
"""
function rand(rng::AbstractRNG, dist::AbstractstDDM; kwargs...)
return simulate_trial(rng, dist; kwargs...)
end

"""
simulate_trial(rng::AbstractRNG, dist::AbstractstDDM; Δt, max_steps)

Generate a single simulated trial from the starting-time diffusion decision model.

# Arguments

- `rng`: a random number generator
- `model::AbstractstDDM`: a starting-time diffusion decision model object
- `Δt`: time-step for simulation
- `max_steps`: total/max time for simulation
"""
function simulate_trial(rng::AbstractRNG, d::AbstractstDDM; Δt = .001, max_steps=6)
(;ν, σ, s, z, η, ρ, α, τ) = d

lt = Int(max_steps / Δt)
start_step = abs(Int(s / Δt))

t = τ
choice = 0 # Initialize choice with a default value

X = z * α
deciding = true
cont = 1
Ρ = [1.0 ρ; ρ 1.0]
Σ = cor2cov(Ρ,η)

evidence = rand(MvNormal([ν[1], ν[2]], Σ))

while deciding && cont <= lt
δ1 = cont ≤ start_step && s > 0 ? 0.0 : 1.0
δ2 = cont ≤ start_step && s < 0 ? 0.0 : 1.0

noise = rand(rng, Normal(0, σ)) * √(Δt)

X += (evidence[1] * δ1 + evidence[2] * δ2) * Δt + noise
# X += (evidence[1] * a1Δ * δ1 + evidence[2] * a1Δ * δ2) * Δt + noise #note something to consider and fix is attribute difference
if X > α
choice = 1
deciding = false
elseif X < 0
choice = 2
deciding = false
end
t += Δt

cont += 1
end

return (;choice,rt=t)

end


"""
simulate(rng::AbstractRNG, model::AbstractstDDM; Δt)

Returns a matrix containing evidence samples of the stDDM decision process. In the matrix, rows
represent samples of evidence per time step and columns represent different accumulators.

# Arguments

- `rng`: a random number generator
- `model::AbstractstDDM`: a starting-time diffusion decision model diffusion model object
- `Δt`: time-step for simulation
"""
function simulate(rng::AbstractRNG, model::AbstractstDDM; Δt = .001)
(;ν, σ, s, z, η, ρ, α, τ) = model

x = α * z
t = 0.0
evidence = [x]
time_steps = [t]
cont = 1
start_step = abs(Int(s / Δt))

Ρ = [1.0 ρ; ρ 1.0]
Σ = cor2cov(Ρ,η)
while (x < α) && (x > 0)
t += Δt

δ1 = cont ≤ start_step && s > 0 ? 0.0 : 1.0
δ2 = cont ≤ start_step && s < 0 ? 0.0 : 1.0

increment = rand(rng, MvNormal([ν[1], ν[2]], Σ))
noise = rand(rng, Normal(0, σ)) * √(Δt)

x += (increment[1] * δ1 + increment[2] * δ2) * Δt + noise

push!(evidence, x)
push!(time_steps, t)
cont += 1
end

return time_steps,evidence
end
Loading