1"""F5-conf-01: Walrasian equilibrium of a 2x2 Cobb-Douglas exchange economy.2Reads only data/, writes out/results.json and out/exclusions.csv deterministically. No randomness."""3import json, os, hashlib4import pandas as pd5from scipy.optimize import brentq67ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))8D = os.path.join(ROOT, "data"); O = os.path.join(ROOT, "out")910end = pd.read_csv(os.path.join(D, "endowments.csv"))11par = pd.read_csv(os.path.join(D, "parameters.csv"))12n_rows = {"endowments.csv": int(len(end)), "parameters.csv": int(len(par))}13P = dict(zip(par["parameter"], par["value"].astype(float)))14issues = []1516# --- audit ---17assert sorted(end["agent"]) == ["A", "B"] and not end["agent"].duplicated().any()18assert end[["good1", "good2"]].notna().all().all() and (end[["good1", "good2"]] > 0).all().all()19for a in ("alpha_A", "alpha_B"):20 assert 0 < P[a] < 1, a21E = end.set_index("agent")[["good1", "good2"]].astype(float)22alpha = {"A": P["alpha_A"], "B": P["alpha_B"]}23sum1, sum2 = float(E["good1"].sum()), float(E["good2"].sum())24rec1, rec2 = P["aggregate_endowment_good1"], P["aggregate_endowment_good2"]25if abs(rec1 - sum1) > 1e-12:26 issues.append({"issue": f"parameters.csv aggregate_endowment_good1 = {rec1:g} but individual endowments in endowments.csv sum to {sum1:g} (8 + 4); the summary sheet is internally inconsistent with the primary data.",27 "handling": f"Used the sum of individual endowments ({sum1:g}) as the aggregate endowment of good 1 in the market-clearing condition, because endowments.csv is the primary data and the aggregate is by definition the sum of individual endowments; the recorded value {rec1:g} is ignored (with it the market cannot clear: excess demand at the equilibrium price would be {sum1 - rec1:g})."})28if abs(rec2 - sum2) > 1e-12:29 issues.append({"issue": f"aggregate_endowment_good2 recorded {rec2:g} vs sum {sum2:g}",30 "handling": "Used the sum of individual endowments."})31W1, W2 = sum1, sum23233# --- closed form ---34# Cobb-Douglas demand: x1_i = a_i m_i / p, x2_i = (1-a_i) m_i, m_i = p e1_i + e2_i.35# Clearing good 1: sum a_i (p e1_i + e2_i) = p W1 => p = sum a_i e2_i / sum (1-a_i) e1_i36p_cf = sum(alpha[i] * E.loc[i, "good2"] for i in "AB") / sum((1 - alpha[i]) * E.loc[i, "good1"] for i in "AB")3738def demand(p):39 out = {}40 for i in "AB":41 m = p * E.loc[i, "good1"] + E.loc[i, "good2"]42 out[i] = (alpha[i] * m / p, (1 - alpha[i]) * m)43 return out4445def z1(p):46 d = demand(p); return d["A"][0] + d["B"][0] - W14748def z2(p):49 d = demand(p); return d["A"][1] + d["B"][1] - W25051# --- independent numerical root of z1(p) (does not use the closed form) ---52p_num = brentq(z1, 1e-6, 1e6, xtol=1e-14, rtol=1e-15, maxiter=500)5354d = demand(p_cf)55res = {56 "task_id": "F5-conf-01",57 "price_ratio_p1_over_p2": float(p_cf),58 "x1_A": float(d["A"][0]), "x2_A": float(d["A"][1]),59 "x1_B": float(d["B"][0]), "x2_B": float(d["B"][1]),60 "excess_demand_good1": float(z1(p_cf)),61 "walras_law_residual": float(p_cf * z1(p_cf) + z2(p_cf)),62 "aggregate_endowment_good1": W1,63 "aggregate_endowment_good2": W2,64 "price_ratio_numerical": float(p_num),65 "feasibility": "complete",66 "feasibility_reason": None,67 "data_issues": issues,68 "n_input_rows": n_rows,69 "n_analysed": int(len(E)),70 "random_seed": None,71 # supplementary diagnostics72 "excess_demand_good2": float(z2(p_cf)),73 "abs_diff_closed_form_vs_numerical": float(abs(p_cf - p_num)),74 "excess_demand_good1_if_recorded_aggregate_used": float(z1(p_cf) + W1 - rec1),75 "recorded_aggregate_endowment_good1": float(rec1),76 "input_sha256": {f: hashlib.sha256(open(os.path.join(D, f), "rb").read()).hexdigest() for f in sorted(n_rows)},77}78with open(os.path.join(O, "results.json"), "w") as f:79 json.dump(res, f, indent=2)80pd.DataFrame([{"step": 1, "rule": "agents with missing/non-positive endowments", "n_before": len(E), "n_after": len(E), "n_removed": 0,81 "rationale": "none found; both agents analysed"}]).to_csv(os.path.join(O, "exclusions.csv"), index=False)82print(json.dumps({k: res[k] for k in ["price_ratio_p1_over_p2", "price_ratio_numerical", "excess_demand_good1", "walras_law_residual"]}))83