NeatEvolution.jl v0.1.1
Bug Fixes
- CTRNN forward Euler integration — The double-buffered integration read from the wrong buffer after the swap, using state from two steps ago instead of the previous step. This effectively doubled the time constant for all CTRNN networks. Single-step computations were unaffected, but multi-step advance! calls produced incorrect dynamics.
- IZNN spike threshold — Changed from v > 30 to v >= 30 to match the Izhikevich (2003) paper and the neat-python implementation. A neuron at exactly v=30 now correctly fires.
- BoolAttribute mutation — Mutation now flips the value (!value) instead of randomizing (rand(Bool)), which had a 50% chance of producing no change and halved the effective mutation rate. Matches neat-python behavior.
- FS-NEAT initialization — connect_fs_neat! now correctly selects a single random input and connects it to outputs (Feature-Selective NEAT), instead of connecting all inputs, which was identical to full connectivity.
- Crossover with unevaluated parents — When one parent had nothing fitness and the other had a real fitness value, the parent with real fitness is now correctly treated as fitter.
- Stagnation improvement detection — The improvement check now compares against the previous generation's fitness rather than the historical maximum. Previously, with non-max fitness functions (e.g., mean), a species could only be marked as improved if it exceeded its all-time best, which was strictly harder than intended.
- Missing post_evaluate! default — Added a default no-op method for the Reporter base type, preventing MethodError for custom reporter subtypes.
- Typo correction mapping — The config validator's suggestion for :max_generations now correctly points to :no_fitness_termination instead of the unrelated :fitness_threshold.
Added
- CITATION.cff for Zenodo DOI registration and standardized citation metadata.