Равномерное создание случайных чисел с использованием Boost

Я пытаюсь сгенерировать некоторые единые действительные числа для интеграции Монте-Карло, но построенная мной подпрограмма возвращала действительно странные значения. При ближайшем рассмотрении я замечаю, что Boost возвращал какие-то безумно выглядящие случайные числа, например:

     temp = -0.185276
     temp = -0.864523
     temp = -0.0942081
     temp = -0.164991
     temp = -0.873013
     temp = -0.0311322
     temp = -0.0866241
     temp = -0.778966
     temp = -0.367641
     temp = -0.691833
     temp = 5.66499e-310
     temp = 9.42007e-311
     temp = 6.29821e-310
     temp = 5.80603e-310
     temp = 8.82973e-311
     temp = 6.73679e-310
     temp = 6.35094e-310
     temp = 1.53691e-310
     temp = 4.39696e-310
     temp = 2.14277e-310

Хотя эти числа технически все еще являются реальными, сгенерированными между границами -1 и 1, я бы предпочел, чтобы они не были такими маленькими!

Моя реализация вызова boost находится в функции, которая вызывается несколько раз (для разных ограничивающих значений) следующим образом:

// Define Boost typedefs
typedef boost::mt19937 Engine;
typedef boost::uniform_real<double> Distribution;
typedef boost::variate_generator <Engine, Distribution> Generator;

int main (void) {
    ...
    Integral = MCRecursion(...);
    ...
    return 0;
}

double MCRecursion (int Count, double Lower, double Upper, double (*Integrand)(double)) {

// Define Boost objects
Engine       Eng;
Distribution Dist (Lower, Upper);
Generator    RandomGen (Eng, Dist);

Eng.seed(time(0));

// Variables for Monte Carlo sample sums
double Sum = 0.0;
double temp;

for (int i = 0; i < Count; i++) {
    temp = RandomGen();
    std::cout << "         temp = " << temp << std::endl;
    Sum += Integrand(temp);
}

return (Upper - Lower) * Sum / Count;
}

Я предполагаю, что проблема связана с моей реализацией, но я не могу найти никаких ошибок. Любая помощь приветствуется! Привет, Джек

РЕДАКТИРОВАТЬ

Код для вызова MCRecursion:

Код, который я пишу, запускает метод Монте-Карло для всего интересующего меня домена [нижний, верхний], а затем снова просматривает левую половину всего домена и правую половину домена. например если бы мы интегрировали f(x) между -a и a, я вычислил бы полный интеграл, используя:

double FullDomain = MCRecursion (1e5, LowerBound, UpperBound, f);
double Centre = (Upper + Lower) / 2.0;
double LeftHalf = MCRecursion (1e5, LowerBound, Centre, f);
double RightHalf = MCRecursion (1e5, Centre, UpperBound, f);

затем я смотрю на неопределенность, вычисляя: двойная разница = fabs(FullDomain - LeftHalf - Righthalf); чтобы увидеть, стоит ли в каком-то смысле больше образцов, Джек


