Пожалуйста, рассмотрите следующую boost::math::pdf
-подобную реализацию обобщенной c оценки функции плотности вероятности:
template<typename T, class Distribution>
inline typename Distribution::result_type pdf(Distribution const& d, T const& x) {
return pdf(d, static_cast<typename Distribution::result_type>(x));
}
template<typename RealType>
RealType pdf(std::uniform_real_distribution<RealType> const& d, RealType const& x)
{
if (d.a() <= x && x <= d.b())
return 1 / (d.b() - d.a());
return 0;
}
Я бы хотел определить другую pdf
функцию, которая принимает распределение и вектор и оценивает плотность вероятности каждого компонента вектора. Функция должна быть активна и для вложенных векторов. Я пробовал что-то вроде этого:
template<typename T, class Distribution>
inline typename Distribution::result_type pdf(Distribution const& d, std::vector<T> const& x)
{
return std::reduce(x.begin(), x.end(), typename Distribution::result_type{ 1 },
[&](auto const& p, auto const& x) { return p * pdf(d, x); });
}
Пример кода:
std::vector<std::vector<double>> x = { {1}, {2, 3}, {4} };
std::vector<double> y = { 1, 2, 3, 4 };
std::uniform_real_distribution<> d;
std::cout << pdf(d, x) << std::endl;
std::cout << pdf(d, y) << std::endl;
Это работает так, как должно быть. Тем не менее, если я изменю std::uniform_real_distribution<> d;
на std::uniform_real_distribution<float> d;
, то я получу бесконечную рекурсию для вызова pdf(d, x)
(по очевидным причинам). Итак, как мне нужно изменить код? Может быть, так, что он работает и для других контейнеров.