Skip to content

MvNormal unnecessarily slow when mean and covariance matrix have different types #1964

@hersle

Description

@hersle

My model has a MvNormal with a constant covariance matrix (just Float64s) and a differentiable mean vector (e.g. with ForwardDiff.Duals):

using Distributions, ForwardDiff, PDMats, LinearAlgebra, BenchmarkTools

Σ = PDMat(Matrix(1.0I, 1000, 1000)) # e.g. constant model-independent covariance matrix
μ = ForwardDiff.Dual.(1.0:1000.0) # e.g. differentiable model-dependent data vector

MvNormalSlow(μ, Σ) = MvNormal(μ, Σ) # standard constructor
MvNormalFast(μ, Σ) = MvNormal{Real, typeof(Σ), typeof(μ)}(μ, Σ) # construct manually

@btime MvNormalSlow(μ, Σ); # 1.789 ms (7 allocations: 15.26 MiB)
@btime MvNormalFast(μ, Σ); # 17.818 ns (1 allocation: 48 bytes)

The standard MvNormal constructor is unnecessarily slow. It seems to copy/refactorize covariance matrix, even though it is already factorized in my call to PDMat (which I use precisely because I know my covariance matrix is constant and I don't want to refactorize it for every model evaluation):

@profview [MvNormalSlow(μ, Σ) for i in 1:100]

Image

I think the reason is here. When μ and Σ are of different types (like here), it hits the second constructor, triggering a conversion and refactorization of the covariance matrix.

Is this intended? Is there a smooth fix to it?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions