在C/ c++中生成正态分布后的随机数

时间:2021-10-06 01:05:48

Does anyone know how I could easily generate random numbers following a normal distribution in C/C++ ?

有人知道在C/ c++中,我可以很容易地生成随机数吗?

http://www.mathworks.com/access/helpdesk/help/toolbox/stats/normrnd.html

http://www.mathworks.com/access/helpdesk/help/toolbox/stats/normrnd.html

I don't want to use any of Boost.

我不想使用任何Boost。

I know that Knuth talks about this at length but I don't have his books at hand right now.

我知道Knuth说了很多,但是我现在手头没有他的书。

16 个解决方案

#1


81  

The Box-Muller transform is what is commonly used. This correctly produces values with a normal distribution.

框-穆勒变换是常用的变换。这将正确地生成正态分布的值。

http://en.wikipedia.org/wiki/Normal_distribution#Generating_values_from_normal_distribution

http://en.wikipedia.org/wiki/Normal_distribution Generating_values_from_normal_distribution

http://en.wikipedia.org/wiki/Box_Muller_transform

http://en.wikipedia.org/wiki/Box_Muller_transform

The math is easy. You generate two uniform numbers and from those you get two normally distributed numbers. Return one, save the other for the next request of a random number.

数学很容易。你生成两个统一的数字,从那些你得到两个正态分布的数字。返回一个,将另一个保存为下一个随机数请求。

#2


39  

EDIT: Since 12 August 2011 we have C++11 which directly offers std::normal_distribution, which is the way I would go today.

编辑:自2011年8月12日起,我们有c++ 11直接提供std::normal_distribution,这是我今天的方式。

Here's the original Answer:

这是最初的回答:

Here are some solutions ordered by ascending complexity.

以下是一些由上升复杂度排序的解决方案。

  1. Add 12 uniform numbers from 0 to 1 and subtract 6. This will match mean and standard deviation of a normal variable. An obvious drawback is that the range is limited to +/-6 - unlike a true normal distribution.

    从0到1加12个数,减去6。这将匹配正常变量的均值和标准差。一个明显的缺点是范围被限制在+/-6 -不像真正的正态分布。

  2. Box-Muller transform - was listed above, and is relatively simple to implement. If you need very precise samples however, be aware that the Box-Muller transform combined with some uniform generators suffers from an anomaly called Neave Effect.

    上面列出了Box-Muller变换,它的实现相对简单。但是,如果您需要非常精确的样本,请注意,Box-Muller变换结合一些均匀的发电机,遭受一种称为Neave效应的异常。

    H. R. Neave, “On using the Box-Muller transformation with multiplicative congruential pseudorandom number generators,” Applied Statistics, 22, 92-97, 1973

    “用乘法同余伪随机数发生器的盒-缪勒变换”,应用统计学,22,92-97,1973。

  3. For best precision I suggest drawing uniforms and applying the inverse cumulative normal distribution to arrive at normally distributed variates. You can find a very good algorithm for the inverse cumulative normal distribution at

    为了达到最佳的精度,我建议绘制校服,并应用逆累积正态分布来达到通常分布的变量。你可以找到一个很好的算法来求逆累积正态分布

https://web.archive.org/web/20151030215612/http://home.online.no/~pjacklam/notes/invnorm/

https://web.archive.org/web/20151030215612/http:/ / home.online.no / ~ pjacklam / notes / invnorm /

Hope that helps

希望这有助于

Peter

彼得

#3


26  

A quick and easy method is just to sum a number of evenly distributed random numbers and take their average. See the Central Limit Theorem for a full explanation of why this works.

一个快速而简单的方法就是把一些均匀分布的随机数相加,然后取它们的平均值。请参阅中心极限定理,以了解它为何有效。

#4


18  

I created a C++ open source project for normally distributed random number generation benchmark.

我为正态分布的随机数生成基准创建了一个c++开源项目。

It compares several algorithms, including

它比较了几种算法,包括。

  • Central limit theorem method
  • 中心极限定理的方法
  • Box-Muller transform
  • Box-Muller变换
  • Marsaglia polar method
  • 马极坐标法
  • Ziggurat algorithm
  • 金字形神塔算法
  • Inverse transform sampling method.
  • 逆变换抽样方法。
  • cpp11random uses C++11 std::normal_distribution with std::minstd_rand (it is actually Box-Muller transform in clang).
  • cpp11random使用c++ 11 std::normal_distribution with std::minstd_rand(它实际上是clang中的Box-Muller变换)。

