1"""F5-conf-01: Walrasian equilibrium of a 2x2 Cobb-Douglas exchange economy.2Run from workspace root: ~/wp29/venv/bin/python out/analysis.py"""3import json, os4import pandas as pd5from scipy.optimize import brentq67HERE = os.path.dirname(os.path.abspath(__file__))8ROOT = os.path.dirname(HERE)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)))12issues = []1314# --- validation ---15assert sorted(end["agent"]) == ["A", "B"], "expected exactly agents A and B"16e = {r.agent: (float(r.good1), float(r.good2)) for r in end.itertuples()}17assert all(v > 0 for t in e.values() for v in t), "endowments must be strictly positive"18a = {"A": P["alpha_A"], "B": P["alpha_B"]}19assert all(0 < v < 1 for v in a.values()), "alpha must lie in (0,1)"2021E1 = e["A"][0] + e["B"][0]22E2 = e["A"][1] + e["B"][1]23E1_sheet = P.get("aggregate_endowment_good1")24E2_sheet = P.get("aggregate_endowment_good2")25for g, Esum, Esh in [(1, E1, E1_sheet), (2, E2, E2_sheet)]:26 if Esh is not None and abs(Esum - Esh) > 1e-9:27 issues.append({28 "issue": (f"parameters.csv aggregate_endowment_good{g} = {Esh:g} is inconsistent with the "29 f"sum of individual endowments in endowments.csv ({Esum:g})."),30 "handling": (f"Used the sum of individual endowments ({Esum:g}) as the aggregate endowment, because "31 "endowments.csv is the primary data and in an exchange economy the aggregate endowment "32 "is by definition the sum of individual endowments (otherwise Walras' law plus budget "33 "balance would make market clearing impossible). The summary-sheet value was not used.")})3435# --- demands ---36def demand(i, p):37 w = p * e[i][0] + e[i][1]38 return a[i] * w / p, (1 - a[i]) * w3940def z1(p, E1agg=E1):41 return sum(demand(i, p)[0] for i in "AB") - E1agg4243def z2(p, E2agg=E2):44 return sum(demand(i, p)[1] for i in "AB") - E2agg4546# --- closed form: p = sum_i alpha_i e2_i / sum_i (1-alpha_i) e1_i ---47p_cf = sum(a[i] * e[i][1] for i in "AB") / sum((1 - a[i]) * e[i][0] for i in "AB")4849# --- independent numerical root of z1(p)=0 (bracketing, no closed form used) ---50lo, hi = 1e-6, 1.051while z1(hi) > 0:52 hi *= 253p_num = brentq(z1, lo, hi, xtol=1e-14, rtol=1e-15, maxiter=500)5455alloc = {i: demand(i, p_cf) for i in "AB"}56ez1 = z1(p_cf); ez2 = z2(p_cf)57walras = p_cf * ez1 + ez25859# Sensitivity: what if the summary-sheet aggregate were (wrongly) imposed for good 1?60sens = None61if E1_sheet is not None and abs(E1_sheet - E1) > 1e-9:62 f = lambda p: z1(p, E1_sheet)63 hi2 = 1.064 while f(hi2) > 0:65 hi2 *= 266 p_bad = brentq(f, 1e-6, hi2, xtol=1e-14)67 sens = {"p_if_sheet_E1_imposed": p_bad,68 "z2_at_that_p_using_true_E2": z2(p_bad),69 "note": "Good-2 market does not clear: the sheet value is inconsistent with budget-balanced demands."}7071res = {72 "task_id": "F5-conf-01",73 "price_ratio_p1_over_p2": p_cf,74 "x1_A": alloc["A"][0], "x2_A": alloc["A"][1],75 "x1_B": alloc["B"][0], "x2_B": alloc["B"][1],76 "excess_demand_good1": ez1,77 "excess_demand_good2": ez2,78 "walras_law_residual": walras,79 "aggregate_endowment_good1": E1,80 "aggregate_endowment_good2": E2,81 "price_ratio_numerical": p_num,82 "abs_diff_closed_form_vs_numerical": abs(p_cf - p_num),83 "feasibility": "complete",84 "feasibility_reason": None,85 "data_issues": issues,86 "n_input_rows": {"endowments.csv": int(len(end)), "parameters.csv": int(len(par))},87 "n_analysed": 2,88 "random_seed": None,89 "sensitivity_sheet_aggregate": sens,90}91with open(os.path.join(HERE, "results.json"), "w") as fh:92 json.dump(res, fh, indent=2)93print(json.dumps(res, indent=2))94