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

时间:2015-02-26 13:42:19

标签: c++ c++11 random distribution

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

μ∈R - 位置,

σ> 0 - 比例

ξ∈R - 形状

但是,C ++ 11库仅支持仅支持2个参数的extreme_value_distribution:

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

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

编辑:维基百科建议GEV可以由EV,Weibull和Frechet构建。所以它似乎可以通过在C ++中使用EV和Weibull实现来构建。

2 个答案:

答案 0 :(得分:1)

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

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

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

为格式化道歉,我熟悉LaTeX,但在这里评论时完全不熟悉如何使用它。

答案 1 :(得分:0)

我使用wolfram alpha为ξ!= 0:here找到了GEV的IDCF ξ== 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中分析了数据,看起来很棒。