Skip to content

Commit c97c806

Browse files
authored
Merge branch 'pa/deprecation-removal-5.0' into pa/lrt
2 parents 09ba5d9 + d1d4523 commit c97c806

File tree

6 files changed

+44
-104
lines changed

6 files changed

+44
-104
lines changed

NEWS.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ MixedModels v5.0.0 Release Notes
22
==============================
33
- Optimization is now performed _without constraints_. In a post-fitting step, the Cholesky factor is canonicalized to have non-negative diagonal elements. [#840]
44
- The default optimizer has changed to NLopt's implementation of NEWUOA where possible. NLopt's implementation fails on 1-dimensional problems, so in the case of a single, scalar random effect, BOBYQA is used instead. In the future, the default optimizer backend will likely change to PRIMA and NLopt support will be moved to an extension. Blocking this change in backend is an issue with PRIMA.jl when running in VSCode's built-in REPL on Linux. [#840]
5-
- [BREAKING] Support for constrained optimization has been completely removed, i.e. the field `lowerbd` has been removed from `OptSummary`. [#849]
5+
- [BREAKING] Support for constrained optimization has been completely removed, i.e. the field `lowerbd` has been removed from `OptSummary`.[#849]
6+
- [BREAKING] The deprecated `use_threads` kwarg has been dropped from `parametricbootstrap`. It had been a no-op since v4.10.0. [#841]
7+
- [BREAKING] The deprecated `hide_progress` kwarg has been dropped from `parametricbootstrap`. It had been replaced by `progress` since v4.22.0. [#841]
68
- [BREAKING] A fitlog is always kept -- the deprecated keyword argument `thin` has been removed as has the `fitlog` keyword argument. [#850]
79
- The fitlog is now stored as Tables.jl-compatible column table. [#850]
810
- Internal code around the default optimizer has been restructured. In particular, the NLopt backend has been moved to a submodule, which will make it easier to move it to an extension if we promote another backend to the default. [#853]
@@ -673,3 +675,8 @@ Package dependencies
673675
[#840]: https://github.com/JuliaStats/MixedModels.jl/issues/840
674676
[#841]: https://github.com/JuliaStats/MixedModels.jl/issues/841
675677
[#842]: https://github.com/JuliaStats/MixedModels.jl/issues/842
678+
[#849]: https://github.com/JuliaStats/MixedModels.jl/issues/849
679+
[#850]: https://github.com/JuliaStats/MixedModels.jl/issues/850
680+
[#853]: https://github.com/JuliaStats/MixedModels.jl/issues/853
681+
[#854]: https://github.com/JuliaStats/MixedModels.jl/issues/854
682+
[#856]: https://github.com/JuliaStats/MixedModels.jl/issues/856

README.md

Lines changed: 31 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -53,31 +53,33 @@ Typical distribution forms are _Bernoulli_ for binary data or _Poisson_ for coun
5353
|OS | OS Version |Arch |Julia |
5454
|:------:|:-------------:|:------:|:--------------:|
5555
|Linux | Ubuntu 22.04 | x64 |v1.10 |
56-
|Linux | Ubuntu 22.04 | x64 |current release |
56+
|Linux | Ubuntu 24.04 | x64 |current release |
5757
|Linux | Ubuntu 22.04 | x64 |nightly |
5858
|macOS | Sonoma 14 | aarm64 |v1.10 |
59+
|macOS | Sequoia 15 | aarm64 |current release |
5960
|Windows | Server 2022 | x64 |v1.10 |
6061

6162
Note that previous releases still support older Julia versions.
6263

63-
## Version 4.0.0
64+
## Version 5.0
6465

65-
Version 4.0.0 contains some user-visible changes and many changes in the underlying code.
66+
Version 5.0.0 contains some user-visible changes and many changes in the underlying code.
6667

6768
Please see [NEWS](NEWS.md) for a complete overview, but a few key points are:
68-
69-
- The internal storage of the model matrices in `LinearMixedModel` has changed and been optimized. This change should be transparent to users who are not manipulating the fields of the model `struct` directly.
70-
- The [handling of rank deficiency](https://juliastats.org/MixedModels.jl/v4.0/rankdeficiency/) continues to evolve.
71-
- Additional [`predict` and `simulate`](https://juliastats.org/MixedModels.jl/v4.0/prediction/) methods have been added for generalizing to new data.
72-
- `saveoptsum` and `restoreoptsum!` provide for saving and restoring the `optsum` and thus offer a way to serialize a model fit.
73-
- There is improved support for the runtime construction of model formula, especially `RandomEffectsTerm`s and nested terms (methods for `Base.|(::AbstractTerm, ::AbstractTerm)` and `Base./(::AbstractTerm, ::AbstractTerm)`).
74-
- A progress display is shown by default for models taking more than a few hundred milliseconds to fit. This can be disabled with the keyword argument `progress=false`.
69+
- Options related to multithreading in the bootstrap have been completely removed.
70+
- Model fitting now uses unconstrained optimization, with a post-fit canonicalization step so that the diagonal elements of the lower Cholesky factor are non-negative. Relatedly, support for constrained optimization has been completely removed and the `lowerbd` field of `OptSummary` dropped.
71+
- The default optimizer has changed to use NLopt's implementation of NEWUOA. Further changes to the default optimizer are considered non-breaking.
72+
- The `profile` function now respects backend and optimizer settings.
73+
- The deprecated `hide_progress` keyword argument has been removed in favor of the shorter and affirmative `progress`.
74+
- A fitlog is always kept and stored as a Tables.jl-compatible column table.
7575

7676
## Quick Start
7777
```julia-repl
7878
julia> using MixedModels
7979
80-
julia> m1 = fit(MixedModel, @formula(yield ~ 1 + (1|batch)), MixedModels.dataset(:dyestuff))
80+
julia> using MixedModelsDatasets: dataset
81+
82+
julia> m1 = lmm(@formula(yield ~ 1 + (1|batch)), dataset(:dyestuff))
8183
Linear mixed model fit by maximum likelihood
8284
yield ~ 1 + (1 | batch)
8385
logLik -2 logLik AIC AICc BIC
@@ -86,7 +88,7 @@ Linear mixed model fit by maximum likelihood
8688
Variance components:
8789
Column Variance Std.Dev.
8890
batch (Intercept) 1388.3332 37.2603
89-
Residual 2451.2501 49.5101
91+
Residual 2451.2500 49.5101
9092
Number of obs: 30; levels of grouping factors: 6
9193
9294
Fixed-effects parameters:
@@ -98,62 +100,31 @@ Residual 2451.2501 49.5101
98100
99101
julia> using Random
100102
101-
julia> bs = parametricbootstrap(MersenneTwister(42), 1000, m1);
103+
julia> bs = parametricbootstrap(MersenneTwister(42), 1000, m1)
102104
Progress: 100%%|████████████████████████████████████████████████| Time: 0:00:00
103-
104-
julia> propertynames(bs)
105-
13-element Vector{Symbol}:
106-
:allpars
107-
:objective
108-
109-
110-
:se
111-
:coefpvalues
112-
113-
:σs
114-
115-
:inds
116-
:lowerbd
117-
:fits
118-
:fcnames
105+
MixedModelBootstrap with 1000 samples
106+
parameter min q25 median mean q75 max
107+
┌────────────────────────────────────────────────────────────────────
108+
1 │ β1 1474.0 1515.62 1527.68 1527.4 1539.56 1584.57
109+
2 │ σ 26.6353 43.7165 48.4817 48.8499 53.8964 73.8684
110+
3 │ σ1 0.0 16.835 28.1067 27.7039 39.491 83.688
111+
4 │ θ1 0.0 0.340364 0.561701 0.588678 0.840284 2.24396
119112
120113
julia> bs.coefpvalues # returns a row table
121-
1000-element Vector{NamedTuple{(:iter, :coefname, :β, :se, :z, :p), Tuple{Int64, Symbol, Float64, Float64, Float64, Float64}}}:
122-
(iter = 1, coefname = Symbol("(Intercept)"), β = 1517.0670832927115, se = 20.76271142094811, z = 73.0669059804057, p = 0.0)
123-
(iter = 2, coefname = Symbol("(Intercept)"), β = 1503.5781855888436, se = 8.1387737362628, z = 184.7425956676446, p = 0.0)
124-
(iter = 3, coefname = Symbol("(Intercept)"), β = 1529.2236379016574, se = 16.523824785737837, z = 92.54659001356465, p = 0.0)
125-
126-
(iter = 998, coefname = Symbol("(Intercept)"), β = 1498.3795009457242, se = 25.649682012258104, z = 58.417079019913054, p = 0.0)
127-
(iter = 999, coefname = Symbol("(Intercept)"), β = 1526.1076747922416, se = 16.22412120273579, z = 94.06411945042063, p = 0.0)
128-
(iter = 1000, coefname = Symbol("(Intercept)"), β = 1557.7546433870125, se = 12.557577103806015, z = 124.04898098653763, p = 0.0)
129114
130115
julia> using DataFrames
131116
132117
julia> DataFrame(bs.coefpvalues) # puts it into a DataFrame
133118
1000×6 DataFrame
134-
│ Row │ iter │ coefname │ β │ se │ z │ p │
135-
│ │ Int64 │ Symbol │ Float64 │ Float64 │ Float64 │ Float64 │
136-
├──────┼───────┼─────────────┼─────────┼─────────┼─────────┼─────────┤
137-
│ 1 │ 1 │ (Intercept) │ 1517.07 │ 20.7627 │ 73.0669 │ 0.0 │
138-
│ 2 │ 2 │ (Intercept) │ 1503.58 │ 8.13877 │ 184.743 │ 0.0 │
139-
│ 3 │ 3 │ (Intercept) │ 1529.22 │ 16.5238 │ 92.5466 │ 0.0 │
140-
141-
│ 998 │ 998 │ (Intercept) │ 1498.38 │ 25.6497 │ 58.4171 │ 0.0 │
142-
│ 999 │ 999 │ (Intercept) │ 1526.11 │ 16.2241 │ 94.0641 │ 0.0 │
143-
│ 1000 │ 1000 │ (Intercept) │ 1557.75 │ 12.5576 │ 124.049 │ 0.0 │
144-
145-
julia> DataFrame(bs.β)
146-
1000×3 DataFrame
147-
│ Row │ iter │ coefname │ β │
148-
│ │ Int64 │ Symbol │ Float64 │
149-
├──────┼───────┼─────────────┼─────────┤
150-
│ 1 │ 1 │ (Intercept) │ 1517.07 │
151-
│ 2 │ 2 │ (Intercept) │ 1503.58 │
152-
│ 3 │ 3 │ (Intercept) │ 1529.22 │
153-
154-
│ 998 │ 998 │ (Intercept) │ 1498.38 │
155-
│ 999 │ 999 │ (Intercept) │ 1526.11 │
156-
│ 1000 │ 1000 │ (Intercept) │ 1557.75 │
119+
Row │ iter coefname β se z p
120+
│ Int64 Symbol Float64 Float64 Float64 Float64
121+
──────┼─────────────────────────────────────────────────────────
122+
1 │ 1 (Intercept) 1552.65 9.8071 158.319 0.0
123+
2 │ 2 (Intercept) 1557.33 21.0679 73.9197 0.0
124+
⋮ │ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮
125+
999 │ 999 (Intercept) 1503.1 30.3349 49.5501 0.0
126+
1000 │ 1000 (Intercept) 1565.47 24.5067 63.8794 0.0
127+
996 rows omitted
157128
```
158129

159130
## Funding Acknowledgement

src/bootstrap.jl

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -219,18 +219,9 @@ function parametricbootstrap(
219219
β::AbstractVector=fixef(morig),
220220
σ=morig.σ,
221221
θ::AbstractVector=morig.θ,
222-
use_threads::Bool=false,
223222
progress::Bool=true,
224-
hide_progress::Union{Bool,Nothing}=nothing,
225223
optsum_overrides=(;),
226224
) where {T}
227-
if !isnothing(hide_progress)
228-
Base.depwarn(
229-
"`hide_progress` is deprecated, please use `progress` instead." *
230-
"NB: `progress` is a positive action, i.e. `progress=true` means show the progress bar.",
231-
:parametricbootstrap; force=true)
232-
progress = !hide_progress
233-
end
234225
if σ !== missing
235226
σ = T(σ)
236227
end
@@ -248,10 +239,6 @@ function parametricbootstrap(
248239

249240
β_names = Tuple(Symbol.(coefnames(morig)))
250241

251-
use_threads && Base.depwarn(
252-
"use_threads is deprecated and will be removed in a future release",
253-
:parametricbootstrap,
254-
)
255242
samp = replicate(n; progress) do
256243
simulate!(rng, m; β, σ, θ)
257244
refit!(m; progress=false)

src/utilities.jl

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -129,19 +129,8 @@ Return a vector of the values of `n` calls to `f()` - used in simulations where
129129
bar is automatically disabled for non-interactive (i.e. logging) contexts.
130130
"""
131131
function replicate(
132-
f::Function, n::Integer; use_threads=false, hide_progress=nothing, progress=true
132+
f::Function, n::Integer; progress=true
133133
)
134-
use_threads && Base.depwarn(
135-
"use_threads is deprecated and will be removed in a future release",
136-
:replicate,
137-
)
138-
if !isnothing(hide_progress)
139-
Base.depwarn(
140-
"`hide_progress` is deprecated, please use `progress` instead." *
141-
"NB: `progress` is a positive action, i.e. `progress=true` means show the progress bar.",
142-
:replicate; force=true)
143-
progress = !hide_progress
144-
end
145134
# and we want some advanced options
146135
p = Progress(n; output=Base.stderr, enabled=progress && !_is_logging(stderr))
147136
# get the type

test/bootstrap.jl

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ include("modelcache.jl")
1616

1717
function quickboot(m, n=2)
1818
return parametricbootstrap(MersenneTwister(42), n, m;
19-
progress=false, use_threads=false,
19+
progress=false,
2020
optsum_overrides=(; ftol_rel=1e-8))
2121
end
2222

@@ -92,11 +92,8 @@ end
9292
# two implicit tests
9393
# 1. type conversion of ints to floats
9494
# 2. test method for default RNG
95-
@test_logs((:warn, r"hide_progress"),
96-
parametricbootstrap(1, fm, β=[1], σ=1, hide_progress=true))
97-
9895
bsamp = parametricbootstrap(MersenneTwister(1234321), 100, fm;
99-
use_threads=false, progress=false)
96+
progress=false)
10097
@test isa(propertynames(bsamp), Vector{Symbol})
10198
@test length(bsamp.objective) == 100
10299
@test keys(first(bsamp.fits)) == (:objective, :σ, :β, :se, :θ)
@@ -107,13 +104,13 @@ end
107104

108105
@testset "optsum_overrides" begin
109106
bsamp2 = parametricbootstrap(MersenneTwister(1234321), 100, fm;
110-
use_threads=false, progress=false,
107+
progress=false,
111108
optsum_overrides=(; ftol_rel=1e-8))
112109
# for such a simple, small model setting the function value
113110
# tolerance has little effect until we do something extreme
114111
@test bsamp.objective bsamp2.objective
115112
bsamp2 = parametricbootstrap(MersenneTwister(1234321), 100, fm;
116-
use_threads=false, progress=false,
113+
progress=false,
117114
optsum_overrides=(; ftol_rel=1.0))
118115
@test !(bsamp.objective bsamp2.objective)
119116
end
@@ -131,12 +128,6 @@ end
131128
@test only(unique(coefp.coefname)) == Symbol("(Intercept)")
132129
@test propertynames(coefp) == [:iter, :coefname, :β, :se, :z, :p]
133130

134-
@testset "threaded bootstrap" begin
135-
@test_logs (:warn, r"use_threads is deprecated") parametricbootstrap(
136-
MersenneTwister(1234321), 1, fm;
137-
use_threads=true, progress=false)
138-
end
139-
140131
@testset "zerocorr + Base.length + ftype" begin
141132
fmzc = models(:sleepstudy)[2]
142133
pbzc = parametricbootstrap(MersenneTwister(42), 5, fmzc, Float16;

test/utilities.jl

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,6 @@ end
3939
@test isconstant(Union{Int,Missing}[missing, missing, missing])
4040
end
4141

42-
@testset "replicate" begin
43-
@test_logs (:warn, r"use_threads is deprecated") replicate(string, 1; use_threads=true)
44-
@test_logs (:warn, r"hide_progress") replicate(string, 1; hide_progress=true)
45-
end
46-
4742
@testset "PCA" begin
4843
io = IOBuffer()
4944
pca = models(:kb07)[3].PCA.item

0 commit comments

Comments
 (0)