The results of single-precision (float) version on iMac Corei5-3330S@2.70GHz , clang 6.1, 64-bit:

iMac Corei5-3330S@2.70GHz, clang 6.1, 64位的单精度(浮动)版本结果:

在C/ c++中生成正态分布后的随机数

For correctness, the program verifies the mean, standard deviation, skewness and kurtosis of the samples. It was found that CLT method by summing 4, 8 or 16 uniform numbers do not have good kurtosis as the other methods.

为保证正确性,程序验证样本的均值、标准差、偏度和峰度。结果表明,将4、8、16个等数相加得到的CLT方法比其他方法的峰度不高。

Ziggurat algorithm has better performance than the others. However, it does not suitable for SIMD parallelism as it needs table lookup and branches. Box-Muller with SSE2/AVX instruction set is much faster (x1.79, x2.99) than non-SIMD version of ziggurat algorithm.

Ziggurat算法具有比其他算法更好的性能。但是,它不适合SIMD并行,因为它需要表查找和分支。带有SSE2/AVX指令集的Box-Muller比非simd版本的ziggurat算法要快得多(x1.79, x2.99)。

Therefore, I will suggest using Box-Muller for architecture with SIMD instruction sets, and may be ziggurat otherwise.

因此,我建议使用SIMD指令集使用Box-Muller作为架构,否则可能是ziggurat。


P.S. the benchmark uses a simplest LCG PRNG for generating uniform distributed random numbers. So it may not be sufficient for some applications. But the performance comparison should be fair because all implementations uses the same PRNG, so the benchmark mainly tests the performance of the transformation.

基准测试使用最简单的LCG PRNG来生成均匀分布随机数。所以对某些应用来说可能是不够的。但是性能比较应该是公平的,因为所有实现都使用相同的PRNG,因此基准测试主要测试转换的性能。

#5


13  

Here's a C++ example, based on some of the references. This is quick and dirty, you are better off not re-inventing and using the boost library.

这里有一个c++示例,基于一些引用。这是快速和肮脏的,您最好不要重新发明和使用boost库。

#include "math.h" // for RAND, and rand
double sampleNormal() {
    double u = ((double) rand() / (RAND_MAX)) * 2 - 1;
    double v = ((double) rand() / (RAND_MAX)) * 2 - 1;
    double r = u * u + v * v;
    if (r == 0 || r > 1) return sampleNormal();
    double c = sqrt(-2 * log(r) / r);
    return u * c;
}

You can use a Q-Q plot to examine the results and see how well it approximates a real normal distribution (rank your samples 1..x, turn the ranks into proportions of total count of x ie. how many samples, get the z-values and plot them. An upwards straight line is the desired result).

你可以用Q-Q图来检验结果,看看它是如何接近真实的正态分布的。x,将秩变为x的总数的比例。有多少个样本值,得到z值并绘制出来。向上的直线是期望的结果)。

#6


12  

Use std::tr1::normal_distribution.

使用std::tr1::normal_distribution。

The std::tr1 namespace is not a part of boost. It's the namespace that contains the library additions from the C++ Technical Report 1 and is available in up to date Microsoft compilers and gcc, independently of boost.

tr1命名空间不是boost的一部分。它是一个名称空间,它包含了来自c++技术报告1的库,它可以在最新的Microsoft编译器和gcc中使用,独立于boost。

#7


11  

This is how you generate the samples on a modern C++ compiler.

这就是如何在现代c++编译器上生成示例的方法。

#include <random>
...
std::mt19937 generator;
double mean = 0.0;
double stddev  = 1.0;
std::normal_distribution<double> normal(mean, stddev);
cerr << "Normal: " << normal(generator) << endl;

#8


4  

You can use the GSL. Some complete examples are given to demonstrate how to use it.

您可以使用GSL。给出了一些完整的示例来演示如何使用它。

#9


4  

Have a look on: http://www.cplusplus.com/reference/random/normal_distribution/. It's the simplest way to produce normal distributions.

