diff --git a/Project.toml b/Project.toml index 16867755..282f2055 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "SequentialSamplingModels" uuid = "0e71a2a6-2b30-4447-8742-d083a85e82d1" authors = ["itsdfish"] -version = "0.2.0" +version = "0.3.0" [deps] ConcreteStructs = "2569d6c7-a4a2-43d3-a901-331e8e4be471" diff --git a/src/AttentionalDiffusion.jl b/src/AttentionalDiffusion.jl index 75a1496e..e424bb9e 100644 --- a/src/AttentionalDiffusion.jl +++ b/src/AttentionalDiffusion.jl @@ -169,8 +169,8 @@ the mean drift rate for the attribute 1 of alternative 1 is given by: - `ν₁₁=5.0`: relative decision value for alternative 1, attribute 1 - `ν₁₂=4.0`: relative decision value for alternative 1, attribute 2 -- `ν₂₁`=5.0: relative decision value for alternative 2, attribute 1 -- `ν₂₂`4.0: relative decision value for alternative 2, attribute 2 +- `ν₂₁=5.0`: relative decision value for alternative 2, attribute 1 +- `ν₂₂=4.0`: relative decision value for alternative 2, attribute 2 - `α=1.0`: evidence threshold - `z=0.0`: initial evidence - `θ=.3`: bias away from unattended alternative (lower indicates more bias) diff --git a/src/DiffusionRace.jl b/src/DiffusionRace.jl index 9050baf5..eef3a0e8 100644 --- a/src/DiffusionRace.jl +++ b/src/DiffusionRace.jl @@ -113,6 +113,8 @@ end Broadcast.broadcastable(x::DiffusionRace) = Ref(x) +loglikelihood(d::DiffusionRace, data) = sum(logpdf.(d, data...)) + DiffusionRace(;ν, k, A, θ) = DiffusionRace(ν, k, A, θ) function rand(dist::DiffusionRace) @@ -124,7 +126,14 @@ function rand(dist::DiffusionRace) return resp,rt end -rand(dist::DiffusionRace, N::Int) = [rand(dist) for i in 1:N] +function rand(d::DiffusionRace, N::Int) + choice = fill(0, N) + rt = fill(0.0, N) + for i in 1:N + choice[i],rt[i] = rand(d) + end + return (choice=choice,rt=rt) +end function logpdf(d::DiffusionRace, r::Int, rt::Float64) (;ν, k, A, θ) = d diff --git a/src/LBA.jl b/src/LBA.jl index ac5625d8..274384b4 100644 --- a/src/LBA.jl +++ b/src/LBA.jl @@ -36,6 +36,8 @@ end Base.broadcastable(x::LBA) = Ref(x) +loglikelihood(d::LBA, data) = sum(logpdf.(d, data...)) + LBA(;τ, A, k, ν, σ=1.0) = LBA(ν, A, k, τ, σ) function select_winner(dt) diff --git a/src/LogNormalRace.jl b/src/LogNormalRace.jl index bd92cc31..50769920 100644 --- a/src/LogNormalRace.jl +++ b/src/LogNormalRace.jl @@ -32,6 +32,8 @@ end Broadcast.broadcastable(x::LNR) = Ref(x) +loglikelihood(d::LNR, data) = sum(logpdf.(d, data...)) + LNR(;μ, σ, ϕ) = LNR(μ, σ, ϕ) function rand(dist::LNR) @@ -41,7 +43,14 @@ function rand(dist::LNR) return resp,rt end -rand(dist::LNR, N::Int) = [rand(dist) for i in 1:N] +function rand(d::LNR, N::Int) + choice = fill(0, N) + rt = fill(0.0, N) + for i in 1:N + choice[i],rt[i] = rand(d) + end + return (choice=choice,rt=rt) +end function logpdf(d::LNR, r::Int, t::Float64) (;μ,σ,ϕ) = d diff --git a/src/Wald.jl b/src/Wald.jl index 6358f47b..f6dd6313 100644 --- a/src/Wald.jl +++ b/src/Wald.jl @@ -1,5 +1,7 @@ abstract type AbstractWald <: SequentialSamplingModel end +loglikelihood(d::AbstractWald, data::AbstractArray{T,1}) where {T} = sum(logpdf.(d, data)) + """ # Wald Constructor diff --git a/temp/sandbox.jl b/temp/sandbox.jl index a851cc59..095e6938 100644 --- a/temp/sandbox.jl +++ b/temp/sandbox.jl @@ -7,18 +7,20 @@ using Revise Pkg.activate("../") using SequentialSamplingModels using StatsBase +using SequentialSamplingModels: update +using SequentialSamplingModels: _rand_state! -model = maaDDM(ν₁₁ = 1.0, - ν₁₂ = 1.0, - ν₂₁ = 2.0, - ν₂₂ = 2.0, +model = maaDDM(ν₁₁ = 6.0, + ν₁₂ = 5.0, + ν₂₁ = 4.0, + ν₂₂ = 5.0, α = 1.0, z = 0.0, - θ = 0.0, - ϕ = 1.0, - ω = 1.0, - σ = .05, - Δ = .005) + θ = 0.3, + ϕ = 0.60, + ω = .50, + σ = .025, + Δ = .0004) mutable struct Transition state::Int @@ -46,9 +48,128 @@ mutable struct Transition # 2. alternative 1, attribute 2 # 3. alternative 2, attribute 1 # 4. alternative 2, attribute 2 - tmat = Transition([.98 .015 .0025 .0025; - .015 .98 .0025 .0025; - .0025 .0025 .98 .015; - .0025 .0025 .015 .98]) + tmat = Transition([.98 .02; + .02 .98]) - rts = rand(model, 1000, attend, tmat) \ No newline at end of file +rts = rand(model, 10_000, attend, tmat) + +using Distributions +using Plots + +sim_data = rand(Normal(0, 1), 10_000) + +histogram(sim_data, norm=true, grid=false, leg=false) + +x = range(-3, 3, length=100) +y = pdf.(Normal(0, 1), x) +plot!(x, y, color=:black, linewidth=2) + +using KernelDensity +using Interpolations + +sim_data = rand(MvNormal([0,0],[1 0;0 1]), 10_000)' +kd = kde(sim_data) +est_dist = InterpKDE(kd) + +x = range(-3, 3, length=10) +v = mapreduce(y -> [y...], hcat, Base.product(x,x)) +est_pdfs = [est_dist.itp(col...) for col in eachcol(v)] + + + +using Revise, ProbabilityTheoryPlusNoiseModel, Random +using InterferenceEffectUtilities +Random.seed!(3363) + +ds = range(0, .5, length=50) +ns = fill(100, 3) + +int_preds = map(d -> begin + dist = ObjectivePTN(; d) + preds = compute_preds(dist) + df = interference_effects(preds) + df.d .= d + return df + end, ds) + +df = vcat(int_preds...) + +pyplot() + +@df df plot(:d, + :interference, + group = :condition, + ylabel = "interference effect", + xlabel = "d", + grid = false, + xaxis = font(5), + yaxis = font(5), + legendfontsize = 4, + linewidth = .75, + ylims = (-.04,.04), + size = (240,120), + dpi = 300) + +hline!([0.0], color = :black, linestyle = :dash, linewidth=.75, label=false) + + + +function full(pA, pAgBC, pAgnBC, pBC, d) + v1 = 1 - 2 * d + t1 = v1 * pAgBC + d + t2 = (1 - d) * pBC + t3 = v1 * pAgnBC + d + t4 = d * (1 - pBC) + t5 = v1 * pBC + d + return (t1 * t2 + t3 * t4) / t5 +end + + + +function compute_a_given_bc(pA, pBC, pABC, d) + v1 = 1 - 2 * d + t1 = v1 * (pABC - d * (pA - 2 * pABC)) + t2 = d * (v1 * pBC + d) + t3 = v1 * pBC + d + return (t1 + t2) / t3 +end + +# function compute_a_given_bc1(pA, pBC, pABC, d) +# v1 = 1 - 2 * d +# t1 = v1 * (pABC - d * (pA - 2 * pABC + pBC)) + d^2 +# t2 = v1 * pBC + d +# return t1 / t2 +# end + +d = .1 +dist = ObjectivePTN(; d) +pA = sum(dist.probs[1,:,:]) +pB = sum(dist.probs[:,1,:]) +pBC = sum(dist.probs[:,1,1]) +pABC = dist.probs[1,1,1] +pAgBC = dist.probs[1,1,1] / sum(dist.probs[:,1,1]) +pAgnBC = (sum(dist.probs[1,:,:]) - dist.probs[1,1,1])/ (1 - sum(dist.probs[:,1,1])) +compute_a_given_bc(pA, pBC, pABC, d) +full(pA, pAgBC, pAgnBC, pBC, d) +#conditional_prob(p_A, p_B, p_AB, d) +# probability attack given b-type and bad +ProbabilityTheoryPlusNoiseModel.compute_a_given_b(pA, pBC, pABC, d) + + +((1 - 2 * d) * pAgBC + d) * (1 - d) * pBC + ((1 - 2 * d) * pAgnBC + d) * d * (1 - pBC) + +# (1 - d) * pBC * (1 - 2 * d) * pAgBC + d * (1 - d) * pBC + d * (1 - pBC) * (1 - 2 * d) * pAgnBC + d * d * (1 - pBC) + + +(1 - d) * (1 - 2 * d) * pABC + d * (1 - d) * pBC + d * (1 - 2 * d) * (pA - pABC) + d^2 * (1 - pBC) + +# group + +(1 - 2 * d) * ((1 - d) * pABC + d * (pA - pABC)) + d *((1 - d) * pBC + d * (1 - pBC)) + +# distribute +(1 - 2 * d) * (pABC - d * pABC + d * pA - d * pABC) + d * (pBC - d * pBC + d - d * pBC) + +(1 - 2 * d) * (pABC + d * (pA - 2 * pABC)) + d *((1 - 2 * d) * pBC + d) + +(1 - 2 * d) * ((pABC + d * (pA - 2 * pABC)) + d * pBC) + d^2 \ No newline at end of file diff --git a/test/attentional_diffusion_tests.jl b/test/attentional_diffusion_tests.jl new file mode 100644 index 00000000..ce799a39 --- /dev/null +++ b/test/attentional_diffusion_tests.jl @@ -0,0 +1,46 @@ +@safetestset "Attentional Diffusion" begin + @safetestset "aDDM" begin + using Test, SequentialSamplingModels, StatsBase, Random + Random.seed!(5511) + + mutable struct Transition + state::Int + n::Int + mat::Array{Float64,2} + end + + function Transition(mat) + n = size(mat,1) + state = rand(1:n) + return Transition(state, n, mat) + end + + function attend(t) + w = t.mat[t.state,:] + next_state = sample(1:t.n, Weights(w)) + t.state = next_state + return next_state + end + + model = aDDM(;ν1=5.0, ν2=4.0) + + tmat = Transition([.98 .015 .005; + .015 .98 .005; + .45 .45 .1]) + + rts1 = rand(model, 1000, x -> attend(x), tmat) + n1,n2 = length.(rts1) + @test n1 > n2 + + model = aDDM(;ν1=4.0, ν2=5.0) + rts2 = rand(model, 1000, x -> attend(x), tmat) + n1,n2 = length.(rts2) + @test n1 < n2 + + μ_rts1 = mean(vcat(rts1...)) + model = aDDM(;ν1=5.0, ν2=5.0) + rts3 = rand(model, 1000, x -> attend(x), tmat) + μ_rts3 = mean(vcat(rts3...)) + @test μ_rts1 < μ_rts3 + end +end \ No newline at end of file diff --git a/test/lba_tests.jl b/test/lba_tests.jl new file mode 100644 index 00000000..8e34ff91 --- /dev/null +++ b/test/lba_tests.jl @@ -0,0 +1,64 @@ +@safetestset "LBA Tests" begin + @safetestset "LBA Test1" begin + using SequentialSamplingModels, Test, KernelDensity, Random + Random.seed!(10542) + + dist = LBA(ν=[3.0,2.0], A = .8, k = .2, τ = .3) + choice,rt = rand(dist, 10^5) + rt1 = rt[choice .== 1] + p1 = mean(x -> x == 1, choice) + p2 = 1 - p1 + approx_pdf = kde(rt1) + x = .2:.01:1.5 + y′ = pdf(approx_pdf, x) * p1 + y = pdf.(dist, (1,), x) + @test y′ ≈ y rtol = .03 + + rt2 = rt[choice .== 2] + approx_pdf = kde(rt2) + x = .2:.01:1.5 + y′ = pdf(approx_pdf, x) * p2 + y = pdf.(dist, (2,), x) + @test y′ ≈ y rtol = .03 + end + + @safetestset "LBA Test2" begin + using SequentialSamplingModels, Test, KernelDensity, Random + Random.seed!(8521) + + # note for some values, tests will fail + # this is because kde is sensitive to outliers + # density overlay on histograms are valid + dist = LBA(ν=[2.0,2.7], A = .6, k = .26, τ = .4) + choice,rt = rand(dist, 10^5) + rt1 = rt[choice .== 1] + p1 = mean(x -> x == 1, choice) + p2 = 1 - p1 + approx_pdf = kde(rt1) + x = .2:.01:1.5 + y′ = pdf(approx_pdf, x) * p1 + y = pdf.(dist, (1,), x) + @test y′ ≈ y rtol = .03 + + rt2 = rt[choice .== 2] + approx_pdf = kde(rt2) + x = .2:.01:1.5 + y′ = pdf(approx_pdf, x) * p2 + y = pdf.(dist, (2,), x) + @test y′ ≈ y rtol = .03 + end + + @safetestset "LBA loglikelihood" begin + using SequentialSamplingModels + using Test + using Random + Random.seed!(8521) + + dist = LBA(ν=[2.0,2.7], A = .6, k = .26, τ = .4) + choice,rt = rand(dist, 10) + + sum_logpdf = logpdf.(dist, choice, rt) |> sum + loglike = loglikelihood(dist, (choice, rt)) + @test sum_logpdf ≈ loglike + end +end \ No newline at end of file diff --git a/test/log_normal_race_tests.jl b/test/log_normal_race_tests.jl new file mode 100644 index 00000000..9c33ba8b --- /dev/null +++ b/test/log_normal_race_tests.jl @@ -0,0 +1,86 @@ +@safetestset "LogNormal Race Tests" begin + @safetestset "pdf" begin + using SequentialSamplingModels, Test, Random, KernelDensity, Distributions + Random.seed!(54154) + d1 = LNR(;μ=[1.0], σ=1.0, ϕ=.1) + v1 = .3 + p1 = pdf(d1, 1, v1) + p2 = pdf(LogNormal(1, 1), v1-.1) + @test p1 ≈ p2 + d2 = LNR(;μ=[1.0,0.0],σ=1.0,ϕ=.1) + d3 = LNR(;μ=[1.0,0.0,0.0], σ=1.0, ϕ=.1) + p1 = pdf(d2, 1, v1) + p2 = pdf(d3, 1 ,v1) + @test p1 > p2 + @test p1 ≈ pdf(LogNormal(1, 1), v1-.1)*(1-cdf(LogNormal(0, 1), v1-.1)) + + m1,m2=-2,-1 + σ = .9 + ϕ = 0.0 + d = LNR(μ=[m1,m2], σ=σ, ϕ=ϕ) + choice,rts = rand(d, 10^4) + x = range(m1*.8, m1*1.2, length=100) + y = map(x -> sum(logpdf.(LNR(μ=[x,m2], σ=σ, ϕ=ϕ), choice, rts)), x) + mv,mi = findmax(y) + @test m1 ≈ x[mi] atol = .05 + + x = range(m2*.8, m2*1.2, length=100) + y = map(x -> sum(logpdf.(LNR(μ=[m1,x], σ=σ, ϕ=ϕ), choice, rts)), x) + mv,mi = findmax(y) + @test m2 ≈ x[mi] atol = .05 + + x = range(σ*.8, σ*1.2, length=100) + y = map(x -> sum(logpdf.(LNR(μ=[m1,m2], σ=x, ϕ=ϕ), choice, rts)), x) + mv,mi = findmax(y) + @test σ ≈ x[mi] atol = .05 + + x = range(ϕ*.8, ϕ*1.2, length=100) + y = map(x -> sum(logpdf.(LNR(μ=[m1,m2], σ=σ, ϕ=x), choice, rts)), x) + mv,mi = findmax(y) + @test ϕ ≈ x[mi] atol = .0005 + + d = LNR(μ=[m1,m2], σ=σ, ϕ=ϕ) + choice,rts = rand(d, 10^4) + y1 = logpdf.(d, choice, rts) + y2 = log.(pdf.(d, choice, rts)) + @test y1 ≈ y2 atol = .00001 + + d = LNR(μ=[1.,.5], σ=.4, ϕ=.5) + choice,rts = rand(d, 10^4) + y1 = logpdf.(d, choice, rts) + y2 = log.(pdf.(d, choice, rts)) + @test y1 ≈ y2 atol = .00001 + + dist = LNR(μ=[-1.5,-.9], σ=.5, ϕ=.3) + choice,rts = rand(dist, 10^5) + rts1 = rts[choice .== 1] + p1 = mean(choice .== 1) + p2 = 1 - p1 + approx_pdf = kde(rts1) + x = .2:.01:1.5 + y′ = pdf(approx_pdf, x) * p1 + y = pdf.(dist, (1,), x) + @test y′ ≈ y rtol = .03 + + rts2 = rts[choice .== 2] + approx_pdf = kde(rts2) + x = .2:.01:1.5 + y′ = pdf(approx_pdf, x) * p2 + y = pdf.(dist, (2,), x) + @test y′ ≈ y rtol = .03 + end + + @safetestset "LNR loglikelihood" begin + using SequentialSamplingModels + using Test + using Random + Random.seed!(8521) + + dist = LNR(;μ=[1.0,.5], σ=1.0, ϕ=.1) + choice,rt = rand(dist, 10) + + sum_logpdf = logpdf.(dist, choice, rt) |> sum + loglike = loglikelihood(dist, (choice, rt)) + @test sum_logpdf ≈ loglike + end +end \ No newline at end of file diff --git a/test/multiattribute_attentional_diffusion_tests.jl b/test/multiattribute_attentional_diffusion_tests.jl new file mode 100644 index 00000000..819e87b2 --- /dev/null +++ b/test/multiattribute_attentional_diffusion_tests.jl @@ -0,0 +1,161 @@ +@safetestset "maaDDM" begin + @safetestset "update1" begin + using Test, SequentialSamplingModels + using SequentialSamplingModels: update + + model = maaDDM(ν₁₁ = 1.0, + ν₁₂ = 2.0, + ν₂₁ = 2.0, + ν₂₂ = 3.0, + α = 1.0, + z = 0.0, + θ = .5, + ϕ = .50, + ω = .00, + σ = eps(), + Δ = 1.0) + + Δ1s = map(x -> update(model, x), 1:4) + @test Δ1s[1] > 0 + @test Δ1s[2] > 0 + @test Δ1s[3] < 0 + @test Δ1s[4] < 0 + + model = maaDDM(ν₁₁ = 100.0, + ν₁₂ = 2.0, + ν₂₁ = 2.0, + ν₂₂ = 3.0, + α = 1.0, + z = 0.0, + θ = .5, + ϕ = .50, + ω = .00, + σ = eps(), + Δ = 1.0) + + Δ2s = map(x -> update(model, x), 1:4) + @test Δ1s ≈ Δ2s atol = 1e-5 + end + + @safetestset "update2" begin + using Test, SequentialSamplingModels + using SequentialSamplingModels: update + + model = maaDDM(ν₁₁ = 1.0, + ν₁₂ = 2.0, + ν₂₁ = 2.0, + ν₂₂ = 3.0, + α = 1.0, + z = 0.0, + θ = .5, + ϕ = .50, + ω = .00, + σ = eps(), + Δ = 1.0) + + Δs = map(x -> update(model, x), 1:4) + + @test Δs[1] > 0 + @test Δs[2] > 0 + @test Δs[3] < 0 + @test Δs[4] < 0 + end + + @safetestset "update3" begin + using Test, SequentialSamplingModels + using SequentialSamplingModels: update + + model = maaDDM(ν₁₁ = 1.0, + ν₁₂ = 1.0, + ν₂₁ = 2.0, + ν₂₂ = 2.0, + α = 1.0, + z = 0.0, + θ = 1.0, + ϕ = .50, + ω = .50, + σ = eps(), + Δ = 1.0) + + Δs = map(x -> update(model, x), 1:4) + @test all(Δs .≈ -.75) + end + + @safetestset "update4" begin + using Test, SequentialSamplingModels + using SequentialSamplingModels: update + + model = maaDDM(ν₁₁ = 1.0, + ν₁₂ = 1.0, + ν₂₁ = 2.0, + ν₂₂ = 2.0, + α = 1.0, + z = 0.0, + θ = 1.0, + ϕ = 1.0, + ω = 1.0, + σ = eps(), + Δ = 1.0) + + Δ1s = map(x -> update(model, x), 1:4) + + model = maaDDM(ν₁₁ = 1.0, + ν₁₂ = 1.0, + ν₂₁ = 2.0, + ν₂₂ = 2.0, + α = 1.0, + z = 0.0, + θ = 1.0, + ϕ = 1.0, + ω = 0.0, + σ = eps(), + Δ = 1.0) + + Δ2s = map(x -> update(model, x), 1:4) + + @test all(Δ1s .≈ -1.0) + @test all(Δ2s .≈ -1.0) + end + + @safetestset "update5" begin + using Test, SequentialSamplingModels + using SequentialSamplingModels: update + + model = maaDDM(ν₁₁ = 1.0, + ν₁₂ = 1.0, + ν₂₁ = 2.0, + ν₂₂ = 2.0, + α = 1.0, + z = 0.0, + θ = 1.0, + ϕ = 0.0, + ω = 1.0, + σ = eps(), + Δ = 1.0) + + Δ2s = map(x -> update(model, x), 1:4) + + @test Δ2s ≈ [-1,0,-1,0] + end + + @safetestset "update6" begin + using Test, SequentialSamplingModels + using SequentialSamplingModels: update + + model = maaDDM(ν₁₁ = 1.0, + ν₁₂ = 1.0, + ν₂₁ = 2.0, + ν₂₂ = 2.0, + α = 1.0, + z = 0.0, + θ = 0.0, + ϕ = 1.0, + ω = 1.0, + σ = eps(), + Δ = 1.0) + + Δ2s = map(x -> update(model, x), 1:4) + + @test Δ2s ≈ [1,1,-2,-2] + end +end diff --git a/test/racing_diffusion_tests.jl b/test/racing_diffusion_tests.jl new file mode 100644 index 00000000..2e23d48a --- /dev/null +++ b/test/racing_diffusion_tests.jl @@ -0,0 +1,133 @@ +@safetestset "Racing Diffusion Model" begin + @safetestset "pdf" begin + using SequentialSamplingModels, Test, KernelDensity, QuadGK, Random + using Interpolations, Distributions + import SequentialSamplingModels: WaldA + kernel_dist(::Type{Epanechnikov}, w::Float64) = Epanechnikov(0.0, w) + kernel(data) = kde(data; kernel=Epanechnikov) + Random.seed!(741) + + dist = WaldA(ν=.5, k=.3, A=.7, θ=.2) + rts = map(_ -> rand(dist), 1:10^6) + approx_pdf = kernel(rts) + x = .201:.01:2.5 + y′ = pdf(approx_pdf, x) + y = pdf.(dist, x) + @test mean(abs.(y .- y′)) < .02 + #@test std(abs.(y .- y′)) < .04 + + p′ = quadgk(x -> pdf(dist, x), .2, Inf)[1] + @test p′ ≈ 1 rtol = .001 + + p = cdf(dist, .25) + p′ = quadgk(x -> pdf(dist, x), .2, .25)[1] + @test p′ ≈ p rtol = .001 + @test p ≈ mean(rts .< .25) rtol = .01 + + p = cdf(dist, .5) + p′ = quadgk(x -> pdf(dist, x), .2, .5)[1] + @test p′ ≈ p rtol = .001 + @test p ≈ mean(rts .< .5) rtol = .01 + + p = cdf(dist, .6) - cdf(dist, .3) + p′ = quadgk(x -> pdf(dist, x), .3, .6)[1] + @test p′ ≈ p rtol = .001 + @test p ≈ mean((rts .< .6 ).& (rts .> .3)) rtol = .01 + + + dist = WaldA(ν=1.0, k=.3, A=1.0, θ=.2) + rts = map(_->rand(dist), 1:10^6) + approx_pdf = kernel(rts) + x = .201:.01:2.5 + y′ = pdf(approx_pdf, x) + y = pdf.(dist, x) + @test mean(abs.(y .- y′)) < .02 + # @test std(abs.(y .- y′)) < .04 + + p′ = quadgk(x -> pdf(dist, x), .2, Inf)[1] + @test p′ ≈ 1 rtol = .001 + + p = cdf(dist, .25) + p′ = quadgk(x -> pdf(dist, x), .2, .25)[1] + @test p′ ≈ p rtol = .001 + @test p ≈ mean(rts .< .25) rtol = .01 + + p = cdf(dist, .5) + p′ = quadgk(x -> pdf(dist, x), .2, .5)[1] + @test p′ ≈ p rtol = .001 + @test p ≈ mean(rts .< .5) rtol = .01 + + p = cdf(dist, 1.0) - cdf(dist, .6) + p′ = quadgk(x -> pdf(dist, x), .6, 1.0)[1] + @test p′ ≈ p rtol = .001 + @test p ≈ mean((rts .< 1).& (rts .> .6)) rtol = .01 + + p = cdf(dist, 1.5) - cdf(dist, 1.4) + p′ = quadgk(x -> pdf(dist, x), 1.4, 1.5)[1] + @test p′ ≈ p rtol = .001 + @test p ≈ mean((rts .< 1.5).& (rts .> 1.4)) rtol = .02 + + dist = DiffusionRace(;ν=[1.0,.5], k=0.5, A=1.0, θ=.2) + choice,rts = rand(dist, 10^6) + rt1 = rts[choice .== 1] + p1 = mean(choice .== 1) + p2 = 1 - p1 + # approx_pdf = kernel(rt1) + # x = .201:.01:2.5 + # y′ = pdf(approx_pdf, x) * p1 + # y = pdf.(dist, (1,), x) + # @test y′ ≈ y rtol = .03 + + rt2 = rts[choice .== 2] + approx_pdf = kernel(rt2) + # x = .201:.01:1.5 + # y′ = pdf(approx_pdf, x) * p2 + # y = pdf.(dist, (2,), x) + # @test y′ ≈ y rtol = .03 + + p′ = quadgk(x -> pdf(dist, 1, x), .2, Inf)[1] + @test p′ ≈ p1 rtol = .001 + + p = quadgk(x -> pdf(dist, 1, x), .2, .3)[1] + @test p ≈ mean(rt1 .< .3) * p1 atol = .01 + + p = quadgk(x -> pdf(dist, 1, x), .2, .5)[1] + @test p ≈ mean(rt1 .< .5) * p1 atol = .01 + + p = quadgk(x -> pdf(dist, 1, x), .2, 1)[1] - quadgk(x -> pdf(dist, 1, x), .2, .6)[1] + @test p ≈ mean((rt1 .< 1) .& (rt1 .> .6)) * p1 atol = .01 + + p = quadgk(x -> pdf(dist, 1, x), .2, 1.5)[1] - quadgk(x -> pdf(dist, 1, x), .2, 1.4)[1] + @test p ≈ mean((rt1 .< 1.5).& (rt1 .> 1.4)) atol = .01 + + + p′ = quadgk(x -> pdf(dist, 2, x), .2, Inf)[1] + @test p′ ≈ p2 rtol = .001 + + p = quadgk(x -> pdf(dist, 2, x), .2, .3)[1] + @test p ≈ mean(rt2 .< .3) * p2 atol = .01 + + p = quadgk(x -> pdf(dist, 2, x), .2, .5)[1] + @test p ≈ mean(rt2 .< .5) * p2 atol = .02 + + p = quadgk(x -> pdf(dist, 2, x), .2, 1)[1] - quadgk(x -> pdf(dist, 2, x), .2, .6)[1] + @test p ≈ mean((rt2 .< 1) .& (rt2 .> .6)) * p2 atol = .01 + + p = quadgk(x -> pdf(dist, 2, x), .2, 1.5)[1] - quadgk(x -> pdf(dist, 2, x), .2, 1.4)[1] + @test p ≈ mean((rt2 .< 1.5).& (rt2 .> 1.4)) * p2 atol = .01 + end + + @safetestset "loglikelihood" begin + using SequentialSamplingModels + using Test + using Random + Random.seed!(655) + + dist = DiffusionRace(;ν=[1.0,.5], k=0.5, A=1.0, θ=.2) + choice,rt = rand(dist, 10) + + sum_logpdf = logpdf.(dist, choice, rt) |> sum + loglike = loglikelihood(dist, (choice, rt)) + @test sum_logpdf ≈ loglike + end +end \ No newline at end of file diff --git a/test/runtests.jl b/test/runtests.jl index 5f796297..e10c37e8 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,503 +1,5 @@ using SafeTestsets -@safetestset "Wald" begin - using Test, SequentialSamplingModels, KernelDensity, Random - Random.seed!(22158) - d = Wald(2, 1, .1) - @test mean(d) ≈ (1/2) + .1 atol = 1e-5 +files = filter(f -> f ≠ "runtests.jl", readdir()) - function simulate(υ, α, θ) - noise = 1.0 - #Time Step - Δt = .0005 - #Evidence step - Δe = noise * sqrt(Δt) - e = 0.0 - t = θ - p = .5 * (1 + υ * sqrt(Δt) / noise) - while (e < α) - t += Δt - e += rand() ≤ p ? Δe : -Δe - end - return t - end - rts = map(_ -> simulate(3, 1, .2), 1:10^5) - approx_pdf = kde(rts) - x = .2:.01:1.5 - y′ = pdf(approx_pdf, x) - y = pdf.(Wald(3,1,.2), x) - @test y′ ≈ y rtol = .03 - @test mean(rts) ≈ mean(Wald(3,1,.2)) atol = 5e-3 - @test std(rts) ≈ std(Wald(3,1,.2)) atol = 1e-3 -end - -@safetestset "Wald Mixture" begin - using Test, SequentialSamplingModels, KernelDensity, Random - Random.seed!(22198) - d = WaldMixture(2, .2, 1, .1) - @test mean(d) ≈ (1/2) + .1 atol = 1e-5 - rts = rand(d, 100000) - approx_pdf = kde(rts) - x = .2:.01:1.5 - y′ = pdf(approx_pdf, x) - y = pdf.(d, x) - @test y′ ≈ y rtol = .03 - @test mean(rts) ≈ mean(d) atol = 5e-3 - - y′ = @. logpdf(d, x) |> exp - @test y′ ≈ y -end - -@safetestset "LogNormal Race Tests" begin - using SequentialSamplingModels, Test, Random, KernelDensity, Distributions - Random.seed!(54154) - d1 = LNR(;μ=[1.0], σ=1.0, ϕ=.1) - v1 = .3 - p1 = pdf(d1, 1, v1) - p2 = pdf(LogNormal(1, 1), v1-.1) - @test p1 ≈ p2 - d2 = LNR(;μ=[1.0,0.0],σ=1.0,ϕ=.1) - d3 = LNR(;μ=[1.0,0.0,0.0], σ=1.0, ϕ=.1) - p1 = pdf(d2, 1, v1) - p2 = pdf(d3, 1 ,v1) - @test p1 > p2 - @test p1 ≈ pdf(LogNormal(1, 1), v1-.1)*(1-cdf(LogNormal(0, 1), v1-.1)) - - m1,m2=-2,-1 - σ = .9 - ϕ = 0.0 - d = LNR(μ=[m1,m2], σ=σ, ϕ=ϕ) - data = rand(d, 10^4) - x = range(m1*.8, m1*1.2, length=100) - y = map(x->sum(logpdf.(LNR(μ=[x,m2], σ=σ, ϕ=ϕ), data)), x) - mv,mi = findmax(y) - @test m1 ≈ x[mi] atol = .05 - - x = range(m2*.8, m2*1.2, length=100) - y = map(x->sum(logpdf.(LNR(μ=[m1,x], σ=σ, ϕ=ϕ), data)), x) - mv,mi = findmax(y) - @test m2 ≈ x[mi] atol = .05 - - x = range(σ*.8, σ*1.2, length=100) - y = map(x->sum(logpdf.(LNR(μ=[m1,m2], σ=x, ϕ=ϕ), data)), x) - mv,mi = findmax(y) - @test σ ≈ x[mi] atol = .05 - - x = range(ϕ*.8, ϕ*1.2, length=100) - y = map(x->sum(logpdf.(LNR(μ=[m1,m2], σ=σ, ϕ=x), data)), x) - mv,mi = findmax(y) - @test ϕ ≈ x[mi] atol = .0005 - - d = LNR(μ=[m1,m2], σ=σ, ϕ=ϕ) - data = rand(d, 10^4) - y1 = map(x->logpdf(d, x), data) - y2 = map(x->log(pdf(d, x)), data) - @test y1 ≈ y2 atol = .00001 - - d = LNR(μ=[1.,.5], σ=.4, ϕ=.5) - data = rand(d, 10^4) - y1 = map(x->logpdf(d, x), data) - y2 = map(x->log(pdf(d, x)), data) - @test y1 ≈ y2 atol = .00001 - - dist = LNR(μ=[-1.5,-.9], σ=.5, ϕ=.3) - data = rand(dist, 10^5) - data1 = filter(x->x[1] == 1, data) - p1 = mean(x->x[1] == 1, data) - p2 = 1 - p1 - rt1 = map(x->x[2], data1) - approx_pdf = kde(rt1) - x = .2:.01:1.5 - y′ = pdf(approx_pdf, x)*p1 - y = pdf.(dist, (1,), x) - @test y′ ≈ y rtol = .03 - - data2 = filter(x->x[1] == 2, data) - rt2 = map(x->x[2], data2) - approx_pdf = kde(rt2) - x = .2:.01:1.5 - y′ = pdf(approx_pdf, x)*p2 - y = pdf.(dist, (2,), x) - @test y′ ≈ y rtol = .03 -end - -@safetestset "LBA Tests" begin - @safetestset "LBA Test1" begin - using SequentialSamplingModels, Test, KernelDensity, Random - Random.seed!(10542) - - dist = LBA(ν=[3.0,2.0], A = .8, k = .2, τ = .3) - choice,rt = rand(dist, 10^5) - rt1 = rt[choice .== 1] - p1 = mean(x -> x == 1, choice) - p2 = 1 - p1 - approx_pdf = kde(rt1) - x = .2:.01:1.5 - y′ = pdf(approx_pdf, x) * p1 - y = pdf.(dist, (1,), x) - @test y′ ≈ y rtol = .03 - - rt2 = rt[choice .== 2] - approx_pdf = kde(rt2) - x = .2:.01:1.5 - y′ = pdf(approx_pdf, x) * p2 - y = pdf.(dist, (2,), x) - @test y′ ≈ y rtol = .03 - end - - @safetestset "LBA Test2" begin - using SequentialSamplingModels, Test, KernelDensity, Random - Random.seed!(8521) - - # note for some values, tests will fail - # this is because kde is sensitive to outliers - # density overlay on histograms are valid - dist = LBA(ν=[2.0,2.7], A = .6, k = .26, τ = .4) - choice,rt = rand(dist, 10^5) - rt1 = rt[choice .== 1] - p1 = mean(x -> x == 1, choice) - p2 = 1 - p1 - approx_pdf = kde(rt1) - x = .2:.01:1.5 - y′ = pdf(approx_pdf, x) * p1 - y = pdf.(dist, (1,), x) - @test y′ ≈ y rtol = .03 - - rt2 = rt[choice .== 2] - approx_pdf = kde(rt2) - x = .2:.01:1.5 - y′ = pdf(approx_pdf, x) * p2 - y = pdf.(dist, (2,), x) - @test y′ ≈ y rtol = .03 - end -end - -@safetestset "Racing Diffusion Model" begin - - using SequentialSamplingModels, Test, KernelDensity, QuadGK, Random - using Interpolations, Distributions - import SequentialSamplingModels: WaldA - kernel_dist(::Type{Epanechnikov}, w::Float64) = Epanechnikov(0.0, w) - kernel(data) = kde(data; kernel=Epanechnikov) - Random.seed!(741) - - dist = WaldA(ν=.5, k=.3, A=.7, θ=.2) - rts = map(_->rand(dist), 1:10^6) - approx_pdf = kernel(rts) - x = .201:.01:2.5 - y′ = pdf(approx_pdf, x) - y = pdf.(dist, x) - @test mean(abs.(y .- y′)) < .02 - #@test std(abs.(y .- y′)) < .04 - - p′ = quadgk(x->pdf(dist, x), .2, Inf)[1] - @test p′ ≈ 1 rtol = .001 - - p = cdf(dist, .25) - p′ = quadgk(x->pdf(dist, x), .2, .25)[1] - @test p′ ≈ p rtol = .001 - @test p ≈ mean(rts .< .25) rtol = .01 - - p = cdf(dist, .5) - p′ = quadgk(x->pdf(dist, x), .2, .5)[1] - @test p′ ≈ p rtol = .001 - @test p ≈ mean(rts .< .5) rtol = .01 - - p = cdf(dist, .6) - cdf(dist, .3) - p′ = quadgk(x->pdf(dist, x), .3, .6)[1] - @test p′ ≈ p rtol = .001 - @test p ≈ mean((rts .< .6 ).& (rts .> .3)) rtol = .01 - - - dist = WaldA(ν=1.0, k=.3, A=1.0, θ=.2) - rts = map(_->rand(dist), 1:10^6) - approx_pdf = kernel(rts) - x = .201:.01:2.5 - y′ = pdf(approx_pdf, x) - y = pdf.(dist, x) - @test mean(abs.(y .- y′)) < .02 - # @test std(abs.(y .- y′)) < .04 - - p′ = quadgk(x->pdf(dist, x), .2, Inf)[1] - @test p′ ≈ 1 rtol = .001 - - p = cdf(dist, .25) - p′ = quadgk(x->pdf(dist, x), .2, .25)[1] - @test p′ ≈ p rtol = .001 - @test p ≈ mean(rts .< .25) rtol = .01 - - p = cdf(dist, .5) - p′ = quadgk(x->pdf(dist, x), .2, .5)[1] - @test p′ ≈ p rtol = .001 - @test p ≈ mean(rts .< .5) rtol = .01 - - p = cdf(dist, 1.0) - cdf(dist, .6) - p′ = quadgk(x->pdf(dist, x), .6, 1.0)[1] - @test p′ ≈ p rtol = .001 - @test p ≈ mean((rts .< 1).& (rts .> .6)) rtol = .01 - - p = cdf(dist, 1.5) - cdf(dist, 1.4) - p′ = quadgk(x->pdf(dist, x), 1.4, 1.5)[1] - @test p′ ≈ p rtol = .001 - @test p ≈ mean((rts .< 1.5).& (rts .> 1.4)) rtol = .02 - - dist = DiffusionRace(;ν=[1.0,.5], k=0.5, A=1.0, θ=.2) - data = rand(dist, 10^6) - data1 = filter(x->x[1] == 1, data) - p1 = mean(x->x[1] == 1, data) - p2 = 1 - p1 - rt1 = map(x->x[2], data1) - # approx_pdf = kernel(rt1) - # x = .201:.01:2.5 - # y′ = pdf(approx_pdf, x) * p1 - # y = pdf.(dist, (1,), x) - # @test y′ ≈ y rtol = .03 - - data2 = filter(x->x[1] == 2, data) - rt2 = map(x->x[2], data2) - approx_pdf = kernel(rt2) - # x = .201:.01:1.5 - # y′ = pdf(approx_pdf, x) * p2 - # y = pdf.(dist, (2,), x) - # @test y′ ≈ y rtol = .03 - - p′ = quadgk(x->pdf(dist, 1, x), .2, Inf)[1] - @test p′ ≈ p1 rtol = .001 - - p = quadgk(x->pdf(dist, 1, x), .2, .3)[1] - @test p ≈ mean(rt1 .< .3) * p1 atol = .01 - - p = quadgk(x->pdf(dist, 1, x), .2, .5)[1] - @test p ≈ mean(rt1 .< .5) * p1 atol = .01 - - p = quadgk(x->pdf(dist, 1, x), .2, 1)[1] - quadgk(x->pdf(dist, 1, x), .2, .6)[1] - @test p ≈ mean((rt1 .< 1) .& (rt1 .> .6)) * p1 atol = .01 - - p = quadgk(x->pdf(dist, 1, x), .2, 1.5)[1] - quadgk(x->pdf(dist, 1, x), .2, 1.4)[1] - @test p ≈ mean((rt1 .< 1.5).& (rt1 .> 1.4)) atol = .01 - - - p′ = quadgk(x->pdf(dist, 2, x), .2, Inf)[1] - @test p′ ≈ p2 rtol = .001 - - p = quadgk(x->pdf(dist, 2, x), .2, .3)[1] - @test p ≈ mean(rt2 .< .3) * p2 atol = .01 - - p = quadgk(x->pdf(dist, 2, x), .2, .5)[1] - @test p ≈ mean(rt2 .< .5) * p2 atol = .02 - - p = quadgk(x->pdf(dist, 2, x), .2, 1)[1] - quadgk(x->pdf(dist, 2, x), .2, .6)[1] - @test p ≈ mean((rt2 .< 1) .& (rt2 .> .6)) * p2 atol = .01 - - p = quadgk(x->pdf(dist, 2, x), .2, 1.5)[1] - quadgk(x->pdf(dist, 2, x), .2, 1.4)[1] - @test p ≈ mean((rt2 .< 1.5).& (rt2 .> 1.4)) * p2 atol = .01 -end - -@safetestset "Attentional Diffusion" begin - @safetestset "aDDM" begin - using Test, SequentialSamplingModels, StatsBase, Random - Random.seed!(5511) - - mutable struct Transition - state::Int - n::Int - mat::Array{Float64,2} - end - - function Transition(mat) - n = size(mat,1) - state = rand(1:n) - return Transition(state, n, mat) - end - - function attend(t) - w = t.mat[t.state,:] - next_state = sample(1:t.n, Weights(w)) - t.state = next_state - return next_state - end - - model = aDDM(;ν1=5.0, ν2=4.0) - - tmat = Transition([.98 .015 .005; - .015 .98 .005; - .45 .45 .1]) - - rts1 = rand(model, 1000, x -> attend(x), tmat) - n1,n2 = length.(rts1) - @test n1 > n2 - - model = aDDM(;ν1=4.0, ν2=5.0) - rts2 = rand(model, 1000, x -> attend(x), tmat) - n1,n2 = length.(rts2) - @test n1 < n2 - - μ_rts1 = mean(vcat(rts1...)) - model = aDDM(;ν1=5.0, ν2=5.0) - rts3 = rand(model, 1000, x -> attend(x), tmat) - μ_rts3 = mean(vcat(rts3...)) - @test μ_rts1 < μ_rts3 - end - - @safetestset "maaDDM" begin - @safetestset "update1" begin - using Test, SequentialSamplingModels - using SequentialSamplingModels: update - - model = maaDDM(ν₁₁ = 1.0, - ν₁₂ = 2.0, - ν₂₁ = 2.0, - ν₂₂ = 3.0, - α = 1.0, - z = 0.0, - θ = .5, - ϕ = .50, - ω = .00, - σ = eps(), - Δ = 1.0) - - Δ1s = map(x -> update(model, x), 1:4) - @test Δ1s[1] > 0 - @test Δ1s[2] > 0 - @test Δ1s[3] < 0 - @test Δ1s[4] < 0 - - model = maaDDM(ν₁₁ = 100.0, - ν₁₂ = 2.0, - ν₂₁ = 2.0, - ν₂₂ = 3.0, - α = 1.0, - z = 0.0, - θ = .5, - ϕ = .50, - ω = .00, - σ = eps(), - Δ = 1.0) - - Δ2s = map(x -> update(model, x), 1:4) - @test Δ1s ≈ Δ2s atol = 1e-5 - end - - @safetestset "update2" begin - using Test, SequentialSamplingModels - using SequentialSamplingModels: update - - model = maaDDM(ν₁₁ = 1.0, - ν₁₂ = 2.0, - ν₂₁ = 2.0, - ν₂₂ = 3.0, - α = 1.0, - z = 0.0, - θ = .5, - ϕ = .50, - ω = .00, - σ = eps(), - Δ = 1.0) - - Δs = map(x -> update(model, x), 1:4) - - @test Δs[1] > 0 - @test Δs[2] > 0 - @test Δs[3] < 0 - @test Δs[4] < 0 - end - - @safetestset "update3" begin - using Test, SequentialSamplingModels - using SequentialSamplingModels: update - - model = maaDDM(ν₁₁ = 1.0, - ν₁₂ = 1.0, - ν₂₁ = 2.0, - ν₂₂ = 2.0, - α = 1.0, - z = 0.0, - θ = 1.0, - ϕ = .50, - ω = .50, - σ = eps(), - Δ = 1.0) - - Δs = map(x -> update(model, x), 1:4) - @test all(Δs .≈ -.75) - end - - @safetestset "update4" begin - using Test, SequentialSamplingModels - using SequentialSamplingModels: update - - model = maaDDM(ν₁₁ = 1.0, - ν₁₂ = 1.0, - ν₂₁ = 2.0, - ν₂₂ = 2.0, - α = 1.0, - z = 0.0, - θ = 1.0, - ϕ = 1.0, - ω = 1.0, - σ = eps(), - Δ = 1.0) - - Δ1s = map(x -> update(model, x), 1:4) - - model = maaDDM(ν₁₁ = 1.0, - ν₁₂ = 1.0, - ν₂₁ = 2.0, - ν₂₂ = 2.0, - α = 1.0, - z = 0.0, - θ = 1.0, - ϕ = 1.0, - ω = 0.0, - σ = eps(), - Δ = 1.0) - - Δ2s = map(x -> update(model, x), 1:4) - - @test all(Δ1s .≈ -1.0) - @test all(Δ2s .≈ -1.0) - end - - @safetestset "update5" begin - using Test, SequentialSamplingModels - using SequentialSamplingModels: update - - model = maaDDM(ν₁₁ = 1.0, - ν₁₂ = 1.0, - ν₂₁ = 2.0, - ν₂₂ = 2.0, - α = 1.0, - z = 0.0, - θ = 1.0, - ϕ = 0.0, - ω = 1.0, - σ = eps(), - Δ = 1.0) - - Δ2s = map(x -> update(model, x), 1:4) - - @test Δ2s ≈ [-1,0,-1,0] - end - - @safetestset "update6" begin - using Test, SequentialSamplingModels - using SequentialSamplingModels: update - - model = maaDDM(ν₁₁ = 1.0, - ν₁₂ = 1.0, - ν₂₁ = 2.0, - ν₂₂ = 2.0, - α = 1.0, - z = 0.0, - θ = 0.0, - ϕ = 1.0, - ω = 1.0, - σ = eps(), - Δ = 1.0) - - Δ2s = map(x -> update(model, x), 1:4) - - @test Δ2s ≈ [1,1,-2,-2] - end - end -end +include.(files) \ No newline at end of file diff --git a/test/wald_mixture_tests.jl b/test/wald_mixture_tests.jl new file mode 100644 index 00000000..24c8191e --- /dev/null +++ b/test/wald_mixture_tests.jl @@ -0,0 +1,32 @@ +@safetestset "Wald Mixture" begin + @safetestset "pdf" begin + using Test, SequentialSamplingModels, KernelDensity, Random + Random.seed!(22198) + d = WaldMixture(2, .2, 1, .1) + @test mean(d) ≈ (1/2) + .1 atol = 1e-5 + rts = rand(d, 100000) + approx_pdf = kde(rts) + x = .2:.01:1.5 + y′ = pdf(approx_pdf, x) + y = pdf.(d, x) + @test y′ ≈ y rtol = .03 + @test mean(rts) ≈ mean(d) atol = 5e-3 + + y′ = @. logpdf(d, x) |> exp + @test y′ ≈ y + end + + @safetestset "loglikelihood" begin + using SequentialSamplingModels + using Test + using Random + Random.seed!(655) + + dist = WaldMixture(2, .2, 1, .1) + rt = rand(dist, 10) + + sum_logpdf = logpdf.(dist, rt) |> sum + loglike = loglikelihood(dist, rt) + @test sum_logpdf ≈ loglike + end +end \ No newline at end of file diff --git a/test/wald_tests.jl b/test/wald_tests.jl new file mode 100644 index 00000000..55c169b0 --- /dev/null +++ b/test/wald_tests.jl @@ -0,0 +1,46 @@ +@safetestset "Wald" begin + @safetestset "pdf" begin + using Test, SequentialSamplingModels, KernelDensity, Random + Random.seed!(22158) + d = Wald(2, 1, .1) + @test mean(d) ≈ (1/2) + .1 atol = 1e-5 + + function simulate(υ, α, θ) + noise = 1.0 + #Time Step + Δt = .0005 + #Evidence step + Δe = noise * sqrt(Δt) + e = 0.0 + t = θ + p = .5 * (1 + υ * sqrt(Δt) / noise) + while (e < α) + t += Δt + e += rand() ≤ p ? Δe : -Δe + end + return t + end + rts = map(_ -> simulate(3, 1, .2), 1:10^5) + approx_pdf = kde(rts) + x = .2:.01:1.5 + y′ = pdf(approx_pdf, x) + y = pdf.(Wald(3,1,.2), x) + @test y′ ≈ y rtol = .03 + @test mean(rts) ≈ mean(Wald(3,1,.2)) atol = 5e-3 + @test std(rts) ≈ std(Wald(3,1,.2)) atol = 1e-3 + end + + @safetestset "loglikelihood" begin + using SequentialSamplingModels + using Test + using Random + Random.seed!(655) + + dist = Wald(2, 1, .1) + rt = rand(dist, 10) + + sum_logpdf = logpdf.(dist, rt) |> sum + loglike = loglikelihood(dist, rt) + @test sum_logpdf ≈ loglike + end +end \ No newline at end of file