# Path: stationary/utils/math_helpers.py
# def normalize(x):
#     s = float(sum(x))
#     for j in range(len(x)):
#         x[j] /= s
#     return x
# 
# def multiply_vectors(a, b):
#     c = []
#     for i in range(len(a)):
#         c.append(a[i]*b[i])
#     return c


from ..utils.math_helpers import normalize, multiply_vectors
    def p(pop):
        s = sum(pop)
        return math.pow(k, s-N)
    return p


def discrete_sigmoid(t, k_1=0.1, k_2=-1.1):
    # Adapted from
    # https://dinodini.wordpress.com/2010/04/05/normalized-tunable-sigmoid-functions/
    k_2 = -1 - k_1
    if t < 0:
        return 0
    if t <= 0.5:
        return k_1 * t / (k_1 - 2 * t + 1)
    else:
        return 0.5 + 0.5 * k_2 * (2 * t - 1.) / (k_2 - (2 * t - 1.) + 1)


def sigmoid_death(N, k_1=2, k_2=2):
    def p(pop):
        s = sum(pop)
        return discrete_sigmoid(float(s) / N, k_1=k_1, k_2=k_2)
    return p


def linear_death(N):
    def p(pop):
        s = sum(pop)
        if s == 1:
            return 0

# Path: stationary/utils/math_helpers.py
# def normalize(x):
#     s = float(sum(x))
#     for j in range(len(x)):
#         x[j] /= s
#     return x
# 
# def multiply_vectors(a, b):
#     c = []
#     for i in range(len(a)):
#         c.append(a[i]*b[i])
#     return c


# Path: stationary/processes/variable_population_size.py
from ..utils.math_helpers import normalize, multiply_vectors

    def p(pop):
        s = sum(pop)
        return math.pow(k, s-N)
    return p


def discrete_sigmoid(t, k_1=0.1, k_2=-1.1):
    # Adapted from
    # https://dinodini.wordpress.com/2010/04/05/normalized-tunable-sigmoid-functions/
    k_2 = -1 - k_1
    if t < 0:
        return 0
    if t <= 0.5:
        return k_1 * t / (k_1 - 2 * t + 1)
    else:
        return 0.5 + 0.5 * k_2 * (2 * t - 1.) / (k_2 - (2 * t - 1.) + 1)


def sigmoid_death(N, k_1=2, k_2=2):
    def p(pop):
        s = sum(pop)
        return discrete_sigmoid(float(s) / N, k_1=k_1, k_2=k_2)
    return p


def linear_death(N):
    def p(pop):
        s = sum(pop)
        if s == 1:
            return 0

        return float(s) / N