1 #ifndef HOPS_MIXTURE_HPP
2 #define HOPS_MIXTURE_HPP
14 explicit Mixture(
const std::vector<std::shared_ptr<Model>> &models) :
16 weights(std::vector<double>(models.size(), 1. / models.size())) {}
18 Mixture(std::vector<std::shared_ptr<Model>> models, std::vector<double> weights) :
19 models(std::move(models)),
20 weights(std::move(weights)) {
21 if (this->models.size() != this->weights.size()) {
22 throw std::invalid_argument(
23 "Models and weights should have the same length for construction of Multimodal Object."
29 double likelihood = std::transform_reduce(std::execution::seq,
35 [&x](
const std::shared_ptr<Model> &model,
double weight) {
36 return static_cast<double>(weight * std::exp(
37 -model->computeNegativeLogLikelihood(x)));
39 return -std::log(likelihood);
47 [[nodiscard]] std::optional<VectorType>
49 std::vector<double> weightedLikelihoods;
51 std::transform(models.begin(),
54 std::back_inserter(weightedLikelihoods),
55 [&x](
const std::shared_ptr<Model> &model,
double weight) {
56 return weight * std::exp(-model->computeNegativeLogLikelihood(x));
60 double denominator = std::accumulate(weightedLikelihoods.begin(), weightedLikelihoods.end(), 0.);
62 return std::transform_reduce(models.begin(),
64 weightedLikelihoods.begin(),
67 [&x](
const std::shared_ptr<Model> &model,
double weightedLikelihood) {
68 auto gradient = model->computeLogLikelihoodGradient(x);
70 return VectorType(weightedLikelihood * gradient.value());
77 [[nodiscard]] std::optional<MatrixType>
83 std::vector<std::shared_ptr<Model>> models;
84 std::vector<double> weights;
88 #endif //HOPS_MIXTURE_HPP