看看:http://www.cplusplus.com/reference/random/normal_distribution/。这是生成正态分布最简单的方法。

#10


3  

If you're using C++11, you can use std::normal_distribution:

如果使用c++ 11,可以使用std::normal_distribution:

#include <random>

std::default_random_engine generator;
std::normal_distribution<double> distribution(/*mean=*/0.0, /*stddev=*/1.0);

double randomNumber = distribution(generator);

There are many other distributions you can use to transform the output of the random number engine.

可以使用许多其他分布来转换随机数引擎的输出。

#11


3  

I've followed the definition of the PDF given in http://www.mathworks.com/help/stats/normal-distribution.html and came up with this:

我遵循了http://www.mathworks.com/help/stats/normal-distribution.html中给出的PDF的定义,得出了以下结论:

const double DBL_EPS_COMP = 1 - DBL_EPSILON; // DBL_EPSILON is defined in <limits.h>.
inline double RandU() {
    return DBL_EPSILON + ((double) rand()/RAND_MAX);
}
inline double RandN2(double mu, double sigma) {
    return mu + (rand()%2 ? -1.0 : 1.0)*sigma*pow(-log(DBL_EPS_COMP*RandU()), 0.5);
}
inline double RandN() {
    return RandN2(0, 1.0);
}

It is maybe not the best approach, but it's quite simple.

这可能不是最好的方法,但很简单。

#12


0  

Box-Muller implementation:

Box-Muller实现:

#include <cstdlib>
#include <cmath>
#include <ctime>
#include <iostream>
using namespace std;
 // return a uniformly distributed random number
double RandomGenerator()
{
  return ( (double)(rand()) + 1. )/( (double)(RAND_MAX) + 1. );
}
 // return a normally distributed random number
double normalRandom()
{
  double y1=RandomGenerator();
  double y2=RandomGenerator();
  return cos(2*3.14*y2)*sqrt(-2.*log(y1));
}

int main(){
double sigma = 82.;
double Mi = 40.;
  for(int i=0;i<100;i++){
double x = normalRandom()*sigma+Mi;
    cout << " x = " << x << endl;
  }
  return 0;
}

#13


-1  

Take a look at what I found.

看看我发现了什么。

This library uses the Ziggurat algorithm.

这个库使用Ziggurat算法。

#14


-1  

The comp.lang.c FAQ list shares three different ways to easily generate random numbers with a Gaussian distribution.

comp.lang。c FAQ列表提供了三种不同的方法,可以轻松生成带有高斯分布的随机数。

You may take a look of it: http://c-faq.com/lib/gaussian.html

您可以查看它:http://c-faq.com/lib/gaussian.html

#15


-1  

There exist various algorithms for the inverse cumulative normal distribution. The most popular in quantitative finance are tested on http://chasethedevil.github.io/post/monte-carlo--inverse-cumulative-normal-distribution/

反累积正态分布有多种算法。在定量金融中最流行的是在http://chasethedevil.github.io/post/monte-carlo-反累积-正态分布/上进行测试

In addition, it shows the drawback of Ziggurat like approaches.

此外,它还显示了Ziggurat类方法的缺点。

#16


-3  

Computer is deterministic device. There is no randomness in calculation. Moreover arithmetic device in CPU can evaluate summ over some finite set of integer numbers (performing evaluation in finite field) and finite set of real rational numbers. And also performed bitwise operations. Math take a deal with more great sets like [0.0, 1.0] with infinite number of points.

电脑是确定性的设备。计算没有随机性。此外,CPU中的算术设备可以对有限整数集(有限域内的运算)和有限有理数集求和。并进行位操作。数学处理更大的集合,比如[0.0,1.0],有无数个点。

You can listen some wire inside of computer with some controller, but would it have uniform distributions? I don't know. But if assumed that it's signal is the the result of accumulate values huge amount of independent random variables then you will receive approximately normal distributed random variable (It was proved in Probability Theory)

你可以用一些控制器监听计算机内部的电线,但是它会有均匀分布吗?我不知道。但如果假设它的信号是累积值的结果大量的独立随机变量那么你将会得到近似正态分布随机变量(在概率论中得到了证明)

