How do I get an almost "normal" normal distribution?

Sorry for the “normal” normal :sweat_smile:. What I mean is that I need a Gaussian distribution with a slight change. I need to include a factor \xi, such as the density distribution below

Captura de tela de 2020-08-31 17-16-41

I don’t need the best performance, just a simple example.

1 Like

You can define your own distribution w Distributions.jl.

For example here is how to define a slew-normal: Skew normal distribution? - #9 by Albert_Zevelev

1 Like

The expression you posted looks like an ordinary three-dimensional (i.e. multivariate) normal distribution with zero mean and a diagonal (but not isotropic) covariance matrix.

This is easy with the Distributions package - see here.

using Distributions
rf = 1.2
xi = 0.3
sig = rf^2*[1/xi, 1/xi, xi^2]   # diagonal of covariance matrix
d = MvNormal(sig)                     # get distribution object

rand(d,4)       # draw samples

r = [2,3,4]
pdf(d,r)           # evaluate probability density function (pdf)

student’s T is almost normal.

Heck by CLT sum(x) if elements of x are all drawn from iid distribution then it is almost normal.

With this diagonal of covariance matrix you got something new to my life.

At link of the documentation you’ve send, it says :

vector of type Vector{T} : indicating a diagonal covariance as diagm(abs2(sig))

Maybe I’m overthinking, but if the MvNormal function applies a abs2, the input should be the square root. That is, sig = rf*[1/sqrt(xi), 1/sqrt(xi), xi]. Or am I just confused ?

AFAICT, this looks like a mistake in the documentation. In the source code, sig is taken as the covariance matrix \varSigma, or an abbreviated form thereof.

The parameter would probably better be named Sig, to avoid confusion with the standard deviation \sigma. The two are related by \varSigma = \sigma^2 \boldsymbol{I} for an isotropic covariance matrix.

EDIT: This is wrong.

After some reading I believe that you’re talking about this line:

# constructor without mean vector
MvNormal(Σ::AbstractVecOrMat{<:Real}) = MvNormal(Zeros{eltype(Σ)}(size(Σ, 1)), Σ)

Indeed, the input should be the covariance matrix diagonal as you wrote before.

Actually, I was wrong in my previous post (I crossed it out). The meaning of sig in MvNormal(sig) depends on the type of sig .

  • If sig is a scalar, it’s taken as the isotropic standard deviation \sigma.
    julia> using Distributions, LinearAlgebra
    julia> mu = [1.,2.,3.]; sig = 2.; MvNormal(mu,sig)
    dim: 3
    μ: [1.0, 2.0, 3.0]
    Σ: [4.0 0.0 0.0; 0.0 4.0 0.0; 0.0 0.0 4.0]
  • If sig is a 3-element vector, it’s the vector of standard deviations (\sigma_x,\sigma_y,\sigma_z)
    julia> mu = [1.,2.,3.]; sig = [2.,3.,4.]; MvNormal(mu,sig)
    dim: 3
    μ: [1.0, 2.0, 3.0]
    Σ: [4.0 0.0 0.0; 0.0 9.0 0.0; 0.0 0.0 16.0]
  • If sig is a 3-by-3 matrix, it’s taken as the covariance matrix \varSigma (with the squares of the standard deviations on the diagonal).
    julia> mu = [1.,2.,3.]; sig = diagm([2.,3.,4.]); MvNormal(mu,sig)
    dim: 3     
    μ: [1.0, 2.0, 3.0]
    Σ: [2.0 0.0 0.0; 0.0 3.0 0.0; 0.0 0.0 4.0]

One needs to be careful here, since for a vector sig, MvNormal(sig) and MvNormal(diagm(sig)) give different distributions. Not sure whether this subtle difference is by design or not.