"""Mating-system tests (pure NumPy) — monogamy vs promiscuity as mate-pool breadth (E14). Cover the diversity helpers and the two load-bearing behaviours: promiscuity (wide mate-pool breadth) monotonically destroys standing diversity, and the run is deterministic and well-formed. The full ruggedness crossover (intermediate breadth wins the champion on rugged landscapes) is a swept, multi-replicate result asserted only in aggregate here to keep the test fast. """ from __future__ import annotations import numpy as np from knowledge.mating_system import _distinct_peaks, _diversity, run_mating_system from knowledge.genotype import nk_fitness def _run(breadth: float, K: int = 6, seed: int = 0, gens: int = 40, N: int = 32, L: int = 10): cfg = {"mating": {"L": L, "N": N, "breadth": breadth, "K": K, "recomb_rate": 0.5, "mu": 0.005}, "generations": gens} return run_mating_system(cfg, seed=seed) def test_diversity_zero_for_clones_and_positive_for_spread(): clones = np.ones((5, 8), dtype=np.int8) assert _diversity(clones) == 0.0 # identical -> no diversity spread = np.array([[0] * 8, [1] * 8], dtype=np.int8) assert np.isclose(_diversity(spread), 1.0) # opposite -> maximal diversity def test_distinct_peaks_counts_basins(): fitness = nk_fitness(6, 2, seed=0) pop = np.zeros((4, 6), dtype=np.int8) # all identical -> one basin assert _distinct_peaks(pop, fitness, 6) == 1 def test_schema_and_bounds(): df = _run(0.5) for col in ["generation", "best_fitness", "mean_fitness", "diversity", "distinct_peaks", "global_opt"]: assert col in df.columns assert (df["best_fitness"] <= df["global_opt"] + 1e-9).all() # nothing beats reality's optimum assert (df["diversity"] >= 0).all() and (df["diversity"] <= 1).all() assert df["distinct_peaks"].iloc[-1] >= 1 def test_deterministic_given_seed(): a = _run(0.3, seed=7) b = _run(0.3, seed=7) assert np.allclose(a["best_fitness"], b["best_fitness"]) # pure function of the seed def test_promiscuity_destroys_diversity(): # Averaged over replicates, wide mate-pool breadth (promiscuity) leaves LESS standing diversity than # narrow breadth (monogamy) — the homogenisation effect, robust on a rugged landscape. def final_div(b): return np.mean([_run(b, K=8, seed=s, gens=40, N=32, L=10)["diversity"].iloc[-1] for s in range(6)]) assert final_div(1.0) < final_div(0.05) # panmixia < isolation-by-distance