Я пытаюсь сгенерировать несколько единообразных действительных чисел для интеграции Монте-Карло, но созданная мною процедура возвращала некоторые действительно странные значения. При ближайшем рассмотрении я замечаю, что 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:
Код, который я пишу, выполняет Монте-Карло для всего интересующего меня домена [Lower, Upper], а затем снова смотрит на левую половину всего домена и правую половину домена.
например если бы мы интегрировали 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);
чтобы увидеть, стоит ли в каком-то смысле больше образцов
Джек
На основании пастбина вопросник разместил в комментариях:
Это не проблема со случайной библиотекой, а простая ошибка программирования. Компиляция кода выдает предупреждение:
../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
параметр. Так что ваш результат не является неожиданным. Вам на самом деле повезло, что программа работает вообще.
Других решений пока нет …