// NewNormal creates a new Normal with the given mean and covariance matrix. // NewNormal panics if len(mu) == 0, or if len(mu) != sigma.N. If the covariance // matrix is not positive-definite, the returned boolean is false. func NewNormal(mu []float64, sigma mat64.Symmetric, src *rand.Rand) (*Normal, bool) { if len(mu) == 0 { panic(badZeroDimension) } dim := sigma.Symmetric() if dim != len(mu) { panic(badSizeMismatch) } n := &Normal{ src: src, dim: dim, mu: make([]float64, dim), sigma: mat64.NewSymDense(dim, nil), chol: mat64.NewTriDense(dim, true, nil), } copy(n.mu, mu) n.sigma.CopySym(sigma) // TODO(btracey): Change this to the input Sigma, in case it is diagonal or // banded. ok := n.chol.Cholesky(n.sigma, true) if !ok { return nil, false } for i := 0; i < dim; i++ { n.logSqrtDet += math.Log(n.chol.At(i, i)) } return n, true }
// NewNormal creates a new Normal with the given mean and covariance matrix. // NewNormal panics if len(mu) == 0, or if len(mu) != sigma.N. If the covariance // matrix is not positive-definite, the returned boolean is false. func NewNormal(mu []float64, sigma mat64.Symmetric, src *rand.Rand) (*Normal, bool) { if len(mu) == 0 { panic(badZeroDimension) } dim := sigma.Symmetric() if dim != len(mu) { panic(badSizeMismatch) } n := &Normal{ src: src, dim: dim, mu: make([]float64, dim), } copy(n.mu, mu) ok := n.chol.Factorize(sigma) if !ok { return nil, false } n.lower.LFromCholesky(&n.chol) n.logSqrtDet = 0.5 * n.chol.LogDet() return n, true }