90 const auto& existingNames = handle.getNames();
91 auto nameExists = [&](
const std::string& name) {
92 return std::find(existingNames.begin(), existingNames.end(), name) != existingNames.end();
96 if (!nameExists(
"uniform")) {
97 handle.add(
"uniform", [
this](
const std::vector<double>& args) ->
double {
98 if (args.size() != 2) {
99 throw std::runtime_error(
"uniform requires 2 arguments: min, max");
102 throw std::runtime_error(
"uniform: no RNG context set");
104 std::uniform_real_distribution<double> dist(args[0], args[1]);
105 return dist(*currentRng);
110 if (!nameExists(
"uniform_int")) {
111 handle.add(
"uniform_int", [
this](
const std::vector<double>& args) ->
double {
112 if (args.size() != 2) {
113 throw std::runtime_error(
"uniform_int requires 2 arguments: min, max");
116 throw std::runtime_error(
"uniform_int: no RNG context set");
118 std::uniform_int_distribution<int> dist(
static_cast<int>(args[0]),
static_cast<int>(args[1]));
119 return static_cast<double>(dist(*currentRng));
124 if (!nameExists(
"normal")) {
125 handle.add(
"normal", [
this](
const std::vector<double>& args) ->
double {
126 if (args.size() != 2) {
127 throw std::runtime_error(
"normal requires 2 arguments: mean, stddev");
130 throw std::runtime_error(
"normal: no RNG context set");
132 std::normal_distribution<double> dist(args[0], args[1]);
133 return dist(*currentRng);
138 if (!nameExists(
"exponential")) {
139 handle.add(
"exponential", [
this](
const std::vector<double>& args) ->
double {
140 if (args.size() != 1) {
141 throw std::runtime_error(
"exponential requires 1 argument: rate");
144 throw std::runtime_error(
"exponential: no RNG context set");
146 std::exponential_distribution<double> dist(args[0]);
147 return dist(*currentRng);
152 if (!nameExists(
"poisson")) {
153 handle.add(
"poisson", [
this](
const std::vector<double>& args) ->
double {
154 if (args.size() != 1) {
155 throw std::runtime_error(
"poisson requires 1 argument: mean");
158 throw std::runtime_error(
"poisson: no RNG context set");
160 std::poisson_distribution<int> dist(args[0]);
161 return static_cast<double>(dist(*currentRng));
166 if (!nameExists(
"bernoulli")) {
167 handle.add(
"bernoulli", [
this](
const std::vector<double>& args) ->
double {
168 if (args.size() != 1) {
169 throw std::runtime_error(
"bernoulli requires 1 argument: probability");
172 throw std::runtime_error(
"bernoulli: no RNG context set");
174 std::bernoulli_distribution dist(args[0]);
175 return dist(*currentRng) ? 1.0 : 0.0;
180 if (!nameExists(
"binomial")) {
181 handle.add(
"binomial", [
this](
const std::vector<double>& args) ->
double {
182 if (args.size() != 2) {
183 throw std::runtime_error(
"binomial requires 2 arguments: trials, probability");
186 throw std::runtime_error(
"binomial: no RNG context set");
188 std::binomial_distribution<int> dist(
static_cast<int>(args[0]), args[1]);
189 return static_cast<double>(dist(*currentRng));
194 if (!nameExists(
"gamma")) {
195 handle.add(
"gamma", [
this](
const std::vector<double>& args) ->
double {
196 if (args.size() != 2) {
197 throw std::runtime_error(
"gamma requires 2 arguments: shape, scale");
200 throw std::runtime_error(
"gamma: no RNG context set");
202 std::gamma_distribution<double> dist(args[0], args[1]);
203 return dist(*currentRng);
208 if (!nameExists(
"lognormal")) {
209 handle.add(
"lognormal", [
this](
const std::vector<double>& args) ->
double {
210 if (args.size() != 2) {
211 throw std::runtime_error(
"lognormal requires 2 arguments: logscale, shape");
214 throw std::runtime_error(
"lognormal: no RNG context set");
216 std::lognormal_distribution<double> dist(args[0], args[1]);
217 return dist(*currentRng);
222 if (!nameExists(
"geometric")) {
223 handle.add(
"geometric", [
this](
const std::vector<double>& args) ->
double {
224 if (args.size() != 1) {
225 throw std::runtime_error(
"geometric requires 1 argument: probability");
228 throw std::runtime_error(
"geometric: no RNG context set");
230 std::geometric_distribution<int> dist(args[0]);
231 return static_cast<double>(dist(*currentRng));