使用头文件定义 mt19937 和 normal_distribution
Using a header file to define mt19937 and normal_distribution
我正在使用以下例程生成从 Gaussian/Normal 分布中选择的随机数:
当所有内容都在一个文件中进行编译时,它相当简单:
#include <iostream>
#include <math.h>
#include <random>
using namespace std;
int main()
{
double m;
double v;
int seed=100;
int samplesize=10;
double ls [samplesize]; //to store as a list
m = 0.0;
v = 0.05;
mt19937 e2(seed);
normal_distribution<float> dist(m, sqrt(v));
for (int i=0; i<samplesize; i++){
ls[i] = dist(e2);
cout << ls[i] << endl;
}
return 0;
}
现在我正在尝试做类似的事情,但我希望能够全局定义 e2
和 dist
,或者只是先在听者文件中定义 .h
和然后在我程序的各种 .C
文件中调用它们。
我的尝试使 运行 陷入 error: invalid use of non-static member function ‘std::mt19937 e2(int)’
类错误。
目的是:
- 在头文件中定义
e2
和 dist
。
- 在
.C
文件中播种 e2
,该文件加载包含给定种子的参数文件。
- 在我的
.C
文件中使用 dist(e2)
生成这样的数字。
我的尝试:
在头文件中我写了:
#include <random>
std::mt19937 e2(int sd); //sd for seed to be read from file later.
std::normal_distribution<float> dist(double meanNormal, double varNormal); //define generally, mean and var to be read from file.
然后在我读取参数的 setup.C
文件中,我尝试生成 e2
和 dist
:
的实例
e2(seed); //seed read from file before.
dist(mean,sqrt(var)); //mean and var are double variables defined in this file.
现在在我的主程序文件中,当我尝试使用 dist(e2)
从 dist
生成一个数字时,我得到一个非静态成员函数错误,如上所示。
任何有关如何实现这一目标的帮助将不胜感激。
那是因为在第一个示例中您声明了一个变量 e2
和 dist
,而在第二个示例中您定义了函数。
你要的是这个header:
#include <random>
std::mt19937 e2;
std::normal_distribution<float> dist;
在您的主文件或 .C
文件中,您应该:
e2 = std::mt19937(seed);
dist = normal_distribution<float>(m, sqrt(v));
您还应该包含一个 header 守卫以防止多次声明。我假设您已经有了一个,但为了简洁没有包含它。
您创建了 header 并声明了 2 个函数
std::mt19937 e2(int sd);
std::normal_distribution<float> dist(double meanNormal, double varNormal);
函数f2
接受一个参数,returnsstd::mt19937
object,函数dist
接受两个参数,returnsstd::normal_distribution
object。
在您的主文件中,您通过
调用了这些函数
e2(seed); //seed read from file before.
dist(mean,sqrt(var)); //mean and var are double variables defined in this file.
你在这一行遇到了编译器错误
ls[i] = dist(e2); // <----
因为你想用e2
函数作为参数调用dist
函数,这是不可能的。 dist
函数需要两个双参数。
如果你想将 dist
和 e2
视为全局变量以在多个源文件中生成随机值,你可以在 header 函数中这样声明
double myrandom ();
并将其定义为
double myrandom ()
{
static mt19937 e2(100);
static normal_distribution<float> dist(0.0, sqrt(0.05));
// e2 and dist will be created during first call of this function
return dist(e2);
}
你不能这样做。 std::mt19937 e2(int sd);
不太确定为什么您认为这会起作用...正如所指出的,这声明了一个函数。
你能做的就是把
std::mt19937 e2;
在您的头文件中,然后从您的 .cpp 文件调用
e2.seed(something);
然而,这似乎是一个很好的机会来制作一个小 class 来为您封装它。
class RNG_class {
private:
std::mt19937 e2;
std::normal_distribution<float> dist;
public:
RNG_class(int seed, double meanNormal, double varNormal) : e2(seed), dist(meanNormal, varNormal) {}
float get() {
return dist(e2);
}
};
从你的 .cpp
然后你可以做
RNG_class rng(100, m, sqrt(v));
...
ls[i] = rng.get();
我正在使用以下例程生成从 Gaussian/Normal 分布中选择的随机数:
当所有内容都在一个文件中进行编译时,它相当简单:
#include <iostream>
#include <math.h>
#include <random>
using namespace std;
int main()
{
double m;
double v;
int seed=100;
int samplesize=10;
double ls [samplesize]; //to store as a list
m = 0.0;
v = 0.05;
mt19937 e2(seed);
normal_distribution<float> dist(m, sqrt(v));
for (int i=0; i<samplesize; i++){
ls[i] = dist(e2);
cout << ls[i] << endl;
}
return 0;
}
现在我正在尝试做类似的事情,但我希望能够全局定义 e2
和 dist
,或者只是先在听者文件中定义 .h
和然后在我程序的各种 .C
文件中调用它们。
我的尝试使 运行 陷入 error: invalid use of non-static member function ‘std::mt19937 e2(int)’
类错误。
目的是:
- 在头文件中定义
e2
和dist
。 - 在
.C
文件中播种e2
,该文件加载包含给定种子的参数文件。 - 在我的
.C
文件中使用dist(e2)
生成这样的数字。
我的尝试:
在头文件中我写了:
#include <random>
std::mt19937 e2(int sd); //sd for seed to be read from file later.
std::normal_distribution<float> dist(double meanNormal, double varNormal); //define generally, mean and var to be read from file.
然后在我读取参数的 setup.C
文件中,我尝试生成 e2
和 dist
:
e2(seed); //seed read from file before.
dist(mean,sqrt(var)); //mean and var are double variables defined in this file.
现在在我的主程序文件中,当我尝试使用 dist(e2)
从 dist
生成一个数字时,我得到一个非静态成员函数错误,如上所示。
任何有关如何实现这一目标的帮助将不胜感激。
那是因为在第一个示例中您声明了一个变量 e2
和 dist
,而在第二个示例中您定义了函数。
你要的是这个header:
#include <random>
std::mt19937 e2;
std::normal_distribution<float> dist;
在您的主文件或 .C
文件中,您应该:
e2 = std::mt19937(seed);
dist = normal_distribution<float>(m, sqrt(v));
您还应该包含一个 header 守卫以防止多次声明。我假设您已经有了一个,但为了简洁没有包含它。
您创建了 header 并声明了 2 个函数
std::mt19937 e2(int sd);
std::normal_distribution<float> dist(double meanNormal, double varNormal);
函数f2
接受一个参数,returnsstd::mt19937
object,函数dist
接受两个参数,returnsstd::normal_distribution
object。
在您的主文件中,您通过
e2(seed); //seed read from file before.
dist(mean,sqrt(var)); //mean and var are double variables defined in this file.
你在这一行遇到了编译器错误
ls[i] = dist(e2); // <----
因为你想用e2
函数作为参数调用dist
函数,这是不可能的。 dist
函数需要两个双参数。
如果你想将 dist
和 e2
视为全局变量以在多个源文件中生成随机值,你可以在 header 函数中这样声明
double myrandom ();
并将其定义为
double myrandom ()
{
static mt19937 e2(100);
static normal_distribution<float> dist(0.0, sqrt(0.05));
// e2 and dist will be created during first call of this function
return dist(e2);
}
你不能这样做。 std::mt19937 e2(int sd);
不太确定为什么您认为这会起作用...正如所指出的,这声明了一个函数。
你能做的就是把
std::mt19937 e2;
在您的头文件中,然后从您的 .cpp 文件调用
e2.seed(something);
然而,这似乎是一个很好的机会来制作一个小 class 来为您封装它。
class RNG_class {
private:
std::mt19937 e2;
std::normal_distribution<float> dist;
public:
RNG_class(int seed, double meanNormal, double varNormal) : e2(seed), dist(meanNormal, varNormal) {}
float get() {
return dist(e2);
}
};
从你的 .cpp
然后你可以做
RNG_class rng(100, m, sqrt(v));
...
ls[i] = rng.get();