|
| 1 | +import random |
| 2 | + |
| 3 | +import numpy as np |
| 4 | +from scipy import stats |
| 5 | +from sugarscape_g1mt.model import SugarscapeG1mt, flatten |
| 6 | +from sugarscape_g1mt.trader_agents import Trader |
| 7 | + |
| 8 | +random.seed(1) |
| 9 | + |
| 10 | + |
| 11 | +def check_slope(y, increasing): |
| 12 | + x = range(len(y)) |
| 13 | + slope, intercept, _, p_value, _ = stats.linregress(x, y) |
| 14 | + result = (slope > 0) if increasing else (slope < 0) |
| 15 | + # p_value for significance. |
| 16 | + assert result and p_value < 0.05, (slope, p_value) |
| 17 | + |
| 18 | + |
| 19 | +def test_decreasing_price_variance(): |
| 20 | + # The variance of the average trade price should decrease over time (figure IV-3) |
| 21 | + # See Growing Artificial Societies p. 109. |
| 22 | + model = SugarscapeG1mt() |
| 23 | + model.datacollector._new_model_reporter( |
| 24 | + "price_variance", |
| 25 | + lambda m: np.var( |
| 26 | + flatten([a.prices for a in m.schedule.agents_by_type[Trader].values()]) |
| 27 | + ), |
| 28 | + ) |
| 29 | + model.run_model(step_count=50) |
| 30 | + |
| 31 | + df_model = model.datacollector.get_model_vars_dataframe() |
| 32 | + |
| 33 | + check_slope(df_model.price_variance, increasing=False) |
| 34 | + |
| 35 | + |
| 36 | +def test_carrying_capacity(): |
| 37 | + def calculate_carrying_capacities(enable_trade): |
| 38 | + carrying_capacities = [] |
| 39 | + visions = range(1, 10) |
| 40 | + for vision_max in visions: |
| 41 | + model = SugarscapeG1mt(vision_max=vision_max, enable_trade=enable_trade) |
| 42 | + model.run_model(step_count=50) |
| 43 | + carrying_capacities.append(len(model.schedule.agents_by_type[Trader])) |
| 44 | + return carrying_capacities |
| 45 | + |
| 46 | + # Carrying capacity should increase over mean vision (figure IV-6). |
| 47 | + # See Growing Artificial Societies p. 112. |
| 48 | + carrying_capacities_with_trade = calculate_carrying_capacities(True) |
| 49 | + check_slope( |
| 50 | + carrying_capacities_with_trade, |
| 51 | + increasing=True, |
| 52 | + ) |
| 53 | + # Carrying capacity should be higher when trade is enabled (figure IV-6). |
| 54 | + carrying_capacities_no_trade = calculate_carrying_capacities(False) |
| 55 | + check_slope( |
| 56 | + carrying_capacities_no_trade, |
| 57 | + increasing=True, |
| 58 | + ) |
| 59 | + |
| 60 | + t_statistic, p_value = stats.ttest_rel( |
| 61 | + carrying_capacities_with_trade, carrying_capacities_no_trade |
| 62 | + ) |
| 63 | + # t_statistic > 0 means carrying_capacities_with_trade has larger values |
| 64 | + # than carrying_capacities_no_trade. |
| 65 | + # p_value for significance. |
| 66 | + assert t_statistic > 0 and p_value < 0.05 |
| 67 | + |
| 68 | + |
| 69 | +# TODO: |
| 70 | +# 1. Reproduce figure IV-12 that the log of average price should decrease over average agent age |
| 71 | +# 2. Reproduce figure IV-13 that the gini coefficient on trade should decrease over mean vision, and should be higher with trade |
| 72 | +# 3. a stricter test would be to ensure the amount of variance of the trade price matches figure IV-3 |
0 commit comments