2

(質問を言い換えました)

ブースト正規分布のラッパー クラスを作成していますが、できるだけ効率的にしたいと考えています。

私が使用する場合:

double x = 0.0;
boost::variate_generator<boost::mt19937&,boost::normal_distribution<> > var_nor(rng, nd);
for (int i=0; i<20; i++) {
     double x = var_nor();
}

ループは正常に動作します。私の懸念は、メソッドが何度も呼び出されるため、不必要に何かを宣言したくないということです。コードを分割して、次の行をコンストラクターに入れてみました。

boost::variate_generator<boost::mt19937&,boost::normal_distribution<> > var_nor(rng, nd);

これを行うサンプルメソッドがあります:

     double x = var_nor();
     return x;

しかし、この場合、var_nor() (つまり、引数なし) が見つからないというエラーが表示されます。これらのブースト宣言で何が起こっているのか誰か教えてください。は何をしますか

boost:variate_generate など

行は実際にvar_norで行いますか? 私の限られた C++ の知識では、var_nor が 2 つの異なる署名で定義されているように見えます。

みんなありがとうピート

4

2 に答える 2

4

コードでvar_norは、関数ではなく変数であるため、署名はありません。をサポートしているため、関数のように動作variate_generatorできるオブジェクトを表します。operator()

コードでは、宣言と初期化var_norを同時に行います。および引数はrng、オブジェクトのコンストラクターnd渡されます。variate_generator

宣言をクラスのコンストラクターに移動したとき、コンストラクターでローカル変数var_norとして宣言していたので、他の場所で使用できなかったのも不思議ではありません。クラス全体で何かを利用できるようにするには、メンバー変数である必要があります。クラスでプライベートを宣言します。

class NormalDistribution
{
  boost::random::mt19937 _rng;
  boost::variate_generator<boost::mt19937&,boost::normal_distribution<> > var_nor;
public:
  NormalDistribution();
};

次に、コンストラクターで初期化します。

NormalDistribution::NormalDistribution():
  _rng(), var_nor(_rng, boost::normal_distribution<>(0.0, 1.0))
{ }

最初に初期化されるように、_rngメンバーを最初に宣言する必要があります。上記のように、パラメーターを省略して、コンストラクターに直接渡されるnd一時オブジェクトに置き換えることができます。normal_distributionvar_nor

これらの変更により、関数normal_distributionへの複数の呼び出しで同じオブジェクトを使用できるようになるはずです。sampleNormalDistribution

質問から削除したコードでは、変数宣言と関数宣言を混同していました。nd2 つのパラメーターを受け取り、 を返す関数として宣言しましたnormal_distribution。同様にvar_nor。本当にオブジェクトが欲しいときの機能でした。たまたま関数のように振る舞うオブジェクトだったので混乱しましたが、それでも単なるオブジェクトです。

于 2012-05-31T12:34:42.820 に答える
0

OK、ロブ・ケネディの回答を使用して最終バージョンを作業します。興味のある他の人のために:

// normaldistribution.h
#ifndef NORMALDISTRIBUTION_H
#define NORMALDISTRIBUTION_H

#include <boost/random.hpp>
#include <boost/random/normal_distribution.hpp>
class NormalDistribution
{
 public:
    NormalDistribution();
    double sample(void);
 private:
    // Use the boost random number generator
    boost::mt19937 rng;
    // Make a variate_generator OBJECT.
    boost::variate_generator<boost::mt19937&,boost::normal_distribution<> > var_nor;
};

#endif // NORMALDISTRIBUTION_H

// normaldistribution.cpp
NormalDistribution::NormalDistribution():
  rng(), var_nor(rng, boost::normal_distribution<>(0.0, 1.0))
{
    std::cout << "Called normal distribution constructor, passing up var_nor" << std::endl;
}

double NormalDistribution::sample(void) {
    double x = var_nor();
    return x;
}

// main.cpp
#include "normaldistribution.h"

int main(int argc, char *argv[])
{
    NormalDistribution *nd = new NormalDistribution();
    for (int i=0; i < 10; ++i)
    {
      double d = nd->sample();
      std::cout << d << std::endl;
    }
    return 0;
}
于 2012-05-31T12:53:08.163 に答える