У меня возникли некоторые проблемы с пониманием, как использовать функцию gsl_histogram_pdf_sample из библиотеки GSL в C ++. Документация здесь,
Я еще не эксперт, поэтому мне было интересно, если кто-нибудь может сказать мне, что не так с этим кодом,
#include <iostream>
#include <gsl/gsl_histogram.h>
#include <gsl/gsl_rng.h>
using namespace std;
int main()
{
// I am going to use 5 bins
size_t Bins = 5;
// These are the ranges (must be Bins + 1)
double range[6] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 };
// Array with probabilities
double w[5] = {0.05, 0.1, 0.3, 0.4, 1};
// Create the histogram pdf
gsl_histogram_pdf MyHistPdf;
MyHistPdf.n = Bins;
MyHistPdf.range = range;
MyHistPdf.sum = w;
const gsl_rng_type * T;
gsl_rng * r;
T = gsl_rng_default;
r = gsl_rng_alloc (T);
double u = gsl_rng_uniform(r);
cout << u << endl;
double a = gsl_histogram_pdf_sample(&MyHistPdf, u);
return 0;
}
Программа компилируется без ошибок, но когда я ее запускаю, я всегда получаю следующую ошибку:
gsl: /usr/src/gsl-1.16-1/src/gsl-1.16/histogram/pdf.c:46: ERROR: cannot find r in cumulative pdf
И я понятия не имею, что это значит.
Прежде чем ответить на ваш вопрос, вы должны понять фундаментальное правило о GSL: «Если вы не разбираетесь в исходном коде GSL подробно, никогда не манипулируйте напрямую переменными gsl-структур». Если вы сделаете это, ваша программа неизбежно потерпит неудачу или ваши результаты не будут иметь смысла! Зачем? Потому что вы не знаете подробно внутренние соглашения gsl о том, как эти переменные хранятся и управляются!
Внимательно прочитайте документацию, и вы увидите, что есть API-функции для распределения и управления всеми структурными переменными. Если вы являетесь программистом C ++, хорошее «практическое правило» состоит в том, чтобы представить, что все переменные в структурах GSL являются частными (единственная причина, по которой это не так, заключается в том, что C не имеет возможности сделать переменные-члены частными!).
Из документации ясно, что структура gsl_histogram должна быть выделена, некоторые данные должны быть вставлены, а используемый вами gsl_histogram_pdf должен быть инициализирован с использованием определенной функции API, прежде чем вы сможете вызвать gsl_histogram_pdf_sample. Я видел, что вы пытались избежать вставки некоторых данных, взломав указатель «сумма», и GSL потерпел неудачу, как я сказал, что это произойдет, если вы не будете следовать фундаментальному правилу!
Вот пример, который я написал, чтобы вести вас
#include <iostream>
#include <cassert>
#include <gsl/gsl_histogram.h>
#include <gsl/gsl_rng.h>
using namespace std;
int main()
{
size_t Bins = 5;
double range[6] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 };
// histogram
gsl_histogram* hist = gsl_histogram_alloc (Bins);
assert( hist != NULL );
gsl_histogram_set_ranges (hist, range, 6);
// include some elements
const gsl_rng_type * T = gsl_rng_default;
gsl_rng *r = gsl_rng_alloc (T);
for(int j = 0; j < 10000; ++j ) {
const double u = gsl_rng_uniform(r) * 5.0;
gsl_histogram_increment (hist, u);
}
// Create the histogram pdf
gsl_histogram_pdf* MyHistPdf = gsl_histogram_pdf_alloc (Bins);
assert( MyHistPdf != NULL );
int status = gsl_histogram_pdf_init (MyHistPdf, hist);
assert( status != GSL_EDOM );
std::cout << "result you want";
std::cout << gsl_histogram_pdf_sample(MyHistPdf,gsl_rng_uniform(r)) << std::endl;
return 0;
}
Других решений пока нет …