Генерация экспоненциального распределения для набора данных с использованием boost C++

Как создать экспоненциальное распределение для набора данных, используя boost C++.

У меня есть вектор, содержащий переменные с плавающей точкой с именем vararr и использующий Boost C++, и я хочу подогнать его по экспоненциальному распределению и получить соответствующий параметр скорости (лямбда) для подгонки. Код эквивалентности в Matlab:

PD = fitdist(vararr,'exponential'); 
vararr = sort(vararr); 
fxx = pdf(PD,vararr);

Мне нужно реализовать это в C++

1 ответ

Экспоненциальное распределение существует для генерации случайного числа после определенного распределения. Чтобы использовать экспоненциальное распределение, вы делаете что-то вроде этого:

#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++ довольно старая, и я не уверен, что она полностью функциональна, но, возможно, это вам подойдет.

Другие вопросы по тегам