use itertools::izip;
use ndarray::{Array, ArrayView, Ix1, Ix2, LinalgScalar, NdFloat};
use ndarray_linalg::Lapack;
use num_traits::Float;
use crate::normal::multivariate_normal;
pub fn gmm<F, const K: usize>(
x: ArrayView<F, Ix2>,
mus: &[Array<F, Ix1>; K],
covs: &[Array<F, Ix2>; K],
phis: &[F; K],
) -> Option<Array<F, Ix1>>
where
F: Float + NdFloat + LinalgScalar + Lapack,
{
let mut pdf = Array::zeros(x.shape()[0]);
for (mu, cov, phi) in izip!(mus.iter(), covs.iter(), phis.iter()) {
let tmp = multivariate_normal(x, mu.view(), cov.view())?;
pdf = pdf + tmp * phi.clone();
}
Some(pdf)
}