#c
Вопрос:
Я хотел бы передать функции случайного распределения (они могут отличаться в зависимости от того, что я хочу, что может измениться), поэтому я хотел бы, чтобы они были функцией параметров по существу, как я могу этого достичь?
auto GenerateRandomVector(double amp;mean, double amp;SD, int amp;VecSize) -> std::vector<double> {
std::random_device rnd_device;
std::mt19937 mersenne_engine {rnd_device()};
std::normal_distribution<double> dist {mean, SD}; //Hw do I make this an argument?
auto gen = [amp;dist, amp;mersenne_engine]() {
return dist(mersenne_engine);
};
std::vector<int> vec(VecSize);
std::generate(vec.begin(), vec.end(), gen);
return vec;
}
Ответ №1:
Вы просто берете его по ссылке (если хотите сохранить его внутреннее состояние) или передаете по значению.
Пример использования ссылок:
std::mt19937amp; prng() {
thread_local std::mt19937 mersenne_engine(std::random_device{}());
return mersenne_engine;
}
std::vector<double> GenerateRandomVector(doubleamp; mean, doubleamp; SD,
std::size_t VecSize,
std::normal_distribution<double>amp; dist)
{
auto gen = [amp;dist](){ return dist(prng()); };
std::vector<double> vec(VecSize); // Note: `double`, not `int`
std::generate(vec.begin(), vec.end(), gen);
mean = std::accumulate(vec.begin(), vec.end(), 0.) / vec.size();
return vec;
}
Примечание: Не инициализируйте новый PRNG каждый раз, когда вы звоните GenerateRandomVector
. Инициализируйте один PRNG и используйте его везде, как я показал выше.
Если вам нужно поддерживать другие типы дистрибутивов, вы можете сделать его шаблоном функции:
template<class Dist>
auto GenerateRandomVector(doubleamp; mean, doubleamp; SD,
std::size_t VecSize, Distamp; dist)
{
using result_type = typename Dist::result_type;
auto gen = [amp;dist](){ return dist(prng()); };
std::vector<result_type> vec(VecSize); // type depends on Dist
std::generate(vec.begin(), vec.end(), gen);
mean = std::accumulate(vec.begin(), vec.end(), 0.) / vec.size();
return vec;
}
Если вы используете C 11, вам необходимо добавить конечный тип возврата:
template<class Dist>
auto GenerateRandomVector(double amp;mean, double amp;SD, std::size_t VecSize,
Distamp; dist) -> std::vector<typename Dist::result_type>
{
Комментарии:
1. Что, если вместо этого я захочу использовать дистрибутив? Например, равномерное распределение и все остальные вместо этого? Как бы я смог их передать? Могу ли я просто просто создать шаблон?
2. @Steveit Да, я добавил это в качестве примера
3. это потрясающе, я определенно попробую еще раз!
4. Да, это работает просто отлично, большое вам спасибо!
5. просто вопрос, как мне принять ответ