davidrpugh / population-ecology-approach

0 stars 2 forks source link

Spurious coexistence of "altruism" and "selfishness"? #3

Closed davidrpugh closed 9 years ago

davidrpugh commented 9 years ago

In the examples directory I have created a number of scripts which, for different parameterizations of the model, generate equilibrium population shares that exhibit what appear to be examples of coexistence of "altruism" and "selfishness".

Computing equilibria

So far all of my example scripts focus on edge cases. For example, in random-signaling/random_signaling_equilibria.py parameters are:

# females send random signals, but males screen with high precision
params = {'dA': 0.5, 'da': 0.5, 'eA': 1.0, 'ea': 1.0, 'PiaA': 6.0, 'PiAA': 5.0,
          'Piaa': 4.0, 'PiAa': 3.0}

whereas in random-signaling/almost_random_signaling_equilibria.py parameters are:

# females send almost random signals, but males screen with high precision
eps = 1e-3
params = {'dA': 0.5 + eps, 'da': 0.5 + eps, 'eA': 1.0, 'ea': 1.0,
          'PiaA': 6.0, 'PiAA': 5.0, 'Piaa': 4.0, 'PiAa': 3.0}

Model parameterizations used in random-screening/random_screening_equilibria.py and random-screening/almost_random_screening.py are similar in spirit.

Experiment with initial conditions

For a given dictionary of parameters values, I generate an array of random initial conditions for population shares using the Dirichlet distribution:

# create an array of initial guesses for root finder
N = 250
prng = np.random.RandomState(42)
initial_males = prng.dirichlet(np.ones(4), size=N)
initial_females = initial_males
initial_guesses = np.hstack((initial_males, initial_females))

I then loop over the initial conditions, solve for the steady state equilibrium population shares, and plot each result.

Equilibrium population shares with random signaling

It appears that, no matter the initial condition, the the equilibrium population is composed of both GA (i.e., "altruistic") and ga (i.e., "selfish") genotypes. The exact frequency of altruistic vs. selfish genotypes depends entirely on the initial condition given to the solver. A typical example output from the solver looks as follows.

Out[182]: 
  status: 0
 success: True
    njev: 18
    nfev: 18
     fun: 9.1829762721241014e-14
       x: array([  5.88492764e-01,   3.47450892e-07,   2.69747709e-07,
         4.11506619e-01,   6.41270308e-01,   6.50879918e-07,
         1.00000138e-15,   3.58729041e-01])
 message: 'Optimization terminated successfully.'
     jac: array([  4.30526387e-08,  -7.91127591e-08,  -4.21485044e-08,
        -6.15688333e-08,  -6.43479419e-08,   3.42203858e-07,
        -2.32562527e-07,   4.57884472e-08,   0.00000000e+00])
     nit: 18

Note that the value of the objective is fun: 9.1829762721241014e-14 which indicates that we have found a global minimum of the objective (which by construction is a root of our non-linear system). Also note that this is an interior equilibrium with m_GA = 0.59, m_ga = 0.41, f_GA = 0.64, f_ga = 0.36 (with all other population shares are essentially zero).

Dynamic (in)stability

Unfortunately, it seems like the above identified equilibria are not dynamically stable. I first simulated an plotted trajectories for various initial conditions.

Simulated trajectories for various initial conditions.

Note that instead of converging to any of the interior equilibria, the trajectories of the model seem to converge toward m_GA = f_GA = 1.0 (with all other population shares roughly zero).

To double check this result, I then simulated trajectories starting from the identified steady state equilibria. If the identified equilibria where dynamically unstable, then any trajectory using one of the equilibria as an initial condition should eventually diverge away due to accumulation of numerical error. This is exactly what we observe.

Dynamic instability of interior equilibria.

@markeschaffer, do these results confirm your priors?

markeschaffer commented 9 years ago

OK, let’s see if replying to a GitHub email works as advertised….

Consider the case where males screen perfectly. No mistakes. This is just like coexistence of (competition between) two separate species. One species is GA, one is ga, and there are no cross-matings. So if e_A = e_a = 1, and if these are basically two species, then

S(G,A) = S(g,a) = 1

S(G,a) = S(g,A) = 0

m_Ga = m_gA = f_Ga = f_gA = 0

And if you plug these into the recurrence relations, I think you'll find that any split between GA and ga is an equilibrium.

Which makes sense, sort of. The model has been rigged so that the extra fecundity that cooperation creates in the GA species translates into more females sent out to look for groups to join. It does NOT translate into more groups to join. Think of a fixed number of family plots that belong to the males and get handed down generation to generation.

We set it up this way because we wanted competition to take place only via the number of females sent out to look for groups to join.

But most (all?) of these will be knife-edge equilibria, because as soon as you allow for imperfect mate selection, you get competition between (1) the larger number of females carrying A sent out by cooperator groups, and (2) the larger number of females carrying a sent out by non-cooperators exploiting the cooperative partner. In the cases we've look at so far, this seems to converge to either an all-A or an all-a equilibrium.

Does this make sense to you too?

davidrpugh commented 9 years ago

@markeschaffer

This does make sense. In order to test the hypothesis that these are knife edge equilibria I can check whether the solver returns such equilibria with the following parameterization:

# females send random signals and male screening is slightly imperfect
eps = 1e-3
params = {'dA': 0.5, 'da': 0.5, 'eA': 1 - eps, 'ea': 1 - eps, 'PiaA': 6.0, 'PiAA': 5.0,
          'Piaa': 4.0, 'PiAa': 3.0}
davidrpugh commented 9 years ago

This issue is no longer relevant given that we have moved to a new prisoner's dilemma payoff matrix where "selfish" females have a higher payoff when they are relatively scarce in the population.