def two_dim_transitions_figure(N, m, mu=0.01, incentive_func=replicator): """ Plot transition entropies and stationary distributions. """ n = len(m[0]) fitness_landscape = linear_fitness_landscape(m) incentive = incentive_func(fitness_landscape) if not mu: mu = 1./ N edges = incentive_process.multivariate_transitions(N, incentive, num_types=n, mu=mu) s = stationary_distribution(edges, exact=True) d = edges_to_edge_dict(edges) # Set up plots gs = gridspec.GridSpec(3, 1) ax1 = pyplot.subplot(gs[0, 0]) ax1.set_title("Transition Probabilities") ups, downs, _ = two_dim_transitions(edges) xs = range(0, N+1) ax1.plot(xs, ups) ax1.plot(xs, downs) ax2 = pyplot.subplot(gs[1, 0]) ax2.set_title("Relative Entropy") divs1 = expected_divergence(edges) divs2 = expected_divergence(edges, q_d=0) plot_dictionary(divs1, ax=ax2) plot_dictionary(divs2, ax=ax2) ax3 = pyplot.subplot(gs[2, 0]) ax3.set_title("Stationary Distribution") plot_dictionary(s, ax=ax3) ax3.set_xlabel("Number of A individuals (i)")
def two_dim_transitions_figure(N, m, mu=0.01, incentive_func=replicator): """ Plot transition entropies and stationary distributions. """ n = len(m[0]) fitness_landscape = linear_fitness_landscape(m) incentive = incentive_func(fitness_landscape) if not mu: mu = 1. / N edges = incentive_process.multivariate_transitions(N, incentive, num_types=n, mu=mu) s = stationary_distribution(edges, exact=True) d = edges_to_edge_dict(edges) # Set up plots gs = gridspec.GridSpec(3, 1) ax1 = pyplot.subplot(gs[0, 0]) ax1.set_title("Transition Probabilities") ups, downs, _ = two_dim_transitions(edges) xs = range(0, N + 1) ax1.plot(xs, ups) ax1.plot(xs, downs) ax2 = pyplot.subplot(gs[1, 0]) ax2.set_title("Relative Entropy") divs1 = expected_divergence(edges) divs2 = expected_divergence(edges, q_d=0) plot_dictionary(divs1, ax=ax2) plot_dictionary(divs2, ax=ax2) ax3 = pyplot.subplot(gs[2, 0]) ax3.set_title("Stationary Distribution") plot_dictionary(s, ax=ax3) ax3.set_xlabel("Number of A individuals (i)")
def two_dim_transitions(edges): """ Compute the + and - transitions for plotting in two_dim_transitions_figure """ d = edges_to_edge_dict(edges) N = sum(edges[0][0]) ups = [] downs = [] stays = [] for i in range(0, N + 1): try: up = d[((i, N - i), (i + 1, N - i - 1))] except KeyError: up = 0 try: down = d[((i, N - i), (i - 1, N - i + 1))] except KeyError: down = 0 ups.append(up) downs.append(down) stays.append(1 - up - down) return ups, downs, stays
def two_dim_transitions(edges): """ Compute the + and - transitions for plotting in two_dim_transitions_figure """ d = edges_to_edge_dict(edges) N = sum(edges[0][0]) ups = [] downs = [] stays = [] for i in range(0, N+1): try: up = d[((i, N-i), (i+1, N-i-1))] except KeyError: up = 0 try: down = d[((i, N-i), (i-1, N-i+1))] except KeyError: down = 0 ups.append(up) downs.append(down) stays.append(1 - up - down) return ups, downs, stays
def exact_stationary(edges, initial_state=None, logspace=False): """ Computes the stationary distribution of a reversible process on the simplex exactly. No check for reversibility. Parameters ---------- edges: list or dictionary The edges or edge_dict of the process initial_state: tuple, None The initial state. If not given a suitable state is created. logspace: bool False Carry out the calculation in logspace returns ------- dictionary, the stationary distribution """ # Convert edges to edge_dict if necessary if isinstance(edges, list): edges = edges_to_edge_dict(edges) # Compute population parameters from the edge_dict state = list(edges)[0][0] N = sum(state) num_players = len(state) # Get an initial state if not initial_state: initial_state = [N // num_players] * num_players initial_state[-1] = N - (num_players - 1) * (N // num_players) initial_state = tuple(initial_state) # Use the exact form of the stationary distribution. d = dict() for state in simplex_generator(N, num_players - 1): # Take a path from initial to state. seq = [initial_state] e = list(seq[-1]) for i in range(0, num_players): while e[i] < state[i]: for j in range(0, num_players): if e[j] > state[j]: break e[j] = e[j] - 1 e[i] = e[i] + 1 seq.append(tuple(e)) while e[i] > state[i]: for j in range(0, num_players): if e[j] < state[j]: break e[j] = e[j] + 1 e[i] = e[i] - 1 seq.append(tuple(e)) if logspace: s = 0. else: s = 1. for index in range(len(seq) - 1): e, f = seq[index], seq[index + 1] if logspace: s += log(edges[(e, f)]) - log(edges[(f, e)]) else: s *= edges[(e, f)] / edges[(f, e)] d[state] = s if logspace: s0 = logsumexp([v for v in d.values()]) for key, v in d.items(): d[key] = exp(v - s0) else: s0 = 1. / sum([v for v in d.values()]) for key, v in d.items(): d[key] = s0 * v return d