There is exist algorithms called - pseudo random generator. As I feeled the purpose of pseudo random generator is to emulate randomness. And the criteria of goodnes is: - the empirical distribution is converged (in some sense - pointwise, uniform, L2) to theoretical - values that you receive from random generator are seemed to be idependent. Of course it's not true from 'real point of view', but we assume it's true.

有一种算法叫做-伪随机生成器。当我感觉到伪随机生成器的目的是模拟随机性。goodnes的准则是:-经验分布(在某种意义上-点向,均匀,L2)收敛于理论-你从随机生成器得到的值似乎是理想的。当然,从“真实的观点”来看,这不是真的,但我们认为这是真的。

One of the popular method - you can summ 12 i.r.v with uniform distributions....But to be honest during derivation Central Limit Theorem with helping of Fourier Transform, Taylor Series, it is neededed to have n->+inf assumptions couple times. So for example theoreticaly - Personally I don't undersand how people perform summ of 12 i.r.v. with uniform distribution.

一种流行的方法-你可以把12。v ....均匀分布但老实说,在推导中心极限定理的时候借助傅里叶变换,泰勒级数,我们需要n->+inf假设。比如理论上,我不理解人们如何用均匀分布来计算12个i.r.v.的总和。

I had probility theory in university. And particulary for me it is just a math question. In university I saw the following model:

我在大学里学过证明理论。尤其对我来说,这只是一个数学问题。在大学里,我看到了下面的模型:


double generateUniform(double a, double b)
{
  return uniformGen.generateReal(a, b);
}

double generateRelei(double sigma)
{
  return sigma * sqrt(-2 * log(1.0 - uniformGen.generateReal(0.0, 1.0 -kEps)));
}
double generateNorm(double m, double sigma)
{
  double y2 = generateUniform(0.0, 2 * kPi);
  double y1 = generateRelei(1.0);
  double x1 = y1 * cos(y2);
  return sigma*x1 + m;
}

Such way how todo it was just an example, I guess it exist another ways to implement it.

这样做只是一个例子,我猜还有另外一种实现它的方法。

Provement that it is correct can be found in this book "Moscow, BMSTU, 2004: XVI Probability Theory, Example 6.12, p.246-247" of Krishchenko Alexander Petrovich ISBN 5-7038-2485-0

《莫斯科,BMSTU, 2004: XVI概率论》,例6.12,p。克利须琴科·亚历山大·彼得罗维奇ISBN: 5-7038-2485-0

Unfortunately I don't know about existence of translation of this book into English.

不幸的是,我不知道这本书是否有翻译成英语的可能。

#1


81  

The Box-Muller transform is what is commonly used. This correctly produces values with a normal distribution.

框-穆勒变换是常用的变换。这将正确地生成正态分布的值。

http://en.wikipedia.org/wiki/Normal_distribution#Generating_values_from_normal_distribution

http://en.wikipedia.org/wiki/Normal_distribution Generating_values_from_normal_distribution

http://en.wikipedia.org/wiki/Box_Muller_transform

http://en.wikipedia.org/wiki/Box_Muller_transform

The math is easy. You generate two uniform numbers and from those you get two normally distributed numbers. Return one, save the other for the next request of a random number.

数学很容易。你生成两个统一的数字,从那些你得到两个正态分布的数字。返回一个,将另一个保存为下一个随机数请求。

#2


39  

EDIT: Since 12 August 2011 we have C++11 which directly offers std::normal_distribution, which is the way I would go today.

编辑:自2011年8月12日起,我们有c++ 11直接提供std::normal_distribution,这是我今天的方式。

Here's the original Answer:

这是最初的回答:

Here are some solutions ordered by ascending complexity.

