From 13b79fe04bfeda5a544a35d949e4b2929db42529 Mon Sep 17 00:00:00 2001 From: Dahua Lin Date: Fri, 31 Oct 2014 15:40:58 +0800 Subject: [PATCH] new implementation of `show` for distributions --- src/multivariate/dirichlet.jl | 2 + src/multivariate/mvnormal.jl | 3 + src/show.jl | 101 +++++++++++++++++++++------------- 3 files changed, 67 insertions(+), 39 deletions(-) diff --git a/src/multivariate/dirichlet.jl b/src/multivariate/dirichlet.jl index 0d6335e82..ae46bebc4 100644 --- a/src/multivariate/dirichlet.jl +++ b/src/multivariate/dirichlet.jl @@ -32,6 +32,8 @@ length(d::DirichletCanon) = length(d.alpha) Base.convert(::Type{Dirichlet}, cf::DirichletCanon) = Dirichlet(cf.alpha) +Base.show(io::IO, d::Dirichlet) = show(io, d, (:alpha,)) + # Properties length(d::Dirichlet) = length(d.alpha) diff --git a/src/multivariate/mvnormal.jl b/src/multivariate/mvnormal.jl index f38120dbb..eb4b666ea 100644 --- a/src/multivariate/mvnormal.jl +++ b/src/multivariate/mvnormal.jl @@ -28,6 +28,9 @@ function GenericMvNormal{Cov<:AbstractPDMat}(Σ::Cov) GenericMvNormal{Cov}(d, true, zeros(d), Σ) end +Base.show(io::IO, d::GenericMvNormal) = + show_multline(io, d, [(:dim, d.dim), (:μ, mean(d)), (:Σ, cov(d))]) + ## Construction of multivariate normal with specific covariance type typealias IsoNormal GenericMvNormal{ScalMat} diff --git a/src/show.jl b/src/show.jl index 26f902f32..665b4b889 100644 --- a/src/show.jl +++ b/src/show.jl @@ -1,48 +1,71 @@ -function show(io::IO, d::Distribution) - @printf io "%s distribution\n" typeof(d) - for parameter in typeof(d).names - if isa(d.(parameter), AbstractArray) - param = string(ucfirst(string(parameter)), - ":\n", - d.(parameter), - "\n") - else - param = string(ucfirst(string(parameter)), - ": ", - d.(parameter), - "\n") + + +# the name of a distribution +# +# Generally, this should be just the type name, e.g. Normal. +# Under certain circumstances, one may want to specialize +# this function to provide a name that is easier to read, +# especially when the type is parametric. +# +distrname(d::Distribution) = string(typeof(d)) + +show(io::IO, d::Distribution) = show(io, d, typeof(d).names) + +# For some distributions, the fields may contain internal details, +# which we don't want to show, this function allows one to +# specify which fields to show. +# +function show(io::IO, d::Distribution, pnames::(Symbol...)) + # decide whether to use one-line or multi-line format + # + # Criteria: if total number of values is greater than 8, or + # there are matrix-valued params, we use multi-line format + # + namevals = (Symbol, Any)[] + multline = false + tlen = 0 + for (i, p) in enumerate(pnames) + pv = d.(p) + if !(isa(pv, Number) || isa(pv, (Number...)) || isa(pv, AbstractVector)) + multline = true end - print(io, param) + tlen += length(pv) + push!(namevals, (p, pv)) + end + if tlen > 8 + multline = true end + + # call the function that actually does the job + multline ? show_multline(io, d, namevals) : + show_oneline(io, d, namevals) end -function compact_show(io::IO, d::Distribution) - print(io, typeof(d)) - print(io, "( ") - for parameter in typeof(d).names - print(io, string(parameter)) - print(io, "=") - pv = d.(parameter) - if isa(pv, AbstractVector) - print(io, '[') - if !isempty(pv) - for i = 1 : length(pv)-1 - print(io, pv[i]) - print(io, ", ") - end - print(io, pv[end]) - end - print(io, ']') - else - print(io, pv) - end - print(io, " ") - end - print(io, ")") +function show_oneline(io::IO, d::Distribution, namevals) + print(io, distrname(d)) + np = length(namevals) + print(io, '(') + for (i, nv) in enumerate(namevals) + (p, pv) = nv + print(io, p) + print(io, '=') + show(io, pv) + if i < np + print(io, ", ") + end + end + print(io, ')') end -function show(io::IO, d::UnivariateDistribution) - compact_show(io, d) +function show_multline(io::IO, d::Distribution, namevals) + print(io, distrname(d)) + println(io, "(") + for (p, pv) in namevals + print(io, p) + print(io, ": ") + println(io, pv) + end + println(io, ")") end