使用头文件定义 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;
}

现在我正在尝试做类似的事情,但我希望能够全局定义 e2dist,或者只是先在听者文件中定义 .h 和然后在我程序的各种 .C 文件中调用它们。 我的尝试使 运行 陷入 error: invalid use of non-static member function ‘std::mt19937 e2(int)’ 类错误。

目的是:

我的尝试:

在头文件中我写了:

#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 文件中,我尝试生成 e2dist:

的实例
e2(seed); //seed read from file before.
dist(mean,sqrt(var)); //mean and var are double variables defined in this file. 

现在在我的主程序文件中,当我尝试使用 dist(e2)dist 生成一个数字时,我得到一个非静态成员函数错误,如上所示。 任何有关如何实现这一目标的帮助将不胜感激。

那是因为在第一个示例中您声明了一个变量 e2dist,而在第二个示例中您定义了函数。

你要的是这个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::mt19937object,函数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 函数需要两个双参数。

如果你想将 diste2 视为全局变量以在多个源文件中生成随机值,你可以在 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();