以下是一些由上升复杂度排序的解决方案。

  1. Add 12 uniform numbers from 0 to 1 and subtract 6. This will match mean and standard deviation of a normal variable. An obvious drawback is that the range is limited to +/-6 - unlike a true normal distribution.

    从0到1加12个数,减去6。这将匹配正常变量的均值和标准差。一个明显的缺点是范围被限制在+/-6 -不像真正的正态分布。

  2. Box-Muller transform - was listed above, and is relatively simple to implement. If you need very precise samples however, be aware that the Box-Muller transform combined with some uniform generators suffers from an anomaly called Neave Effect.

    上面列出了Box-Muller变换,它的实现相对简单。但是,如果您需要非常精确的样本,请注意,Box-Muller变换结合一些均匀的发电机,遭受一种称为Neave效应的异常。

    H. R. Neave, “On using the Box-Muller transformation with multiplicative congruential pseudorandom number generators,” Applied Statistics, 22, 92-97, 1973

    “用乘法同余伪随机数发生器的盒-缪勒变换”,应用统计学,22,92-97,1973。

  3. For best precision I suggest drawing uniforms and applying the inverse cumulative normal distribution to arrive at normally distributed variates. You can find a very good algorithm for the inverse cumulative normal distribution at

    为了达到最佳的精度,我建议绘制校服,并应用逆累积正态分布来达到通常分布的变量。你可以找到一个很好的算法来求逆累积正态分布

https://web.archive.org/web/20151030215612/http://home.online.no/~pjacklam/notes/invnorm/

https://web.archive.org/web/20151030215612/http:/ / home.online.no / ~ pjacklam / notes / invnorm /

Hope that helps

希望这有助于

Peter

彼得

#3


26  

A quick and easy method is just to sum a number of evenly distributed random numbers and take their average. See the Central Limit Theorem for a full explanation of why this works.

一个快速而简单的方法就是把一些均匀分布的随机数相加,然后取它们的平均值。请参阅中心极限定理,以了解它为何有效。

#4


18  

I created a C++ open source project for normally distributed random number generation benchmark.

我为正态分布的随机数生成基准创建了一个c++开源项目。

It compares several algorithms, including

它比较了几种算法,包括。

  • Central limit theorem method
  • 中心极限定理的方法
  • Box-Muller transform
  • Box-Muller变换
  • Marsaglia polar method
  • 马极坐标法
  • Ziggurat algorithm
  • 金字形神塔算法
  • Inverse transform sampling method.
  • 逆变换抽样方法。
  • cpp11random uses C++11 std::normal_distribution with std::minstd_rand (it is actually Box-Muller transform in clang).
  • cpp11random使用c++ 11 std::normal_distribution with std::minstd_rand(它实际上是clang中的Box-Muller变换)。

The results of single-precision (float) version on iMac Corei5-3330S@2.70GHz , clang 6.1, 64-bit:

iMac Corei5-3330S@2.70GHz, clang 6.1, 64位的单精度(浮动)版本结果:

在C/ c++中生成正态分布后的随机数

For correctness, the program verifies the mean, standard deviation, skewness and kurtosis of the samples. It was found that CLT method by summing 4, 8 or 16 uniform numbers do not have good kurtosis as the other methods.

为保证正确性,程序验证样本的均值、标准差、偏度和峰度。结果表明,将4、8、16个等数相加得到的CLT方法比其他方法的峰度不高。

Ziggurat algorithm has better performance than the others. However, it does not suitable for SIMD parallelism as it needs table lookup and branches. Box-Muller with SSE2/AVX instruction set is much faster (x1.79, x2.99) than non-SIMD version of ziggurat algorithm.

Ziggurat算法具有比其他算法更好的性能。但是,它不适合SIMD并行,因为它需要表查找和分支。带有SSE2/AVX指令集的Box-Muller比非simd版本的ziggurat算法要快得多(x1.79, x2.99)。

Therefore, I will suggest using Box-Muller for architecture with SIMD instruction sets, and may be ziggurat otherwise.

因此,我建议使用SIMD指令集使用Box-Muller作为架构,否则可能是ziggurat。


P.S. the benchmark uses a simplest LCG PRNG for generating uniform distributed random numbers. So it may not be sufficient for some applications. But the performance comparison should be fair because all implementations uses the same PRNG, so the benchmark mainly tests the performance of the transformation.

基准测试使用最简单的LCG PRNG来生成均匀分布随机数。所以对某些应用来说可能是不够的。但是性能比较应该是公平的,因为所有实现都使用相同的PRNG,因此基准测试主要测试转换的性能。

#5


13  

Here's a C++ example, based on some of the references. This is quick and dirty, you are better off not re-inventing and using the boost library.

这里有一个c++示例,基于一些引用。这是快速和肮脏的,您最好不要重新发明和使用boost库。

