我在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;
}
请帮帮我。寻找任何提示。谢谢。
答案 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;
}