Эффективное использование ускоренного распределения

(Перефразировал вопрос)

Я создаю класс-оболочку для ускорения нормального распространения и хочу сделать его максимально эффективным.

Если я использую:

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 etc.

линия на самом деле делать сvar_nor? With my limited C++ knowledge, it looks as if var_nor is being defined with two different signatures.

Спасибо, парни Пит

 Kerrek SB31 мая 2012 г., 11:37
Конструктор причудливый: он определил некоторые совершенно бесполезные локальные переменные и не может инициализировать ни одного из членов класса. Возможно, пришло время для хорошей книги по C ++?

Ответы на вопрос(2)

Хорошо, рабочая окончательная версия с использованием ответа Роба Кеннеди для других, которые могут быть заинтересованы:

// 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;
}
 Pete85521702 июн. 2012 г., 11:20
var_nor и rng теперь приватные
 31 мая 2012 г., 15:55
Не вижу причин дляrng а такжеvar_nor быть публичным.
Решение Вопроса

В вашем кодеvar_nor этоvariable, а не функция, поэтому она не имеет подписи. Это представляетvariate_generator объект, который можетbehave like функция, потому что она поддерживаетoperator().

В своем коде вы объявляете и инициализируетеvar_nor в то же время.rng а такжеnd аргументы передаютсяconstructor изvariate_generator объект.

Когда вы переместили объявление в конструктор вашего класса, вы объявилиvar_nor какlocal variable в конструкторе, поэтому неудивительно, что он не был доступен в другом месте. Чтобы что-то было доступно в течение всего класса, оно должно бытьmember variable, Объявите это частным в классе:

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_distribution Объект передан непосредственно вvar_nor конструктор, как показано выше.

С этими изменениями вы сможете использовать тот жеnormal_distribution возражать против нескольких звонков на вашsample функция, или что-либо другое, что вы используете для вашегоNormalDistribution учебный класс.

В коде, который вы с тех пор удалили из своего вопроса, вы путали объявления переменных с объявлениями функций. Вы объявилиnd как функция, получающая два параметра и возвращающаяnormal_distribution, Аналогично сvar_nor, Это была функция, когда вы действительно хотели объект. Вы были сбиты с толку, потому что это был объект, который действует как функция, но он все еще просто объект.

 Pete85521731 мая 2012 г., 14:39
Спасибо, Роб, это проясняет ситуацию. Я пропустил распознавание перегруженного ().

Ваш ответ на вопрос