Как создать экспоненциальное распределение для набора данных, используя boost c ++.
У меня есть вектор, содержащий переменные с плавающей точкой с именем vararr и используя Boost c ++, и я хочу подогнать его по экспоненциальному распределению и получить соответствующий параметр скорости (лямбда) для подгонки.
Код эквивалентности в Matlab:
PD = fitdist(vararr,'exponential');
vararr = sort(vararr);
fxx = pdf(PD,vararr);
Мне нужно реализовать это в C ++
Экспоненциальное распределение существует для генерации случайного числа после определенного распределения.
Чтобы использовать экспоненциальное распределение, вы делаете что-то вроде этого:
#include <iostream>
#include <boost/random.hpp>
int main() {
boost::mt19937 seed(5u);
boost::variate_generator<boost::mt19937&, boost::exponential_distribution<>> random_n(seed, boost::exponential_distribution<>()) ;
cout << random_n() << endl; return 0;
}
Я подозреваю, что вы хотите что-то сделать, но мне это не так ясно. Вы хотите отсортировать или как? Выбрать случайное число в вашем векторе?
Редактировать:
ХОРОШО. Короче говоря, даже если у вас есть доступ к C ++ 11, вы не сможете зайти слишком далеко. Большая часть генератора случайных чисел теперь в стандарте. Но не PDF. Если вам интересно, почему: вот оно: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1398.html.
Так что вам определенно нужен инструментарий boost.math, это ваш единственный способ вычислить ваш PDF. Вот пример кода для вас:
#include <boost/math/distributions/exponential.hpp>
int main() {
const auto lbda = 1.0;
const auto d = exponential_distribution<> { lbda };
cout << pdf(d, 0) << endl; // e(0) = 1
cout << pdf(d, 1) << endl; // e(-1) = 0.3678
return 0;
}
Короче говоря: для использования наддува PDF
Вам не нужен сам по себе вектор, потому что функция PDF знает, как вычислить его распределение.
Редактировать 2: Итак, если вам нужно заполнить вектор некоторым распределением, вы можете просто использовать std::generate
и примените к нему дистрибутив, вот пример с std::exponential_distribution
(C ++ 11, но вы можете использовать boost).
std::vector<float> v(20);
random_device rd;
mt19937_64 gen(rd());
exponential_distribution<float> dis(1);
auto rand = bind(dis, gen);
generate(begin(v), end(v), rand);
for (auto& e : v) cout << e << endl;
Код, который я показываю здесь, заполняет vector
из 20 элементов с экспоненциальным распределением. Вы можете переключиться на std::array
измените число с плавающей точкой на любое, увеличьте размер вектора или массива.
Вы также можете взглянуть на эту старую библиотеку C ++ (ныне питоническую), которая делает то, что вам нужно: http://myfitter.hepforge.org/. Это, вероятно, ваш лучший выбор. Он использует непараметрический метод. Версия C ++ довольно старая, и я не уверен, что она полностью функциональна, но, возможно, это вам подойдет.
Других решений пока нет …