#include "math.h" // for RAND, and rand
double sampleNormal() {
    double u = ((double) rand() / (RAND_MAX)) * 2 - 1;
    double v = ((double) rand() / (RAND_MAX)) * 2 - 1;
    double r = u * u + v * v;
    if (r == 0 || r > 1) return sampleNormal();
    double c = sqrt(-2 * log(r) / r);
    return u * c;
}

You can use a Q-Q plot to examine the results and see how well it approximates a real normal distribution (rank your samples 1..x, turn the ranks into proportions of total count of x ie. how many samples, get the z-values and plot them. An upwards straight line is the desired result).

你可以用Q-Q图来检验结果,看看它是如何接近真实的正态分布的。x,将秩变为x的总数的比例。有多少个样本值,得到z值并绘制出来。向上的直线是期望的结果)。

#6


12  

Use std::tr1::normal_distribution.

使用std::tr1::normal_distribution。

The std::tr1 namespace is not a part of boost. It's the namespace that contains the library additions from the C++ Technical Report 1 and is available in up to date Microsoft compilers and gcc, independently of boost.

tr1命名空间不是boost的一部分。它是一个名称空间,它包含了来自c++技术报告1的库,它可以在最新的Microsoft编译器和gcc中使用,独立于boost。

#7


11  

This is how you generate the samples on a modern C++ compiler.

这就是如何在现代c++编译器上生成示例的方法。

#include <random>
...
std::mt19937 generator;
double mean = 0.0;
double stddev  = 1.0;
std::normal_distribution<double> normal(mean, stddev);
cerr << "Normal: " << normal(generator) << endl;

#8


4  

You can use the GSL. Some complete examples are given to demonstrate how to use it.

您可以使用GSL。给出了一些完整的示例来演示如何使用它。

#9


4  

Have a look on: http://www.cplusplus.com/reference/random/normal_distribution/. It's the simplest way to produce normal distributions.

看看:http://www.cplusplus.com/reference/random/normal_distribution/。这是生成正态分布最简单的方法。

#10


3  

If you're using C++11, you can use std::normal_distribution:

如果使用c++ 11,可以使用std::normal_distribution:

#include <random>

std::default_random_engine generator;
std::normal_distribution<double> distribution(/*mean=*/0.0, /*stddev=*/1.0);

double randomNumber = distribution(generator);

There are many other distributions you can use to transform the output of the random number engine.

可以使用许多其他分布来转换随机数引擎的输出。

#11


3  

I've followed the definition of the PDF given in http://www.mathworks.com/help/stats/normal-distribution.html and came up with this:

我遵循了http://www.mathworks.com/help/stats/normal-distribution.html中给出的PDF的定义,得出了以下结论:

const double DBL_EPS_COMP = 1 - DBL_EPSILON; // DBL_EPSILON is defined in <limits.h>.
inline double RandU() {
    return DBL_EPSILON + ((double) rand()/RAND_MAX);
}
inline double RandN2(double mu, double sigma) {
    return mu + (rand()%2 ? -1.0 : 1.0)*sigma*pow(-log(DBL_EPS_COMP*RandU()), 0.5);
}
inline double RandN() {
    return RandN2(0, 1.0);
}

It is maybe not the best approach, but it's quite simple.

这可能不是最好的方法,但很简单。

#12


0  

Box-Muller implementation:

Box-Muller实现:

#include <cstdlib>
#include <cmath>
#include <ctime>
#include <iostream>
using namespace std;
 // return a uniformly distributed random number
double RandomGenerator()
{
  return ( (double)(rand()) + 1. )/( (double)(RAND_MAX) + 1. );
}
 // return a normally distributed random number
double normalRandom()
{
  double y1=RandomGenerator();
  double y2=RandomGenerator();
  return cos(2*3.14*y2)*sqrt(-2.*log(y1));
}

int main(){
double sigma = 82.;
double Mi = 40.;
  for(int i=0;i<100;i++){
double x = normalRandom()*sigma+Mi;
    cout << " x = " << x << endl;
  }
  return 0;
}

#13


-1  

Take a look at what I found.

看看我发现了什么。

This library uses the Ziggurat algorithm.

这个库使用Ziggurat算法。

#14


-1  

The comp.lang.c FAQ list shares three different ways to easily generate random numbers with a Gaussian distribution.

comp.lang。c FAQ列表提供了三种不同的方法,可以轻松生成带有高斯分布的随机数。

