<jupyter_start><jupyter_text>Summary<jupyter_code>df = outputs.copy()
display(df[[
    "test/equality/error_max",
    "test/inequality/error_max",
    "test/inequality/active_power/error_max",
    "test/inequality/reactive_power/error_max",
    "test/inequality/voltage_magnitude/error_max",
    "test/inequality/forward_rate/error_max",
    "test/inequality/backward_rate/error_max",
    "test/inequality/voltage_angle_difference/error_max",
]].max())

print(f"""
GNN Cost: {df["test/cost"].mean():0.4f}
IPOPT Cost: {df["acopf/cost"].mean():0.4f}
GNN/IPOPT: {(df["test/cost"]/df["acopf/cost"]).mean():0.4f}
Maximum violation rate: {df["test/inequality/rate"].max():0.4f}
Rate of any violation: {(df["test/inequality/error_max"] > 1e-4).sum() / len(df):0.4f}
""")<jupyter_output><empty_output><jupyter_text>Histograms<jupyter_code>from utils import FlowLayout
aspect = 1.618
kwargs = dict(
    bins=10,
    stat="proportion",
    aspect=aspect,
    height=3.5/aspect,
)

ylabel = "Count / # of samples"

sns.displot(df, x="test/inequality/error_max", **kwargs)
plt.xlabel("Max inequality error")
plt.ylabel(ylabel)
save("error_max")

sns.displot(df, x="test/inequality/error_mean", **kwargs)
plt.xlabel("Mean inequality error")
plt.ylabel(ylabel)
save("error_mean")

# Cost improvement
df["test/cost/improvement"] = df["test/cost"]/df["acopf/cost"]
df["violation"] = df["test/inequality/rate"] > 1e-8
sns.displot(df[~df["violation"]], x="test/cost/improvement", **kwargs)
plt.xlabel("GNN / IPOPT cost ratio")
plt.ylabel(ylabel)
save("costs")

# map variable names to series names
fmt = "test/inequality/%s/error_max"

hist_dict = {
    "equality": ["test/equality/bus_power/error_max"],
    "gen": [fmt % "active_power", fmt % "reactive_power"],
    "vm": [fmt % "voltage_magnitude"],
    "rate": [fmt % "forward_rate", fmt % "backward_rate"],
    "vad": [fmt % "voltage_angle_difference"]
}

sns.displot(df["test/equality/bus_power/error_max"], **kwargs)
plt.xlabel("Bus power equality error")
plt.ylabel(ylabel)
save("error_equality")

power_df = df.melt(value_vars=[fmt % "active_power", fmt % "reactive_power"])
sns.displot(power_df, x="value", **kwargs)
plt.xlabel("Generated power error")
plt.ylabel(ylabel)
save("error_gen")

sns.displot(df[fmt % "voltage_magnitude"], **kwargs)
plt.xlabel("Voltage magnitude error")
plt.ylabel(ylabel)
save("error_vm")

flow_df = df.melt(value_vars=[fmt % "forward_rate", fmt % "backward_rate"])
sns.displot(flow_df, x="value", **kwargs)
plt.xlabel("Power rate limit error")
plt.ylabel(ylabel)
save("error_rate")

sns.displot(df[fmt % "voltage_angle_difference"], **kwargs)
plt.xlabel("Voltage angle difference error")
plt.ylabel(ylabel)
save("error_vad")

FlowLayout().all_open()<jupyter_output><empty_output><jupyter_text>Visualizing Violations<jupyter_code>sort_term = "test/inequality/error_max"
quantile = 1

s = df[sort_term]
index = (s.sort_values()[::-1] <= s.quantile(quantile)).idxmax()
print(sort_term, s[index])
print("Idx", index)
df.iloc[index][[
    "test/cost",
    "test/equality/bus_power/error_max",
    "test/inequality/error_max",
    "test/inequality/active_power/error_max",
    "test/inequality/reactive_power/error_max",
    "test/inequality/voltage_magnitude/error_max",
    "test/inequality/forward_rate/error_max",
    "test/inequality/backward_rate/error_max",
    "test/inequality/voltage_angle_difference/error_max",
]]
import opf.plot

dataset = list(dm.test_dataloader())
barrier.double()
load = dataset[index][0].double() @ barrier.powerflow_parameters.load_matrix
with torch.no_grad():
    variables, _, _, _ = barrier._step_helper(*barrier(load), True)
plots = opf.plot.plot_constraints(variables, barrier.powerflow_parameters)
# df["acopf/cost/relaxed"] = None
# for i in tqdm.tqdm(range(len(df))):
#     forward_error = df.iloc[i]["test/inequality/forward_rate/error_max"]
#     backward_error = df.iloc[i]["test/inequality/backward_rate/error_max"]

#     increase = 1 + torch.clamp((torch.maximum(variables.Sf.abs(), variables.St.abs()) - barrier.powerflow_parameters.rate_a) / barrier.powerflow_parameters.rate_a, min=0) \
#         .squeeze().detach().numpy()
#     net = barrier.net_wrapper.net
#     original = net.line.copy()
#     barrier.net_wrapper.set_load_sparse(variables.Sd.real.squeeze(), variables.Sd.imag.squeeze())

#     net.line["max_i_ka"] *= increase[:len(net.line)]
#     bus = torch.as_tensor(barrier.net_wrapper.optimal_ac(False)[0]).double().unsqueeze(0)
#     _, constraints, cost, _ = barrier._step_helper(
#                     *barrier.parse_bus(bus),
#                     variables.Sd,
#                     project_pandapower=False,
#     )
#     net.line = original
#     df["acopf/cost/relaxed"].iloc[i] = cost.item()
# print("IPOPT Original Cost:", df["acopf/cost"].mean())
# print("IPOPT Relaxed Cost:", df["acopf/cost/relaxed"].mean())
# print("GNN Cost", df["test/cost"].mean())<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.17904993909866018, 'fraction_numerical': 0.005887129516849371, 'mean_word_length': 5.324775353016688, 'pattern_counts': {'":': 5, '<': 14, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '652474', 'license': 'MIT', 'n_tokens_mistral': 1884, 'n_tokens_neox': 1825, 'n_words': 248, 'path': 'notebooks/analysis.ipynb', 'repo_name': 'Damowerko/opf', 'size': '4926'}