# Path: stationary/utils/math_helpers.py
# def simplex_generator(N, d=2):
#     """
#     Generates a discretation of the simplex.
# 
#     Parameters
#     ----------
#     N: int
#         The number of subdivsions in each dimension
#     d: int, 2
#         The dimension of the simplex (the number of population types is d+1
# 
#     Yields
#     ------
#     (d+1)-tuples of numbers summing to N. The total number of yielded tuples is
#     equal to the simplicial polytopic number corresponding to N and d,
#     binom{N + d - 1}{d} (see https://en.wikipedia.org/wiki/Figurate_number )
#     """
# 
#     if d == 1:
#         for i in range(N+1):
#             yield (i, N - i)
#     if d > 1:
#         for j in range(N+1):
#             for s in simplex_generator(N - j, d - 1):
#                 t = [j]
#                 t.extend(s)
#                 yield tuple(t)
# 
# def dot_product(a, b):
#     c = 0
#     for i in range(len(a)):
#         c += a[i] * b[i]
#     return c


import numpy
from numpy import array, log, exp
from scipy.special import gammaln
from ..utils.math_helpers import simplex_generator, dot_product

    Returns
    -------
    edge_func: function on states x states
    """

    if num_types == 2:
        return multivariate_transitions_sub(
            N, incentive, mu=mu, low_memory=low_memory)

    M = cache_multinomial_coefficients(N, num_types=num_types)

    def multinomial_probability(xs, ps):
        xs, ps = array(xs), array(ps)
        result = M[xs[0]][xs[1]] + sum(xs * log(ps))
        return exp(result)

    def g(current_state, next_state):
        inc = incentive(current_state)
        ps = []
        s = float(sum(inc))
        if s == 0:
            raise ValueError(
                "You need to use a Fermi incentive to prevent division by zero."
            )
        half_mu = mu / 2.
        r = dot_product(inc, [1 - mu, half_mu, half_mu]) / s
        ps.append(r)
        r = dot_product(inc, [half_mu, 1 - mu, half_mu]) / s
        ps.append(r)

# Path: stationary/utils/math_helpers.py
# def simplex_generator(N, d=2):
#     """
#     Generates a discretation of the simplex.
# 
#     Parameters
#     ----------
#     N: int
#         The number of subdivsions in each dimension
#     d: int, 2
#         The dimension of the simplex (the number of population types is d+1
# 
#     Yields
#     ------
#     (d+1)-tuples of numbers summing to N. The total number of yielded tuples is
#     equal to the simplicial polytopic number corresponding to N and d,
#     binom{N + d - 1}{d} (see https://en.wikipedia.org/wiki/Figurate_number )
#     """
# 
#     if d == 1:
#         for i in range(N+1):
#             yield (i, N - i)
#     if d > 1:
#         for j in range(N+1):
#             for s in simplex_generator(N - j, d - 1):
#                 t = [j]
#                 t.extend(s)
#                 yield tuple(t)
# 
# def dot_product(a, b):
#     c = 0
#     for i in range(len(a)):
#         c += a[i] * b[i]
#     return c


# Path: stationary/processes/wright_fisher.py
import numpy
from numpy import array, log, exp
from scipy.special import gammaln
from ..utils.math_helpers import simplex_generator, dot_product


    Returns
    -------
    edge_func: function on states x states
    """

    if num_types == 2:
        return multivariate_transitions_sub(
            N, incentive, mu=mu, low_memory=low_memory)

    M = cache_multinomial_coefficients(N, num_types=num_types)

    def multinomial_probability(xs, ps):
        xs, ps = array(xs), array(ps)
        result = M[xs[0]][xs[1]] + sum(xs * log(ps))
        return exp(result)

    def g(current_state, next_state):
        inc = incentive(current_state)
        ps = []
        s = float(sum(inc))
        if s == 0:
            raise ValueError(
                "You need to use a Fermi incentive to prevent division by zero."
            )
        half_mu = mu / 2.
        r = dot_product(inc, [1 - mu, half_mu, half_mu]) / s
        ps.append(r)
        r = dot_product(inc, [half_mu, 1 - mu, half_mu]) / s
        ps.append(r)

        r = dot_product(inc, [half_mu, half_mu, 1 - mu]) / s