random — реализация соотношения униформ для нормального распределения в Stack Overflow

Я понимаю, что это может быть сделано путем определения формы слезы и принятия точек, которые попадают в эту область (из равномерного генератора).

Я пытаюсь сделать это в 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 ++, но каким именно должен быть Ран?

3

Решение

Я изменил предложенный код в книге «Числовые рецепты» настолько, насколько мог, благодаря своим элементарным знаниям C ++, но каким именно должен быть Ран?

Ran является родительским классом NormalDev. Это не определено в коде, который вы дали. Основываясь на коде, это, кажется, довольно общий класс случайных чисел, который принимает unsigned long long int семя в своем конструкторе.

1

Другие решения

Взгляните на 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, напротив, должен вычислять новую случайную переменную при каждом вызове (а не каждую секунду).

Поэтому я измерил время и предпочел использовать приведенный выше код Бокса-Мюллера.

-1

По вопросам рекламы [email protected]