C++ 中的广义极值分布 (GEV)

Generalized Extreme Value Distribution in C++ (GEV)

GEV 分布 (http://en.wikipedia.org/wiki/Generalized_extreme_value_distribution) 有 3 个参数:

μ ∈ R — 位置,

σ > 0 — 尺度

ξ ∈ R — 形状

不过C++11库只支持一个extreme_value_distribution,只支持2个参数:

http://www.cplusplus.com/reference/random/extreme_value_distribution/

所以这个实现缺少形状参数 (ξ)。有没有办法在 C++ 中使用 GEV 分布生成随机数?

编辑:维基百科建议 GEV 可以从 EV、Weibull 和 Frechet 构建。所以看来可以用EV和C++中的Weibull实现来构造。

我不是概率论者,但我有理由相信您可以找到累积分布函数的反函数并将其应用于从 (0,1) 上的均匀分布中获取的值。来自提供的维基百科 link,一般情况的倒数是

F^-1(x; mu, sigma, xi) = mu + ((-ln x)^(-xi) - 1)*sigma/xi

(假设我没有失误,但很容易检查自己)。您所要做的就是将此函数应用于从统一 (0,1] 中提取的值,并且应根据需要分配结果值。当然,如果您尝试计算值,则 xi = 0 的情况将失败这样,但无论如何,这种情况是由 extreme_value_distribution 实现的。

抱歉格式问题,我熟悉 LaTeX,但完全不熟悉如何在此处发表评论时使用它。

我使用 wolfram alpha 找到了 ξ!=0 的 GEV 的 IDCF:here 和 ξ==0: here

这是一个实现:

#include <iostream>
#include <random>
#include <cmath> 

double icdf(double x, double mu, double sigma, double xi)
{
    if(xi == 0)
    {
        return (mu - sigma * log(-log(x))); 
    }
    else
    {
        double a = pow(-1*log(x),-1*xi);
        double b = -1*xi*mu*pow(-log(x),xi);
        double c = sigma * pow(-log(x),xi) - sigma;
        return (-1)*(a*(b+c) )/xi;
    }
}

int main()
{
    std::default_random_engine generator;
    std::uniform_real_distribution<double> distribution(0,1);

    for (int i=0; i<10000; ++i)
    {
        double number = distribution(generator);
        std::cout << icdf(number, 11.328, 2.909, -0.177) << std::endl;
    }

    return 0;
}

我在 Matlab 中分析了数据,看起来不错。