With mutation, equation (1) reads


The difficulty with adding mutation to this model is how to define the mapping between genotype space and phenotype space, or in other words, what defines the embryology. A few studies, including Ray's Tierra world, do this with an explicit mapping from the genotype to to some particular organism property (e.g. interpreted as machine language instructions, or as weight in a neural net). These organisms then interact with one another to determine the population dynamics. In this model, however, we are doing away with the organismal layer, and so an explicit embryology is impossible. The only possibility left is to use a statistical model of embryology. The mapping between genotype space and the population parameters , is expected to look like a rugged landscape, however, if two genotypes are close together (in a Hamming sense) then one might expect that the phenotypes are likely to be similar, as would the population parameters. This I call random embryology with locality.

In the simple case of point mutations, the probability of any child lying distance in genotype space from its parent follows a Poisson distribution. Random embryology with locality implies that the phenotypic parameters are distributed randomly about the parent species, with a standard deviation that depends monotonically on the genotypic displacement. The simplest such model is to distribute the phenotypic parameters in a Gaussian fashion about the parent's values, with standard deviation proportional to the genotypic displacement. This constant of proportionality can be conflated with the species' intrinsic mutation rate, to give rise another phenotypic parameter . It is assumed that the probability of a mutation generating a previously existing species is negligible, and can be ignored. We also need another arbitrary parameter , “species radius”, or ecolab.sp_sep, which can be understood as the minimum genotypic distance separating species, conflated with the same constant of proportionality as .

In summary, the mutation algorithm is as follows:

  1. The number of mutant species arising from species within a timestep is . This number is rounded stochastically to the nearest integer, e.g. 0.25 is rounded up to 1 25% of the time and down to 0 75% of the time.

  2. Roll a random number from a Poisson distribution to determine the standard deviation of phenotypic variation.

  3. Vary according to a Gaussian distribution about the parents' values, with as the standard deviation, where is the range of values that is initialised to, ie =ecolab.repro_max ecolab.repro_min

  4. The diagonal part of must be negative, so vary according to a log-normal distribution. This means that if the old value is , the new value becomes . These values cannot become arbitrarily small, however, as this would imply that some species make arbitrarily small demands on the environment, and will become infinite in number. In Eco Lab, the diagonal interactions terms are prevented from becoming larger than .

  5. The offdiagonal components of , are varied in a similar fashion to . However new connections are added, or old ones removed according to , where is chosen from a stepped uniform distribution

    where (default of 0) is specified by the TCL variable generalization_bias. The values on the new connections are chosen from the same initial distribution that the offdiagonal values where originally set with, ie the range ecolab.odiag_min to ecolab.odiag_max. Since in condition (8) is computationally expensive, we use a slightly stronger criterion that is sufficient, computationally tractable yet still allows “interesting” non-definite matrix behaviour namely that the sum should be nonpositive.

  6. must be positive, so should evolve according to the log-normal distribution like the diagonal components of . Similar to , it is a catastrophe to allow to become arbitrarily large. In the real world, mutation normally exists at some fixed background rate -- species can reduce the level of mutation by improving their genetic repair algorithms. In Eco Lab, this ceiling on is given by the ecolab.mut_max variable.