Program Listing for File popgenmut.hpp

Return to documentation for file (fwdpp/popgenmut.hpp)

#ifndef __FWDPP_SUGAR_MUTATION_POPGENMUT_HPP__
#define __FWDPP_SUGAR_MUTATION_POPGENMUT_HPP__

#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
#include <fwdpp/forward_types.hpp>
#include <fwdpp/tags/tags.hpp>
#include <fwdpp/io/scalar_serialization.hpp>
#include <fwdpp/io/mutation.hpp>
#include <fwdpp/simfunctions/recycling.hpp>
#include <limits>
#include <tuple>

namespace fwdpp
{
    struct popgenmut : public mutation_base
    {
        uint_t g;
        double s;
        double h;
        using constructor_tuple
            = std::tuple<double, double, double, unsigned, std::uint16_t>;

        popgenmut(const double &__pos, const double &__s, const double &__h,
                  const unsigned &__g, const std::uint16_t x = 0) noexcept
            : mutation_base(__pos, (__s == 0.) ? true : false, x), g(__g),
              s(__s), h(__h)
        {
        }

        popgenmut(constructor_tuple t) noexcept
            : mutation_base(std::get<0>(t),
                            (std::get<1>(t) == 0.) ? true : false,
                            std::get<4>(t)),
              g(std::get<3>(t)), s(std::get<1>(t)), h(std::get<2>(t))
        {
        }

        bool
        operator==(const popgenmut &rhs) const
        {
            return std::tie(this->g, this->s, this->h)
                       == std::tie(rhs.g, rhs.s, rhs.h)
                   && is_equal(rhs);
        }
    };

    template < typename mcont_t, typename lookup_table_t,
              typename position_function, typename effect_size_function,
              typename dominance_function>
    std::size_t
    infsites_popgenmut(flagged_mutation_queue &recycling_bin, mcont_t &mutations,
                       const gsl_rng *r, lookup_table_t &lookup,
                       const uint_t &generation, const double pselected,
                       const position_function &posmaker,
                       const effect_size_function &esize_maker,
                       const dominance_function &hmaker,
                       const decltype(popgenmut::xtra) x = 0)
    {
        auto pos = posmaker();
        while (lookup.find(pos) != lookup.end())
            {
                pos = posmaker();
            }
        bool selected = (gsl_rng_uniform(r) < pselected);
        auto idx = recycle_mutation_helper(
            recycling_bin, mutations, pos, (selected) ? esize_maker() : 0.,
            (selected) ? hmaker() : 0., generation, x);
        lookup.emplace(pos, idx);
        return idx;
    }

    namespace io
    {
        template <> struct serialize_mutation<popgenmut>
        {
            io::scalar_writer writer;
            serialize_mutation<popgenmut>() : writer{} {}
            template <typename streamtype>
            inline void
            operator()(streamtype &buffer, const popgenmut &m) const
            {
                writer(buffer, &m.g);
                writer(buffer, &m.pos);
                writer(buffer, &m.s);
                writer(buffer, &m.h);
                writer(buffer, &m.xtra);
            }
        };

        template <> struct deserialize_mutation<popgenmut>
        {
            io::scalar_reader reader;
            deserialize_mutation<popgenmut>() : reader{} {}
            template <typename streamtype>
            inline popgenmut
            operator()(streamtype &buffer) const
            {
                uint_t g;
                double pos, s, h;
                decltype(popgenmut::xtra) xtra;
                io::scalar_reader reader;
                reader(buffer, &g);
                reader(buffer, &pos);
                reader(buffer, &s);
                reader(buffer, &h);
                reader(buffer, &xtra);

                return popgenmut(pos, s, h, g, xtra);
            }
        };
    } // namespace io
} // namespace fwdpp
#endif