-
Notifications
You must be signed in to change notification settings - Fork 48
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
rework passing and handling of FE coefficients to simulate
! for rank deficient models
#778
Changes from all commits
1f41b83
662f303
1f28d29
4f32567
53e04e3
e2f085e
73d50ae
8810666
ceb0600
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
name = "MixedModels" | ||
uuid = "ff71e718-51f3-5ec2-a782-8ffcbfa3c316" | ||
author = ["Phillip Alday <[email protected]>", "Douglas Bates <[email protected]>", "Jose Bayoan Santiago Calderon <[email protected]>"] | ||
version = "4.25.2" | ||
version = "4.25.3" | ||
|
||
[deps] | ||
Arrow = "69666777-d1a9-59fb-9406-91d4454c9d45" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,29 +18,33 @@ function simulate(m::MixedModel, args...; kwargs...) | |
end | ||
|
||
""" | ||
simulate!(rng::AbstractRNG, m::MixedModel{T}; β=m.β, σ=m.σ, θ=T[]) | ||
simulate!(m::MixedModel; β=m.β, σ=m.σ, θ=m.θ) | ||
simulate!(rng::AbstractRNG, m::MixedModel{T}; β=fixef(m), σ=m.σ, θ=T[]) | ||
simulate!(m::MixedModel; β=fixef(m), σ=m.σ, θ=m.θ) | ||
|
||
Overwrite the response (i.e. `m.trms[end]`) with a simulated response vector from model `m`. | ||
|
||
This simulation includes sampling new values for the random effects. | ||
|
||
`β` can be specified either as a pivoted, full rank coefficient vector (cf. [`fixef`](@ref)) | ||
or as an unpivoted full dimension coefficient vector (cf. [`coef`](@ref)), where the entries | ||
corresponding to redundant columns will be ignored. | ||
|
||
!!! note | ||
Note that `simulate!` methods with a `y::AbstractVector` as the first argument | ||
(besides the RNG) and `simulate` methods return the simulated response. This is | ||
in contrast to `simulate!` methods with a `m::MixedModel` as the first argument, | ||
which modify the model's response and return the entire modified model. | ||
""" | ||
function simulate!( | ||
rng::AbstractRNG, m::LinearMixedModel{T}; β=coef(m), σ=m.σ, θ=T[] | ||
rng::AbstractRNG, m::LinearMixedModel{T}; β=fixef(m), σ=m.σ, θ=T[] | ||
) where {T} | ||
# XXX should we add support for doing something with weights? | ||
simulate!(rng, m.y, m; β, σ, θ) | ||
return unfit!(m) | ||
end | ||
|
||
function simulate!( | ||
rng::AbstractRNG, m::GeneralizedLinearMixedModel{T}; β=coef(m), σ=m.σ, θ=T[] | ||
rng::AbstractRNG, m::GeneralizedLinearMixedModel{T}; β=fixef(m), σ=m.σ, θ=T[] | ||
) where {T} | ||
# note that these m.resp.y and m.LMM.y will later be synchronized in (re)fit!() | ||
# but for now we use them as distinct scratch buffers to avoid allocations | ||
|
@@ -85,7 +89,7 @@ function _rand(rng::AbstractRNG, d::Distribution, location, scale=NaN, n=1) | |
return rand(rng, dist) / n | ||
end | ||
|
||
function simulate!(m::MixedModel{T}; β=coef(m), σ=m.σ, θ=T[]) where {T} | ||
function simulate!(m::MixedModel{T}; β=fixef(m), σ=m.σ, θ=T[]) where {T} | ||
return simulate!(Random.GLOBAL_RNG, m; β, σ, θ) | ||
end | ||
|
||
|
@@ -121,7 +125,7 @@ function simulate!( | |
y::AbstractVector, | ||
m::LinearMixedModel, | ||
newdata::Tables.ColumnTable; | ||
β=m.β, | ||
β=fixef(m), | ||
σ=m.σ, | ||
θ=m.θ, | ||
) | ||
|
@@ -147,20 +151,18 @@ function simulate!( | |
end | ||
|
||
function simulate!( | ||
rng::AbstractRNG, y::AbstractVector, m::LinearMixedModel{T}; β=m.β, σ=m.σ, θ=m.θ | ||
rng::AbstractRNG, y::AbstractVector, m::LinearMixedModel{T}; β=fixef(m), σ=m.σ, θ=m.θ | ||
) where {T} | ||
length(β) == length(pivot(m)) || length(β) == m.feterm.rank || | ||
length(β) == length(pivot(m)) || length(β) == rank(m) || | ||
throw(ArgumentError("You must specify all (non-singular) βs")) | ||
|
||
β = convert(Vector{T}, β) | ||
σ = T(σ) | ||
θ = convert(Vector{T}, θ) | ||
isempty(θ) || setθ!(m, θ) | ||
|
||
if length(β) ≠ length(pivot(m)) | ||
padding = length(pivot(m)) - rank(m) | ||
append!(β, fill(-0.0, padding)) | ||
invpermute!(β, pivot(m)) | ||
if length(β) == length(pivot(m)) | ||
β = view(view(β, pivot(m)), 1:rank(m)) | ||
Comment on lines
+164
to
+165
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is the branch that handles the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. correct. |
||
end | ||
|
||
# initialize y to standard normal | ||
|
@@ -172,15 +174,15 @@ function simulate!( | |
end | ||
|
||
# scale by σ and add fixed-effects contribution | ||
return mul!(y, m.X, β, one(T), σ) | ||
return mul!(y, fullrankx(m), β, one(T), σ) | ||
end | ||
|
||
function simulate!( | ||
rng::AbstractRNG, | ||
y::AbstractVector, | ||
m::GeneralizedLinearMixedModel, | ||
newdata::Tables.ColumnTable; | ||
β=m.β, | ||
β=fixef(m), | ||
σ=m.σ, | ||
θ=m.θ, | ||
) | ||
|
@@ -209,7 +211,7 @@ function simulate!( | |
rng::AbstractRNG, | ||
y::AbstractVector, | ||
m::GeneralizedLinearMixedModel{T}; | ||
β=m.β, | ||
β=fixef(m), | ||
σ=m.σ, | ||
θ=m.θ, | ||
) where {T} | ||
|
@@ -250,7 +252,7 @@ function _simulate!( | |
|
||
if length(β) == length(pivot(m)) | ||
# unlike LMM, GLMM stores the truncated, pivoted vector directly | ||
β = view(β, view(pivot(m), 1:(rank(m)))) | ||
β = view(view(β, pivot(m)), 1:rank(m)) | ||
end | ||
fast = (length(m.θ) == length(m.optsum.final)) | ||
setpar! = fast ? setθ! : setβθ! | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's worth documenting somewhere the difference between the possible kinds of inputs to this function.
coef
-style (all values in input model matrix order, pivoted out betas are-0.0
) vs.fixef
-style (only betas for full-rank columns, in pivot order)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
73d50ae