高斯在C ++中的随机正态分布

时间:2018-04-03 23:48:45

标签: c++ statistics

我在Python中使用我的函数进行正态分发。我需要将它转换为C ++,我不熟悉语言。

这是我的Python:

def calculation(value):
    sigma = 0.5
    size = 10000
    x = 200

    x_distribution = np.random.normal(value, sigma, size)
    for i in x_distribution:
        x.append(i)
    return x

它按预期工作。我试图用C ++重写相同的东西,只发现Link和“std :: normal_distribution<> d {5,2}; “必须制造魔法。但我无法弄清楚如何实施。

这是我尝试过的,但它失败了。

# include frame.distribution
Frame DistributionModel(x_mu, x_sigma)
{
    // Motion model;ignore it
    model = std::normal_distribution<> d{x_mu,x_sigma};

    return model;
}

请帮帮我。寻找任何提示。谢谢。

1 个答案:

答案 0 :(得分:3)

好吧,麻烦没有结束......

# include frame.distribution

包含的语法是:

#include <name_of_header_file>
// or:
#include "name_of_header_file"

#include之间的空格不会造成伤害,但绝对不常见......)

Frame DistributionModel(x_mu, x_sigma)

C ++是一种强类型语言,i。即你不能像Python一样给变量赋一个名字,但你需要给它们一个类型!

Frame DistributionModel(double x_mu, double x_sigma)

局部变量相同; type必须与您实际分配的内容相匹配(除非使用auto)

std::normal_distribution<double> nd(x_mu, x_sigma);

这对C ++有点特殊:你定义一个局部变量,e。克。

 std::vector<int> v;

对于类,它已经使用其默认构造函数构造。如果要使用参数调用构造函数,只需将调用追加到变量名称:

 std::vector<int> v(10); // vector with 10 elements.

您在示例中看到的是一个名为&#34;统一初始化&#34;的功能,使用大括号而不是括号。不过,我个人强烈反对它的使用,所以你在我编写的代码中看不到它(见我构建上面的std::normal_distribution ...)。

std::normal_distribution在标头random中定义,因此您需要包含它(函数定义之前):

#include <random>

关于返回值:如果在某处定义了数据类型,则只能返回Frame。在尝试定义新类之前,我们只能使用现有的类:std::vector(它虽然是模板类)。向量与python列表非常相似,它是一个容器类,在连续的内存中存储了许多对象;但是,除了python列表之外,存储的所有元素的类型必须相同。我们可以使用这样的向量来收集结果:

std::vector<double> result;

这样的向量可以动态增长,但是,这可能导致重新分配内部存储器的必要性。昂贵。如果你事先知道了元素的数量,你也可以告诉向量提前分配足够的内存:

result.reserve(max);

向量是我们要返回的,所以我们需要调整函数签名(我允许给它一个不同的名称并添加另一个参数):

std::vector<double> getDistribution(double x_mu, double x_sigma, size_t numberOfValues)

可以让编译器使用auto关键字来推断返回类型。虽然auto带来了很多好处,但我不建议将其用于特定目的:使用显式返回类型,函数的用户可以从签名中看到期望的结果类型,而不必查看功能体了解。

std::normal_distribution现在是一个数字生成器;它不会像python等效的那样立即传递整个序列,你需要明确地绘制值:

while(numberOfValues-- > 0)
{
    auto value = nd(gen);
    result.push_back(value);
}

nd(gen)std::normal_distribution提供了一个函数调用操作符operator(),因此可以像函数一样调用对象(这些对象被称为&#34;仿函数&#34;在C ++术语中)。但是,函数调用需要一个随机数生成器作为参数,因此我们需要在您看到的示例中提供它。全部放在一起:

#include <random>
#include <vector>

std::vector<double> getDistribution
(
    double x_mu, double x_sigma, size_t numberOfValues
)
{
    // shortened compared to your example:
    std::mt19937 gen((std::random_device())());
    // create temporary (anonymous)     ^^
    // instance and call it immediately    ^^
    // afterwards

    std::normal_distribution<double> nd(x_mu, x_sigma);
    std::vector<double> result;
    result.reserve(numberOfValues);
    while(numberOfValues-- > 0)
    {
        // shorter than above: using result of previous
        // function (functor!) call directly as argument to next one
        result.push_back(nd(gen));
    }

    // finally something familiar from python:
    return result;
}