person JMzance    schedule 30.12.2013    source источник
comment
Ну мне кажется нормально. Если вы хотите, чтобы ваши значения имели гарантированное минимальное абсолютное значение, вам нужно создать распределение на [eps, 1] и еще одно для выбора знака. Вызывают ли значения какие-либо проблемы?   -  person stefan    schedule 31.12.2013
comment
проверьте stackoverflow.com/questions/15747194/   -  person tinkertime    schedule 31.12.2013
comment
Да, @stefan, потому что количество чисел составляет ~ 0,0, независимо от того, что я интегрирую, происходит очень передискретизация около нуля, поэтому, скажем, я интегрировал f (x) = x, тогда моя сумма Монте-Карло была бы значительно меньше, чем можно было бы ожидать.   -  person JMzance    schedule 31.12.2013
comment
@JackMedley Вы выбрали дистрибутив uniform_real, поэтому, если boost реализует его правильно, он не должен быть в основном около 0,0. Ну, как я уже сказал: если вы хотите установить минимум абсолютного значения, вам нужно либо игнорировать слишком маленькие значения, либо отражать диапазон [eps, 1].   -  person stefan    schedule 31.12.2013
comment
Не могли бы вы показать код, вызывающий MCRescursion, и убедиться, что вывод действительно является выводом вашего опубликованного кода? У меня проблема не воспроизводится, я сделал тестовый пример и получил равномерно распределенные случайные числа.   -  person    schedule 31.12.2013
comment
Я предполагаю, что другой способ сказать, что говорит @Nabla, - пожалуйста, создайте минимальный тестовый пример;)   -  person Oliver Charlesworth    schedule 31.12.2013
comment
@JackMedley Это все еще не минимальный тестовый пример, так как я не могу скопировать и вставить его и скомпилировать. У вас есть два набора границ: Upper/Lower и UpperBound/LowerBound, так и задумано? Какие значения они имели в вашем тестовом прогоне? Является ли вывод одним или двумя вызовами MCRecursion?   -  person    schedule 31.12.2013
comment
Да, @zahir, у меня есть небольшой оператор if, который выдает ошибку, если с моими границами происходит что-то странное.   -  person JMzance    schedule 31.12.2013
comment
Эй, @Nabla, вот и все... должно скомпилироваться нормально.   -  person JMzance    schedule 31.12.2013
comment
pastebin.com/WycKapx4   -  person JMzance    schedule 31.12.2013
comment
Их называют разными вещами в разных функциях, но они ДЕЙСТВИТЕЛЬНО меняются, они фокусируются на все меньших и меньших участках полной области в попытке найти области с высокой дисперсией.   -  person JMzance    schedule 31.12.2013
comment
@JackMedley Пожалуйста, отправьте код в вопросе. Также вы читали ссылку, опубликованную Оли Чарльзуорт. Это не минимальный тест-кейс.   -  person    schedule 31.12.2013
comment
Тем не менее, ваш код выдает несколько предупреждений. Вы используете Right неинициализированный. Также я сделал отладочный вывод. В какой-то момент ваш код вызывает MCSample с Lower=0 и Upper=6.91473e-310   -  person    schedule 31.12.2013
comment
Эй, @Nabla, проверьте мою ссылку pastebin выше для минимального рабочего примера, это полная вещь (все еще довольно маленький файл).   -  person JMzance    schedule 31.12.2013
comment
Эй, @Nabla, спасибо, я пытался распечатать эти значения, но не получил этого значения, не могли бы вы сообщить мне, на какой строке вы находитесь?   -  person JMzance    schedule 31.12.2013


Ответы (1)


Основываясь на pastebin, вопрошающий написал в комментариях:

Это не проблема случайной библиотеки, а простая ошибка программирования. Компиляция кода выдает предупреждение:

../src/Test.cpp: In function ‘double AdaptiveMCRecursion(double, double, double, double, int, double, double (*)(double))’:
../src/Test.cpp:100:72: warning: ‘Right’ is used uninitialized in this function [-Wuninitialized]
         double Right = MCSample (Count, Central, Right,   Integrand);

Таким образом, все поведение, начиная с этой строки, в основном не определено. Особенно это приводит к вызову функции MCSample с неопределенным параметром Upper. Так что ваш результат не является неожиданным. Вам на самом деле повезло, что программа вообще работает.

person Community    schedule 30.12.2013
comment
Вы совершенно правы, аргументы MCSample должны быть (Count, Central, UPPER, Integrand)! Привет @nabla - person JMzance; 31.12.2013
comment
@JackMedley Вот почему вы должны серьезно относиться к предупреждениям компилятора. - person ; 31.12.2013
comment
Или просто не забудьте добавить -Werror при запуске быстрой компиляции ;) - person JMzance; 31.12.2013