You may take a look of it: http://c-faq.com/lib/gaussian.html

您可以查看它:http://c-faq.com/lib/gaussian.html

#15


-1  

There exist various algorithms for the inverse cumulative normal distribution. The most popular in quantitative finance are tested on http://chasethedevil.github.io/post/monte-carlo--inverse-cumulative-normal-distribution/

反累积正态分布有多种算法。在定量金融中最流行的是在http://chasethedevil.github.io/post/monte-carlo-反累积-正态分布/上进行测试

In addition, it shows the drawback of Ziggurat like approaches.

此外,它还显示了Ziggurat类方法的缺点。

#16


-3  

Computer is deterministic device. There is no randomness in calculation. Moreover arithmetic device in CPU can evaluate summ over some finite set of integer numbers (performing evaluation in finite field) and finite set of real rational numbers. And also performed bitwise operations. Math take a deal with more great sets like [0.0, 1.0] with infinite number of points.

电脑是确定性的设备。计算没有随机性。此外,CPU中的算术设备可以对有限整数集(有限域内的运算)和有限有理数集求和。并进行位操作。数学处理更大的集合,比如[0.0,1.0],有无数个点。

You can listen some wire inside of computer with some controller, but would it have uniform distributions? I don't know. But if assumed that it's signal is the the result of accumulate values huge amount of independent random variables then you will receive approximately normal distributed random variable (It was proved in Probability Theory)

你可以用一些控制器监听计算机内部的电线,但是它会有均匀分布吗?我不知道。但如果假设它的信号是累积值的结果大量的独立随机变量那么你将会得到近似正态分布随机变量(在概率论中得到了证明)

There is exist algorithms called - pseudo random generator. As I feeled the purpose of pseudo random generator is to emulate randomness. And the criteria of goodnes is: - the empirical distribution is converged (in some sense - pointwise, uniform, L2) to theoretical - values that you receive from random generator are seemed to be idependent. Of course it's not true from 'real point of view', but we assume it's true.

有一种算法叫做-伪随机生成器。当我感觉到伪随机生成器的目的是模拟随机性。goodnes的准则是:-经验分布(在某种意义上-点向,均匀,L2)收敛于理论-你从随机生成器得到的值似乎是理想的。当然,从“真实的观点”来看,这不是真的,但我们认为这是真的。

One of the popular method - you can summ 12 i.r.v with uniform distributions....But to be honest during derivation Central Limit Theorem with helping of Fourier Transform, Taylor Series, it is neededed to have n->+inf assumptions couple times. So for example theoreticaly - Personally I don't undersand how people perform summ of 12 i.r.v. with uniform distribution.

一种流行的方法-你可以把12。v ....均匀分布但老实说,在推导中心极限定理的时候借助傅里叶变换,泰勒级数,我们需要n->+inf假设。比如理论上,我不理解人们如何用均匀分布来计算12个i.r.v.的总和。

I had probility theory in university. And particulary for me it is just a math question. In university I saw the following model:

我在大学里学过证明理论。尤其对我来说,这只是一个数学问题。在大学里,我看到了下面的模型:


double generateUniform(double a, double b)
{
  return uniformGen.generateReal(a, b);
}

double generateRelei(double sigma)
{
  return sigma * sqrt(-2 * log(1.0 - uniformGen.generateReal(0.0, 1.0 -kEps)));
}
double generateNorm(double m, double sigma)
{
  double y2 = generateUniform(0.0, 2 * kPi);
  double y1 = generateRelei(1.0);
  double x1 = y1 * cos(y2);
  return sigma*x1 + m;
}

Such way how todo it was just an example, I guess it exist another ways to implement it.

这样做只是一个例子,我猜还有另外一种实现它的方法。

Provement that it is correct can be found in this book "Moscow, BMSTU, 2004: XVI Probability Theory, Example 6.12, p.246-247" of Krishchenko Alexander Petrovich ISBN 5-7038-2485-0

《莫斯科,BMSTU, 2004: XVI概率论》,例6.12,p。克利须琴科·亚历山大·彼得罗维奇ISBN: 5-7038-2485-0

Unfortunately I don't know about existence of translation of this book into English.

不幸的是,我不知道这本书是否有翻译成英语的可能。