C++ lognormal_distribution对数分布随机数函数用法详解
C++ 详解 函数 用法 随机数 分布 distribution 对数
2023-06-13 09:11:54 时间
对数分布和表示随机变量的正态分布有关,这些值的对数分布是一个正态分布。对数分布是由期望和标准差定义的,但这些参数和变量无关,它们和变量的对数相关。具体来说,一个期望为 标准差为 的随机变量 x 的对数分布,说明 log x 是一个期望为 、标准差为 的正态分布。图 1 展示了一个对数分布的曲线,以及改变期望和标准差时的效果。
图 1 对数分布
图 1 对数分布
对于大自然中的很多随机变量来说,对数分布比正态分布更接近概率的表示。病人的感染率就是一个对数分布模式。
lognormal_distribution 模板的一个实例定义了一个默认返回浮点类型值的对数分布对象。 下面是一个期望为 5.0、标准差为 0.5 的对数分布对象的定义:
double mu {5.0}, sigma {0.5}; std::lognormal_distribution norm {mu, sigma};
构造函数的参数以 0 和 1 为默认值,因此省略了定义标准对数分布的参数。还有另一个构造函数,它接受封装了期望和标准差的 param_type 对象作为参数。
lognormal_distribution 对象也有所有分布类型都有的成员函数,如成员函数 m() 和 s(),它们分别返回期望和标准差。可以像看到的其他分布那样去使用这个对象,因此让我们在示例中试试它的用法。
使用对数分布为了不绘制不包含星号的行,这个示例会对前面章节中的函数模板 dist_plot() 做一点修改。这是因为对数分布曲线会有很长的尾巴,不需要去欣赏这个分布的形状。plot_data() 的最后一条语句为:
std::for_each(std::begin(plot_data), std::end(plot_data),[max_f, width](const std::pair int, int v) { if ((width*v.second)/max_f 0) std::cout std::setw(3) v.first -丨 string((width*v.second)/max_f, * ) std::endl; });
下面是程序代码:
// Checking out lognormal distributions #include random // For distributions and random number generators #include algorithm // For generate(), for_each(), max_element(), transform() #include numeric // For accumulate() #include iterator // For back_inserter() #include vector // For vector container #include map // For map container #include cmath // For pow(), round(), log() functions #include iostream // For standard streams #include iomanip // For stream manipulators #include string using std::string; using Params = std::lognormal_distribution ::param_type; // Template to plot a distribution from a range of sample values template typename Iter void dist_plot(Iter beg_iter, Iter end_iter, size_t width = 90) // Create data for distribution plot std::map int, size_t plot_data; // Elements are pair value, frequency auto pr = std::minmax_element(beg_iter, end_iter, [](const double v1, const double v2) {return v1 }); for(int n {static_cast int (*pr.first)}; n static_cast int (*pr.second); ++n) plot_data.emplace(n, 0); // Create the plot data std::for_each(beg_iter, end_iter,[ plot_data](double value) { ++plot_data[static_cast int (std::round(value))]; }); // Find maximum frequency to be plotted - must fit within page width size_t max_f {std::max_element(std::begin(plot_data), std::end(plot_data),[](const std::pair int,int v1, const std::pair int,int v2) { return v1.second v2.second; })- second}; // Draw distribution as histogram std::for_each(std::begin(plot_data), std::end(plot_data), [max_f, width](const std::pair int, int v) if((width*v.second) / max_f 0) std::cout std::setw(3) v.first -| string((width*v.second) / max_f, * ) std::endl; int main() std::random_device rd; std::default_random_engine rng {rd()}; std::lognormal_distribution log_norm; double mu {}, sigma {}; const size_t sample_count {20000}; std::vector double values(sample_count); std::vector double log_values; while(true) std::cout /nEnter values for the mean and standard deviation, or Ctrl+Z to end: if((std::cin mu).eof()) break; std::cin sigma; log_norm.param(Params {mu, sigma}); std::generate(std::begin(values), std::end(values), [ log_norm, rng] { return log_norm(rng); }); // Create data to plot lognormal curve dist_plot(std::begin(values), std::end(values)); // Create logarithms of values std::vector double log_values; std::transform(std::begin(values), std::end(values), std::back_inserter(log_values),[] (double v){ return log(v); }); // Create data to plot curve for logarithms of values std::cout /nThe distribution for logarithms of the values:/n dist_plot(std::begin(log_values), std::end(log_values)); // Get the mean and standard deviation - for the logarithms of the values double mean {std::accumulate(std::begin(log_values), std::end(log_values), 0.0) / log_values.size()}; std::transform(std::begin(log_values), std::end(log_values), std::begin(log_values),[ mean](double value) { return std::pow(value - mean, 2); }); double s_dev {std::sqrt(std::accumulate(std::begin(log_values), std::end(log_values), 0.0) / (log_values.size() - 1))}; std::cout For generated values, mean = mean standard deviation = s_dev std::endl; }
各位读者可自行拷贝代码查看运行结果。通过查看结果,可以看到对数的值是正态分布的,它是一幅标准差很小的狭窄图形。
21181.html
gohtml相关文章
- c++回调函数详解及实现(lambda)
- 【贪玩巴斯】C/C++文件IO流操作的 seekp和seekg详解「建议收藏」
- 剑指 Offer 30. 包含min函数的栈C++(详解)
- C++ 中的getline()函数用法详解
- c++ byte与int详解程序员
- VC++实现图片的旋转详解编程语言
- C++函数的高级特性详解编程语言
- C++字符串函数详解
- C++ deque使用、创建及初始化详解
- C++ hash(STL hash)及其函数模板用法详解
- C++ 自定义比较函数(map和multimap)详解
- C++ set用法(STL set用法)详解
- C++ find_if_not(STL find_if_not)查找算法详解
- C++ accumulate函数用法详解
- C++ setw:格式化输出(详解版)
- C++随机数(rand和srand)函数用法详解
- C++类成员函数定义方法详解
- C++类对象作为函数参数传递详解
- C++字符串查找函数详解
- C++格式化输出(详解版)
- C++ seekg函数用法详解
- C++二进制文件读写(read和write)详解
- C++阶乘函数(递归)详解
- C++快速排序(递归)算法详解
- c++显式类型转换示例详解