6

能够使用std <random>来生成不同概率分布的随机数很棒......现在,有没有办法使用标准库计算给定分布及其参数的一组数字的概率?

我知道我可以自己为任何分布编写概率密度和质量函数(参见下面的单个随机变量示例),但如果可以的话,我宁愿使用标准库。

long double exponential_pdf(long double x, long double rate) {

    if ( x < 0.0 ) {
        return 0.0;
    }
    if ( rate < 0.0 ) {
        return NOT_A_NUMBER;
    }
    auto    pdf = rate * exp( - rate * x);
    return  pdf;
}
4

3 回答 3

10

从 C++11 开始,标准库包含一系列可用于随机数生成的分布。不幸的是,标准库中没有计算概率密度、累积分布或分位数函数的功能。

至于为什么它没有包含在标准库中的理由,请参阅工作文件 N1398(强调我的)

一些库提供给定分布的概率密度函数作为该分布接口的一部分。虽然这可能偶尔有用,但本提案并未提供此类功能。一个原因是关注点分离:分布类模板可能受益于根据分布参数预先计算大型值表,而概率密度函数的计算则没有。此外,函数表示通常很简单,因此用户可以轻松地自己编写代码。

我不太同意这个推理:虽然密度函数确实很容易编码,但对于累积分布或分位数函数则不然。

作为一种解决方法,您可以访问Boost Math Toolkit。它使用与分布的标准库相同的名称,但允许您计算pdf()这些分布的更多属性。Boost 库通常会进入标准,如果不是,它们至少是平台独立的并且可以广泛使用。您的示例将类似于:

#include <iostream>
#include <boost/math/distributions/exponential.hpp>

using namespace boost::math;

int main() 
{
    auto const lambda = 1.0;
    auto d = exponential_distribution<>{lambda};
    std::cout << pdf(d, 0) << "\n"; // exp(0) = 1
    std::cout << pdf(d, 1) << "\n"; // exp(-1) = 0.367879
}

活生生的例子

于 2013-10-16T08:25:59.980 回答
0

此外,如果您已经在使用 C++17,那么还有一个有用的 opensouce 库RandLib。在您的示例中,您可以只写

#include “RandLib.h”

void main() {
    double lambda = 1;
    ExponentialRand X(lambda);
    X.f(0); //=1
}
于 2017-11-01T17:19:42.997 回答
-1

@杜杜

我不知道您使用的是哪个编译器,但请记住 Microsoft Visual C++ 编译器不支持 long double 基本类型。这种支持将强制编译器发出 x87 浮点代码。

于 2015-09-15T15:52:56.683 回答