The source project of this merge request has been removed.
MultivariateGaussianDist(): use "standard" multivariate normal distribution internally
A student of mine (Hank Hua) is working on a CW project using CWInPy. We're using a MultivariateGaussianDist() to set priors on the CW frequency and frequency derivative (spindown) parameters. Because the typical scales of these parameters are very different (frequency ~ 100, spindown ~1 / year), the covariance matrix can appear close to singular, which leads to NumPy errors, e.g.
numpy.linalg.LinAlgError: When `allow_singular is False`, the input matrix must be symmetric positive definite.
This MR modifies MultivariateGaussianDist() to internally use a "standard" multivariate normal distribution. In analogy to a one-dimensional standard normal distribution, where
\text{PDF}( x \,|\, \mu=\mu, \sigma=\sigma ) = \frac{1}{\sigma} \text{PDF}[ (x - \mu)/\sigma \,|\, \mu=0, \sigma=1 ]
the multidimensional analogue is
\text{PDF}( \vec x \,|\, \vec\mu=\vec\mu, \mathbf\Sigma=\mathbf\Sigma ) = \frac{1}{\prod_i \sigma_i} \text{PDF}[ (\vec x - \vec\mu)/\vec\sigma \,|\, \vec\mu=\vec 0, \mathbf\Sigma=\mathbf C ]
where \mathbf C is the correlation matrix. I've attached a PDF of a Mathematica notebook which confirms the derivation.
The code modifications are:
- Add a new array to
MultivariateGaussianDist():self.logprodsigmasto compute the log-product ofself.sigmasfor the PDF normalisation - In
add_mode()add toself.mvna "standard" multivariate normal distribution as above withmus=0andcov=corrcoefs - In
_ln_prob()callself.mvn[i].logpdf()with normalised samplez = (x - mus) / sigmasand subtract normalisation inself.logprodsigmas - Add tests in
test/core/prior/joint_test.pyfor_ln_prob()forMultivariateGaussianDist()with a) order-unity-scale parameters b) CW frequency/spindown parameter scalings