diff --git a/src/Distributions.jl b/src/Distributions.jl index 8d344c415..7cb9f1ed8 100644 --- a/src/Distributions.jl +++ b/src/Distributions.jl @@ -129,7 +129,6 @@ export MatrixBeta, MatrixFDist, MatrixNormal, - MatrixReshaped, MatrixTDist, MixtureModel, Multinomial, diff --git a/src/deprecates.jl b/src/deprecates.jl index 3106154a5..a360c977c 100644 --- a/src/deprecates.jl +++ b/src/deprecates.jl @@ -53,11 +53,20 @@ end @deprecate expectation(distr::Union{UnivariateDistribution,MultivariateDistribution}, g::Function; kwargs...) expectation(g, distr; kwargs...) false # Deprecate `MatrixReshaped` +# This is very similar to `Base.@deprecate_binding MatrixReshaped{...} ReshapedDistribution{...}` +# However, `Base.@deprecate_binding` does not support type parameters +export MatrixReshaped const MatrixReshaped{S<:ValueSupport,D<:MultivariateDistribution{S}} = ReshapedDistribution{2,S,D} Base.deprecate(@__MODULE__, :MatrixReshaped) -@deprecate MatrixReshaped( - d::MultivariateDistribution, n::Integer, p::Integer=n -) reshape(d, (n, p)) +# This is very similar to `Base.@deprecate MatrixReshaped(...) reshape(...)` +# We use another (unexported!) alias here to not throw a deprecation warning/error +# Unexported aliases do not affect the type printing +# In Julia >= 1.6, instead of a new alias we could have defined a method for (ReshapedDistribution{2,S,D} where {S<:ValueSupport,D<:MultivariateDistribution{S}}) +const _MatrixReshaped{S<:ValueSupport,D<:MultivariateDistribution{S}} = ReshapedDistribution{2,S,D} +function _MatrixReshaped(d::MultivariateDistribution, n::Integer, p::Integer=n) + Base.depwarn("`MatrixReshaped(d, n, p)` is deprecated, use `reshape(d, (n, p))` instead.", :MatrixReshaped) + return reshape(d, (n, p)) +end for D in (:InverseWishart, :LKJ, :MatrixBeta, :MatrixFDist, :Wishart) @eval @deprecate dim(d::$D) size(d, 1) diff --git a/test/matrixreshaped.jl b/test/matrixreshaped.jl index da92ecd2e..8f5de605f 100644 --- a/test/matrixreshaped.jl +++ b/test/matrixreshaped.jl @@ -3,113 +3,132 @@ using Distributions, Test, Random, LinearAlgebra rng = MersenneTwister(123456) -@testset "matrixreshaped.jl" begin +if VERSION >= v"1.6.0-DEV.254" + _redirect_stderr(f, ::Base.DevNull) = redirect_stderr(f, devnull) +else + function _redirect_stderr(f, ::Base.DevNull) + nulldev = @static Sys.iswindows() ? "NUL" : "/dev/null" + open(nulldev, "w") do io + redirect_stderr(f, io) + end + end +end function test_matrixreshaped(rng, d1, sizes) - x1 = rand(rng, d1) - d1s = [@test_deprecated(MatrixReshaped(d1, s...)) for s in sizes] + @testset "MatrixReshaped $(nameof(typeof(d1))) tests" begin + x1 = rand(rng, d1) + d1s = [@test_deprecated(MatrixReshaped(d1, s...)) for s in sizes] -@testset "MatrixReshaped $(nameof(typeof(d1))) tests" begin - @testset "MatrixReshaped constructor" begin - for d in d1s - @test d isa MatrixReshaped + @testset "MatrixReshaped constructor" begin + for d in d1s + @test d isa MatrixReshaped + end end - end - @testset "MatrixReshaped constructor errors" begin - @test_deprecated(@test_throws ArgumentError MatrixReshaped(d1, length(d1), 2)) - @test_deprecated(@test_throws ArgumentError MatrixReshaped(d1, length(d1))) - @test_deprecated(@test_throws ArgumentError MatrixReshaped(d1, -length(d1), -1)) - end - @testset "MatrixReshaped size" begin - for (d, s) in zip(d1s[1:end-1], sizes[1:end-1]) - @test size(d) == s + @testset "MatrixReshaped constructor errors" begin + @test_deprecated(@test_throws ArgumentError MatrixReshaped(d1, length(d1), 2)) + @test_deprecated(@test_throws ArgumentError MatrixReshaped(d1, length(d1))) + @test_deprecated(@test_throws ArgumentError MatrixReshaped(d1, -length(d1), -1)) end - end - @testset "MatrixReshaped length" begin - for d in d1s - @test length(d) == length(d1) + @testset "MatrixReshaped size" begin + for (d, s) in zip(d1s[1:end-1], sizes[1:end-1]) + @test size(d) == s + end end - end - @testset "MatrixReshaped rank" begin - for (d, s) in zip(d1s, sizes) - @test rank(d) == minimum(s) + @testset "MatrixReshaped length" begin + for d in d1s + @test length(d) == length(d1) + end end - end - @testset "MatrixReshaped insupport" begin - for (i, d) in enumerate(d1s[1:end-1]) - for (j, s) in enumerate(sizes[1:end-1]) - @test (i == j) ⊻ !insupport(d, reshape(x1, s)) + @testset "MatrixReshaped rank" begin + for (d, s) in zip(d1s, sizes) + @test rank(d) == minimum(s) end end - end - @testset "MatrixReshaped mean" begin - for (d, s) in zip(d1s[1:end-1], sizes[1:end-1]) - @test mean(d) == reshape(mean(d1), s) + @testset "MatrixReshaped insupport" begin + for (i, d) in enumerate(d1s[1:end-1]) + for (j, s) in enumerate(sizes[1:end-1]) + @test (i == j) ⊻ !insupport(d, reshape(x1, s)) + end + end end - end - @testset "MatrixReshaped mode" begin - for (d, s) in zip(d1s[1:end-1], sizes[1:end-1]) - @test mode(d) == reshape(mode(d1), s) + @testset "MatrixReshaped mean" begin + for (d, s) in zip(d1s[1:end-1], sizes[1:end-1]) + @test mean(d) == reshape(mean(d1), s) + end end - end - @testset "MatrixReshaped covariance" begin - for (d, (n, p)) in zip(d1s[1:end-1], sizes[1:end-1]) - @test cov(d) == cov(d1) - @test cov(d, Val(false)) == reshape(cov(d1), n, p, n, p) + @testset "MatrixReshaped mode" begin + for (d, s) in zip(d1s[1:end-1], sizes[1:end-1]) + @test mode(d) == reshape(mode(d1), s) + end end - end - @testset "MatrixReshaped variance" begin - for (d, s) in zip(d1s[1:end-1], sizes[1:end-1]) - @test var(d) == reshape(var(d1), s) + @testset "MatrixReshaped covariance" begin + for (d, (n, p)) in zip(d1s[1:end-1], sizes[1:end-1]) + @test cov(d) == cov(d1) + @test cov(d, Val(false)) == reshape(cov(d1), n, p, n, p) + end end - end - @testset "MatrixReshaped params" begin - for (d, s) in zip(d1s[1:end-1], sizes[1:end-1]) - @test params(d) == (d1, s) + @testset "MatrixReshaped variance" begin + for (d, s) in zip(d1s[1:end-1], sizes[1:end-1]) + @test var(d) == reshape(var(d1), s) + end end - end - @testset "MatrixReshaped partype" begin - for d in d1s - @test partype(d) === partype(d1) + @testset "MatrixReshaped params" begin + for (d, s) in zip(d1s[1:end-1], sizes[1:end-1]) + @test params(d) == (d1, s) + end end - end - @testset "MatrixReshaped eltype" begin - for d in d1s - @test eltype(d) === eltype(d1) + @testset "MatrixReshaped partype" begin + for d in d1s + @test partype(d) === partype(d1) + end end - end - @testset "MatrixReshaped logpdf" begin - for (d, s) in zip(d1s[1:end-1], sizes[1:end-1]) - x = reshape(x1, s) - @test logpdf(d, x) == logpdf(d1, x1) + @testset "MatrixReshaped eltype" begin + for d in d1s + @test eltype(d) === eltype(d1) + end end - end - @testset "MatrixReshaped rand" begin - for d in d1s - x = rand(rng, d) - @test insupport(d, x) - @test insupport(d1, vec(x)) - @test logpdf(d, x) == logpdf(d1, vec(x)) + @testset "MatrixReshaped logpdf" begin + for (d, s) in zip(d1s[1:end-1], sizes[1:end-1]) + x = reshape(x1, s) + @test logpdf(d, x) == logpdf(d1, x1) + end end - end - @testset "MatrixReshaped vec" begin - for d in d1s - @test vec(d) === d1 + @testset "MatrixReshaped rand" begin + for d in d1s + x = rand(rng, d) + @test insupport(d, x) + @test insupport(d1, vec(x)) + @test logpdf(d, x) == logpdf(d1, vec(x)) + end + end + @testset "MatrixReshaped vec" begin + for d in d1s + @test vec(d) === d1 + end end end -end end - # MvNormal - σ = rand(rng, 16, 16) - μ = rand(rng, 16) - d1 = MvNormal(μ, σ * σ') - sizes = [(4, 4), (8, 2), (2, 8), (1, 16), (16, 1), (4,)] - test_matrixreshaped(rng, d1, sizes) +# Note: In contrast to `@deprecate`, `@deprecate_binding` can't be tested with `@test_deprecated` +# Ref: https://github.com/JuliaLang/julia/issues/38780 +@testset "matrixreshaped.jl" begin + @testset "MvNormal" begin + σ = rand(rng, 16, 16) + μ = rand(rng, 16) + d1 = MvNormal(μ, σ * σ') + sizes = [(4, 4), (8, 2), (2, 8), (1, 16), (16, 1), (4,)] + _redirect_stderr(devnull) do + test_matrixreshaped(rng, d1, sizes) + end + end # Dirichlet - α = rand(rng, 36) .+ 1 # mode is only defined if all alpha > 1 - d1 = Dirichlet(α) - sizes = [(6, 6), (4, 9), (9, 4), (3, 12), (12, 3), (1, 36), (36, 1), (6,)] - test_matrixreshaped(rng, d1, sizes) + @testset "Dirichlet" begin + α = rand(rng, 36) .+ 1 # mode is only defined if all alpha > 1 + d1 = Dirichlet(α) + sizes = [(6, 6), (4, 9), (9, 4), (3, 12), (12, 3), (1, 36), (36, 1), (6,)] + _redirect_stderr(devnull) do + test_matrixreshaped(rng, d1, sizes) + end + end end