Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add safety check to gsl_ran_flat. #1035

Merged
merged 1 commit into from
Nov 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 5 additions & 3 deletions cpp/functions/add_mutation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <fwdpy11/rng.hpp>
#include <fwdpy11/types/DiploidPopulation.hpp>
#include <fwdpy11/policies/mutation.hpp>
#include <core/internal/gsl_ran_flat.hpp>
#include <fwdpp/ts/marginal_tree_functions/nodes.hpp>
#include <fwdpp/ts/table_collection_functions.hpp>
#include <fwdpp/ts/marginal_tree_functions/samples.hpp>
Expand Down Expand Up @@ -243,8 +244,8 @@ namespace
return static_cast<std::int64_t>(std::ceil(mutation_node_time));
}
// choose a random time
auto candidate_time = gsl_ran_flat(rng.get(), mutation_node_time,
node_table[mutation_node_parent].time);
auto candidate_time = fwdpy11_core::internal::gsl_ran_flat(
rng, mutation_node_time, node_table[mutation_node_parent].time);
if (candidate_time < 0.0)
{
return static_cast<std::int64_t>(std::floor(mutation_node_time));
Expand Down Expand Up @@ -386,7 +387,8 @@ add_mutation(const fwdpy11::GSLrng_t& rng, const double left, const double right
empty, pop.mutations, pop.mut_lookup, false, mutation_node_time,
// The lambdas will simply transfer input parameters to the new object.
[&rng, &candidate_data]() {
return gsl_ran_flat(rng.get(), candidate_data.left, candidate_data.right);
return fwdpy11_core::internal::gsl_ran_flat(rng, candidate_data.left,
candidate_data.right);
},
[&data]() { return data.effect_size; },
[&data](double) { return data.dominance; }, [&data]() { return data.esizes; },
Expand Down
54 changes: 29 additions & 25 deletions cpp/gsl/gsl_random.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,39 +20,43 @@
#include <pybind11/pybind11.h>
#include <fwdpy11/rng.hpp>
#include <gsl/gsl_randist.h>
#include <core/internal/gsl_ran_flat.hpp>

namespace py = pybind11;

void
init_gsl_random(py::module& m)
{
m.def("gsl_ran_gaussian_ziggurat",
[](const fwdpy11::GSLrng_t& rng, const double sd) {
return gsl_ran_gaussian_ziggurat(rng.get(), sd);
},
"Gaussian deviate with mean zero");
m.def(
"gsl_ran_gaussian_ziggurat",
[](const fwdpy11::GSLrng_t& rng, const double sd) {
return gsl_ran_gaussian_ziggurat(rng.get(), sd);
},
"Gaussian deviate with mean zero");

m.def("gsl_rng_uniform",
[](const fwdpy11::GSLrng_t& rng) {
return gsl_rng_uniform(rng.get());
},
"Uniform deviate on interval [0,1)");
m.def(
"gsl_rng_uniform",
[](const fwdpy11::GSLrng_t& rng) { return gsl_rng_uniform(rng.get()); },
"Uniform deviate on interval [0,1)");

m.def("gsl_ran_flat",
[](const fwdpy11::GSLrng_t& rng, double a, double b) {
return gsl_ran_flat(rng.get(), a, b);
},
"Unform deviate on interval [a,b)");
m.def(
"gsl_ran_flat",
[](const fwdpy11::GSLrng_t& rng, double a, double b) {
return fwdpy11_core::internal::gsl_ran_flat(rng, a, b);
},
"Unform deviate on interval [a,b)");

m.def("gsl_ran_poisson",
[](const fwdpy11::GSLrng_t& rng, double mean) {
return gsl_ran_poisson(rng.get(), mean);
},
"Poisson deviate parameterized by mean.");
m.def(
"gsl_ran_poisson",
[](const fwdpy11::GSLrng_t& rng, double mean) {
return gsl_ran_poisson(rng.get(), mean);
},
"Poisson deviate parameterized by mean.");

m.def("gsl_ran_geometric",
[](const fwdpy11::GSLrng_t& rng, const double p) {
return gsl_ran_geometric(rng.get(), p);
},
"Geometric distribution parameterized by success probability.");
m.def(
"gsl_ran_geometric",
[](const fwdpy11::GSLrng_t& rng, const double p) {
return gsl_ran_geometric(rng.get(), p);
},
"Geometric distribution parameterized by success probability.");
}
3 changes: 2 additions & 1 deletion cpp/ts/infinite_sites.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <cmath>
#include <algorithm>
#include <core/internal/gsl_ran_flat.hpp>
#include <fwdpp/ts/recycling.hpp>
#include <fwdpp/ts/mutate_tables.hpp>
#include <fwdpp/ts/count_mutations.hpp>
Expand All @@ -20,7 +21,7 @@ namespace
const fwdpy11::mutation_origin_time generation)
{
const auto uniform
= [left, right, &rng]() { return gsl_ran_flat(rng.get(), left, right); };
= [left, right, &rng]() { return fwdpy11_core::internal::gsl_ran_flat(rng, left, right); };
const auto return_zero = []() { return 0.0; };
const auto return_zero_h = [](const double) { return 0.0; };
auto key = fwdpy11::infsites_Mutation(recycling_bin, pop.mutations,
Expand Down
7 changes: 6 additions & 1 deletion fwdpy11/headers/fwdpy11/regions/Region.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,12 @@ namespace fwdpy11
inline double
operator()(const GSLrng_t& rng) const
{
return gsl_ran_flat(rng.get(), beg, end);
auto rv = gsl_ran_flat(rng.get(), beg, end);
while (rv == end)
{
rv = gsl_ran_flat(rng.get(), beg, end);
}
return rv;
}

inline bool
Expand Down
11 changes: 8 additions & 3 deletions fwdpy11/headers/fwdpy11/regions/UniformS.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,15 @@ namespace fwdpy11
return infsites_Mutation(
recycling_bin, mutations, lookup_table, false, generation,
[this, &rng]() { return region(rng); },
[this, &rng]() { return gsl_ran_flat(rng.get(), lo, hi) / scaling; },
[this, &rng](const double esize) {
return dominance(rng, esize);
[this, &rng]() {
auto rv = gsl_ran_flat(rng.get(), lo, hi);
while (rv == hi)
{
rv = gsl_ran_flat(rng.get(), lo, hi);
}
return rv / scaling;
},
[this, &rng](const double esize) { return dominance(rng, esize); },
this->label());
}

Expand Down
21 changes: 21 additions & 0 deletions lib/core/internal/gsl_ran_flat.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once

#include <fwdpy11/rng.hpp>
#include <gsl/gsl_randist.h>

namespace fwdpy11_core
{
namespace internal
{
inline auto
gsl_ran_flat(const fwdpy11::GSLrng_t& rng, double lo, double hi)
{
auto rv = gsl_ran_flat(rng.get(), lo, hi);
while (rv == hi)
{
rv = gsl_ran_flat(rng.get(), lo, hi);
}
return rv;
}
}
}
3 changes: 2 additions & 1 deletion lib/mutation_dominance/dependency_injection.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <cmath>
#include <stdexcept>
#include <functional>
#include <core/internal/gsl_ran_flat.hpp>
#include <gsl/gsl_randist.h> // FIXME: hide in static lib
#include <fwdpp/util/validators.hpp>
#include <fwdpy11/mutation_dominance/MutationDominance.hpp>
Expand Down Expand Up @@ -46,7 +47,7 @@ namespace fwdpy11
throw std::invalid_argument("hi must be > lo");
}
return MutationDominance([lo, hi](const GSLrng_t& rng, const double) {
return gsl_ran_flat(rng.get(), lo, hi);
return fwdpy11_core::internal::gsl_ran_flat(rng, lo, hi);
});
}

Expand Down