SPB Git

spb/wp29_uqo

Public
3.7 KB · 85 lines python
1"""F5-conf-01: Walrasian equilibrium of a 2x2 Cobb-Douglas exchange economy.2Run from workspace root: ~/wp29/venv/bin/python out/analysis.py3Reads only data/; writes out/results.json deterministically. No randomness used."""4import json, math, os5import pandas as pd6from scipy.optimize import brentq78ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))9end = pd.read_csv(os.path.join(ROOT, "data", "endowments.csv"))10par = pd.read_csv(os.path.join(ROOT, "data", "parameters.csv"))11P = dict(zip(par["parameter"], par["value"].astype(float)))1213issues = []14# --- validation ---15assert not end.isna().any().any() and not par["value"].isna().any()16assert end["agent"].is_unique and set(end["agent"]) == {"A", "B"}17end = end.set_index("agent")18agents = ["A", "B"]19e1 = {a: float(end.loc[a, "good1"]) for a in agents}20e2 = {a: float(end.loc[a, "good2"]) for a in agents}21alpha = {a: P[f"alpha_{a}"] for a in agents}22valid = [a for a in agents if e1[a] > 0 and e2[a] > 0 and 0 < alpha[a] < 1]23assert valid == agents, "invalid agent parameters"2425E1 = sum(e1.values()); E2 = sum(e2.values())26E1_sheet = P["aggregate_endowment_good1"]; E2_sheet = P["aggregate_endowment_good2"]27for g, s, r in [(1, E1, E1_sheet), (2, E2, E2_sheet)]:28    if not math.isclose(s, r, rel_tol=1e-12):29        issues.append({30            "issue": f"parameters.csv aggregate_endowment_good{g} = {r} but sum of individual "31                     f"endowments in endowments.csv = {s}.",32            "handling": f"Used the sum of individual endowments ({s}) as the aggregate, since budgets are "33                        f"defined by individual endowments and endowments.csv is the primary data; using {r} "34                        f"would violate Walras' law. Summary-sheet value reported only as a sensitivity in report.md."})3536# --- demand and excess demand (p2 = 1) ---37def demand(a, p):38    m = p * e1[a] + e2[a]39    return alpha[a] * m / p, (1 - alpha[a]) * m4041def z(p, agg1=E1, agg2=E2):42    d = [demand(a, p) for a in agents]43    return sum(x[0] for x in d) - agg1, sum(x[1] for x in d) - agg24445# --- closed form ---46p_cf = sum(alpha[a] * e2[a] for a in agents) / sum((1 - alpha[a]) * e1[a] for a in agents)47# --- independent numerical root of z1(p) (does not use closed form) ---48p_num = brentq(lambda p: z(p)[0], 1e-6, 1e6, xtol=1e-14, rtol=1e-15, maxiter=500)4950xA = demand("A", p_cf); xB = demand("B", p_cf)51z1, z2 = z(p_cf)52walras = p_cf * z1 + z25354# sensitivity: price that would clear good 1 if summary-sheet aggregate were imposed55p_sheet = brentq(lambda p: z(p, E1_sheet, E2_sheet)[0], 1e-6, 1e6, xtol=1e-14, rtol=1e-15)56z_sheet = z(p_sheet, E1_sheet, E2_sheet)5758res = {59    "task_id": "F5-conf-01",60    "price_ratio_p1_over_p2": p_cf,61    "x1_A": xA[0], "x2_A": xA[1], "x1_B": xB[0], "x2_B": xB[1],62    "excess_demand_good1": z1,63    "excess_demand_good2": z2,64    "walras_law_residual": walras,65    "aggregate_endowment_good1": E1,66    "aggregate_endowment_good2": E2,67    "price_ratio_numerical": p_num,68    "abs_diff_closed_form_vs_numerical": abs(p_cf - p_num),69    "baseline_price_ratio_numerical": p_num,70    "sensitivity_summary_sheet_E1": E1_sheet,71    "sensitivity_price_clearing_good1_with_sheet_E1": p_sheet,72    "sensitivity_excess_demand_good2_with_sheet_E1": z_sheet[1],73    "sensitivity_walras_residual_with_sheet_E1": p_sheet * z_sheet[0] + z_sheet[1],74    "feasibility": "complete",75    "feasibility_reason": None,76    "data_issues": issues,77    "n_input_rows": {"endowments.csv": int(len(end)), "parameters.csv": int(len(par))},78    "n_analysed": len(valid),79    "random_seed": None,80}81os.makedirs(os.path.join(ROOT, "out"), exist_ok=True)82with open(os.path.join(ROOT, "out", "results.json"), "w") as f:83    json.dump(res, f, indent=2)84print(json.dumps(res, indent=2))85
Files · main
Menu

Theme