Я понимаю, что это может быть сделано путем определения формы слезы и принятия точек, которые попадают в эту область (из равномерного генератора).
Я пытаюсь сделать это в C ++, генерируя два одинаковых случайных числа x и y для определения местоположения точки (x, y), а затем проверяя, попадает ли эта точка в область.
У меня нет проблем с самим кодом, но есть ли здесь ошибка в моей логике? Я не нашел подходящего графического способа проверить, действительно ли это нормальное распределение.
Вот код, который должен работать:
typedef unsigned long long int Ullong;
typedef double Doub;
struct Normaldev : Ran {
Doub mu,sig;
Normaldev (Doub mmu, Doub ssig, Ullong i)
: Ran (i), mu(mmu), sig(ssig){}
Doub dev() {
Doub u, v, x, y, q;
do {
u=Doub();
v=1.7156*(Doub()-0.5);
x=u-0.449871;
y=abs(v)+0.386595;
q=x*x+y*(0.19600*y-0.25472*x);
} while(q>0.27597 && (q>0.27846 || v*v>-4*log(u)*u*u));
return mu+sig*v/u;
}
};
Я изменил предложенный код в книге «Числовые рецепты» настолько, насколько мог, благодаря своим элементарным знаниям C ++, но каким именно должен быть Ран?
Я изменил предложенный код в книге «Числовые рецепты» настолько, насколько мог, благодаря своим элементарным знаниям C ++, но каким именно должен быть Ран?
Ran является родительским классом NormalDev. Это не определено в коде, который вы дали. Основываясь на коде, это, кажется, довольно общий класс случайных чисел, который принимает unsigned long long int
семя в своем конструкторе.
Взгляните на 3-е издание «Числовые рецепты в C», страницы 364-369. Вы обнаружите, что Box-Muller возвращает две нормально распределенные случайные величины, а именно ‘u’ и ‘v’. Таким образом, при первом вызове функции вы вычисляете обе переменные, но возвращаете только ‘u’. Второй вызов функции ничего не делает, кроме возврата «v».
double u, v;
double sigma = 1.0
double mean = 0.0;
int flag = 0;
double boxMuller()
{
if (flag == 1) {
flag = 0;
return v * sigma + mean;
}
double help;
do {
u = Doub() - 0.5;
v = Doub() - 0.5;
help = u * u + v * v;
} while (help >= 0.25);
help = sqrt( log( help * 4.0 ) / help * -2.0 );
u *= help;
v *= help;
flag = 1;
return u * sigma + mean;
}
Метод Ratio-of-Uniforms, напротив, должен вычислять новую случайную переменную при каждом вызове (а не каждую секунду).
Поэтому я измерил время и предпочел использовать приведенный выше код Бокса-Мюллера.