gpt4 book ai didi

C++ 随机数生成 : Generate cos squared function

转载 作者:行者123 更新时间:2023-11-28 01:52:24 25 4
gpt4 key购买 nike

感兴趣的概率分布是

double x; // range: -pi/2.0 to +pi/2.0
double y = std::pow(std::cos(x), 2.0);

这个函数可以解析积分,但是不能反转。因此,无法执行将均匀分布映射到所需概率分布的常用技巧。

是否有另一种方法可用于生成随机变量 cos^2(theta) 分布?

也许可以从数值上找到反函数,但是我不知道执行此操作的有效(内存和计算)方法。

最佳答案

来自 Inverse transform sampling :您可以从任何概率分布中随机生成样本数,给定它的 cdf。

假设您想要 cos2x 分布,从 -pi/2 到 pi/2。由于 cos2x 从 -pi/2 到 pi/2 的积分是 pi/2,您需要按比例缩小以使积分为 1。因此,pdf P(x) = (2/pi)cos2x

下一步是根据给定的 pdf 计算 cdf,这是 pdf 的积分。您可以使用任何数值方法求出 P(x) 的积分。或者你可以去 Wolfram Alpha 得到答案:cdf 是 F(x) = (2/pi)(0.5x + 0.25sin2x) + 0.5

接下来您需要计算 F-1(x)。由于 F(x) 是单调递增函数,因此可以使用二分法(二分查找)轻松找到 F-1(x)。但是 Wolfram Alpha 没有这个 F-1(x) 公式。

然后生成一个从0到1的统一实数u。你的自定义分布是F-1(u)。

#include <iostream>
#include <cmath>
#include <random>
#include <boost/random/random_device.hpp>
#include <vector>
#include <iomanip>

const double pi = 3.14159265358979323846;

const double LOW = -pi/2;
const double HIGH = pi/2;
double pdf(double x)
{
return cos(x) * cos(x);
}

double cdf(double x) //integral of pdf
{
return (2/pi)*(x/2 + sin(2*x)/4) + 0.5; //from Wolfram Alpha
}

double inverse_cdf(double u)
{ //bisection, not 100% accurate
double low = LOW;
double high = HIGH;
double epsilon = 1e-10; //any small number, e.g. 1e-15
while (high - low > epsilon)
{
double mid = (low + high) / 2;
if (cdf(mid) == u) return mid;
if (cdf(mid) < u) low = mid; else high = mid;
}
return (low + high) / 2;
}

double custom_distribution(std::mt19937& rng)
{
double u = std::uniform_real_distribution<double>(0,1)(rng);
return inverse_cdf(u);
}

int main()
{
std::mt19937 rng{boost::random::random_device{}()};

std::vector<double> xCount(15);
int nSamples = 10000;
double gap = (HIGH-LOW) / xCount.size();
while (nSamples--) xCount[(int)( (custom_distribution(rng) - LOW) / gap )]++;
for (int i = 0; i < xCount.size(); ++i)
{
std::cout << std::setw(2) << i << ":" << xCount[i] << "\t";
for (int bar = xCount[i]/15; bar--; std::cout << '*');
std::cout << "\n";
}
}

示例输出:

 0:17   *
1:135 *********
2:305 ********************
3:604 ****************************************
4:859 *********************************************************
5:1106 *************************************************************************
6:1256 ***********************************************************************************
7:1353 ******************************************************************************************
8:1271 ************************************************************************************
9:1102 *************************************************************************
10:876 **********************************************************
11:614 ****************************************
12:334 **********************
13:143 *********
14:25 *

关于C++ 随机数生成 : Generate cos squared function,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42468856/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com