代码之家  ›  专栏  ›  技术社区  ›  Cleo B.

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

  •  -2
  • Cleo B.  · 技术社区  · 7 年前

    我在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::正态分布<gt;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;
    }
    

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

    2 回复  |  直到 7 年前
        1
  •  4
  •   Aconcagua    7 年前

    好吧,麻烦永无止境。。。

    # include frame.distribution
    

    包含的语法为:

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

    (中间的空间 # include 不会造成伤害,但绝对罕见……)

    Frame DistributionModel(x_mu, x_sigma)
    

    C++是一种强类型语言,也就是说,你不能像Python那样给变量命名,但你需要给它们一个类型!

    Frame DistributionModel(double x_mu, double x_sigma)
    

    局部变量相同;类型必须与实际分配的内容匹配(除非使用自动)

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

    这对于C++来说有点特殊:您可以定义一个局部变量,例如。

     std::vector<int> v;
    

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

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

    您在示例中看到的是一个称为“统一初始化”的功能,它使用大括号而不是括号。不过,我个人强烈反对它的使用,所以你永远不会在我编写的代码中看到它(请参阅我构建 std::normal_distribution 以上。

    std::正态分布 在标题中定义 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 的关键字。虽然 汽车 带来了很多好处,我不建议出于特定目的使用它:使用显式返回类型,函数的用户可以从签名中看到期望的结果,而不必查看函数体来了解。

    std::正态分布 现在是一个数字生成器;它不会像python等效程序那样一次交付整个序列,您需要显式地逐个绘制值:

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

    nd(gen) : std::正态分布 提供函数调用运算符 operator() ,因此的对象可以像函数一样调用(在C++术语中,这样的对象称为“functor”)。然而,函数调用需要一个随机数生成器作为参数,因此我们需要像您看到的示例中那样提供它。综合起来:

    #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;
    }
    
        2
  •  0
  •   prabhuiitdhn    3 年前
    #include<iostream>
    #include<random>
    #include<chrono>
    
    int main() {
        unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
        std::default_random_engine generator(seed);
        std::normal_distribution<double> distribution(0.0, 3.0);
        double number = abs(distribution(generator));
        std::cout << number;
        std::cin.get();
        return 0;
    }
    

    这可能有助于使用高斯平均值=0.0和std\u dev=3.0创建一个随机数