{ "cells": [ { "metadata": { "ExecuteTime": { "end_time": "2026-02-06T14:51:27.226527Z", "start_time": "2026-02-06T14:51:25.617943Z" } }, "cell_type": "code", "source": [ "%load_ext autoreload\n", "%autoreload 2" ], "id": "89aa93e9dbedd113", "outputs": [], "execution_count": 1 }, { "metadata": { "ExecuteTime": { "end_time": "2026-02-06T14:51:28.975727Z", "start_time": "2026-02-06T14:51:27.809213Z" } }, "cell_type": "code", "source": [ "%reload_ext autoreload\n", "%autoreload 2\n", "import time\n", "from numpy import nan\n", "import numpy as np\n", "import math\n", "import winkelumrechnungen as wu\n", "import os\n", "from contextlib import contextmanager, redirect_stdout, redirect_stderr\n", "import plotly.graph_objects as go\n", "import warnings\n", "import pickle\n", "import random\n", "\n", "from ellipsoide import EllipsoidTriaxial\n", "from GHA_triaxial.utils import alpha_para2ell, alpha_ell2para\n", "\n", "from GHA_triaxial.gha1_num import gha1_num\n", "from GHA_triaxial.gha1_ana import gha1_ana\n", "from GHA_triaxial.gha1_ES import gha1_ES\n", "from GHA_triaxial.gha1_approx import gha1_approx\n", "\n", "from GHA_triaxial.gha2_num import gha2_num\n", "from GHA_triaxial.gha2_ES import gha2_ES\n", "from GHA_triaxial.gha2_approx import gha2_approx\n", "\n", "from GHA_triaxial.numeric_examples_panou import get_tables as get_tables_panou\n", "from GHA_triaxial.numeric_examples_karney import get_random_examples as get_examples_karney" ], "id": "2005e5a8854eea1e", "outputs": [], "execution_count": 2 }, { "metadata": { "ExecuteTime": { "end_time": "2026-02-06T14:51:30.011589Z", "start_time": "2026-02-06T14:51:29.626051Z" } }, "cell_type": "code", "source": [ "@contextmanager\n", "def suppress_print():\n", " with open(os.devnull, 'w') as fnull:\n", " with redirect_stdout(fnull), redirect_stderr(fnull):\n", " yield" ], "id": "90f107a11ff0de7e", "outputs": [], "execution_count": 3 }, { "metadata": { "ExecuteTime": { "end_time": "2026-02-06T14:51:31.030091Z", "start_time": "2026-02-06T14:51:30.833905Z" } }, "cell_type": "code", "source": [ "# dsPart = [60, 125, 600, 1250, 6000, 60000] entspricht bei der Erde ca. 100km, 50km, 10km, 5km, 1km, 100m\n", "\n", "steps_gha1_num = [20, 50, 100, 200, 500, 1000, 5000]\n", "maxM_gha1_ana = [20, 50]\n", "parts_gha1_ana = [2, 8]\n", "dsPart_gha1_ES = [60, 600, 1250]\n", "dsPart_gha1_approx = [600, 1250, 6000]\n", "\n", "steps_gha2_num = [200, 500, 1000]\n", "dsPart_gha2_ES = [60, 600, 1250]\n", "dsPart_gha2_approx = [600, 1250, 6000]" ], "id": "fc6c39b8d358e54b", "outputs": [], "execution_count": 4 }, { "metadata": { "ExecuteTime": { "end_time": "2026-02-06T15:21:03.374105Z", "start_time": "2026-02-06T15:21:03.129308Z" } }, "cell_type": "code", "source": [ "# test = \"Karney\"\n", "# test = \"Panou\"\n", "test = \"Random\"\n", "if test == \"Karney\":\n", " ell: EllipsoidTriaxial = EllipsoidTriaxial.init_name(\"KarneyTest2024\")\n", " examples = get_examples_karney(4, seed=42)\n", "elif test == \"Panou\":\n", " ell: EllipsoidTriaxial = EllipsoidTriaxial.init_name(\"BursaSima1980round\")\n", " tables = get_tables_panou()\n", " table_indices = []\n", " examples = []\n", " for i, table in enumerate(tables):\n", " for example in table:\n", " table_indices.append(i+1)\n", " examples.append(example)\n", "elif test == \"Random\":\n", " ell: EllipsoidTriaxial = EllipsoidTriaxial.init_name(\"BursaSima1980round\")\n", " examples = [] # beta0, lamb0, alpha0_ell, beta1, lamb1, alpha1_ell, s\n", " random.seed(42)\n", " for _ in range(30):\n", " beta0 = wu.deg2rad(random.randint(-90, 90))\n", " lamb0 = wu.deg2rad(random.randint(-179, 180))\n", " alpha0_ell = wu.deg2rad(random.randint(0, 359))\n", " s = random.randint(10000, int(np.pi*ell.b))\n", " examples.append([beta0, lamb0, alpha0_ell, s])\n", " pass" ], "id": "6770dbd57d475127", "outputs": [], "execution_count": 25 }, { "metadata": {}, "cell_type": "code", "source": [ "if test != \"Random\":\n", " results = {}\n", " for i, example in enumerate(examples):\n", " print(f\"----- Beispiel {i+1}/{len(examples)}\")\n", " example_results = {}\n", "\n", " beta0, lamb0, alpha0_ell, beta1, lamb1, alpha1_ell, s = example\n", " P0 = ell.ell2cart(beta0, lamb0)\n", " P1 = ell.ell2cart(beta1, lamb1)\n", " _, _, alpha0_para = alpha_ell2para(ell, beta0, lamb0, alpha0_ell)\n", "\n", " for steps in steps_gha1_num:\n", " start = time.perf_counter()\n", " try:\n", " P1_num, alpha1_num_1 = gha1_num(ell, P0, alpha0_ell, s, num=steps)\n", " print(f\"GHA1_num_{steps}\", P1_num)\n", " end = time.perf_counter()\n", " beta1_num, lamb1_num = ell.cart2ell(P1_num)\n", " d_beta1 = abs(beta1_num - beta1)\n", " d_lamb1 = abs(lamb1_num - lamb1)\n", " d_alpha1 = abs(alpha1_num_1 - alpha1_ell)\n", " d_time = end - start\n", " example_results[f\"GHA1_num_{steps}\"] = (d_beta1, d_lamb1, d_alpha1, d_time)\n", " except Exception as e:\n", " print(e)\n", " example_results[f\"GHA1_num_{steps}\"] = (nan, nan, nan, nan)\n", "\n", " for maxM in maxM_gha1_ana:\n", " for parts in parts_gha1_ana:\n", " start = time.perf_counter()\n", " try:\n", " P1_ana, alpha1_ana_para = gha1_ana(ell, P0, alpha0_para, s, maxM=maxM, maxPartCircum=parts)\n", " print(f\"GHA1_ana_{maxM}_{parts}\", P1_ana)\n", " end = time.perf_counter()\n", " beta1_ana, lamb1_ana = ell.cart2ell(P1_ana)\n", " _, _, alpha1_ana_ell = alpha_para2ell(ell, beta1_ana, lamb1_ana, alpha1_ana_para)\n", " d_beta1 = abs(beta1_ana - beta1)\n", " d_lamb1 = abs(lamb1_ana - lamb1)\n", " d_alpha1 = abs(alpha1_ana_ell - alpha1_ell)\n", " d_time = end - start\n", " example_results[f\"GHA1_ana_{maxM}_{parts}\"] = (d_beta1, d_lamb1, d_alpha1, d_time)\n", " except Exception as e:\n", " print(e)\n", " example_results[f\"GHA1_ana_{maxM}_{parts}\"] = (nan, nan, nan, nan)\n", "\n", " for dsPart in dsPart_gha1_ES:\n", " ds = ell.ax/dsPart\n", " start = time.perf_counter()\n", " try:\n", " P1_ES, alpha1_ES = gha1_ES(ell, beta0, lamb0, alpha0_ell, s, maxSegLen=ds)\n", " end = time.perf_counter()\n", " beta1_ES, lamb1_ES = ell.cart2ell(P1_ES)\n", " d_beta1 = abs(beta1_ES - beta1)\n", " d_lamb1 = abs(lamb1_ES - lamb1)\n", " d_alpha1 = abs(alpha1_ES - alpha1_ell)\n", " d_time = end - start\n", " example_results[f\"GHA1_ES_{dsPart}\"] = (d_beta1, d_lamb1, d_alpha1, d_time)\n", " except Exception as e:\n", " print(e)\n", " example_results[f\"GHA1_ES_{dsPart}\"] = (nan, nan, nan, nan)\n", "\n", " for dsPart in dsPart_gha1_approx:\n", " ds = ell.ax/dsPart\n", " start = time.perf_counter()\n", " try:\n", " P1_approx, alpha1_approx = gha1_approx(ell, P0, alpha0_ell, s, ds=ds)\n", " end = time.perf_counter()\n", " beta1_approx, lamb1_approx = ell.cart2ell(P1_approx)\n", " d_beta1 = abs(beta1_approx - beta1)\n", " d_lamb1 = abs(lamb1_approx - lamb1)\n", " d_alpha1 = abs(alpha1_approx - alpha1_ell)\n", " d_time = end - start\n", " example_results[f\"GHA1_approx_{dsPart}\"] = (d_beta1, d_lamb1, d_alpha1, d_time)\n", " except Exception as e:\n", " print(e)\n", " example_results[f\"GHA1_approx_{dsPart}\"] = (nan, nan, nan, nan)\n", "\n", " # ----------------------------------------------\n", "\n", " for steps in steps_gha2_num:\n", " start = time.perf_counter()\n", " try:\n", " with warnings.catch_warnings():\n", " warnings.simplefilter(\"ignore\", RuntimeWarning)\n", " alpha0_num, alpha1_num_2, s_num = gha2_num(ell, beta0, lamb0, beta1, lamb1, n=steps)\n", " print(alpha0_num, alpha1_num_2, s_num)\n", " end = time.perf_counter()\n", " d_alpha0 = abs(alpha0_num - alpha0_ell)\n", " d_alpha1 = abs(alpha1_num_2 - alpha1_ell)\n", " d_s = abs(s_num - s)\n", " d_time = end - start\n", " example_results[f\"GHA2_num_{steps}\"] = (d_alpha0, d_alpha1, d_s, d_time)\n", " except Exception as e:\n", " print(e)\n", " example_results[f\"GHA2_num_{steps}\"] = (nan, nan, nan, nan)\n", "\n", " for dsPart in dsPart_gha2_ES:\n", " ds = ell.ax/dsPart\n", " start = time.perf_counter()\n", " try:\n", " with suppress_print():\n", " alpha0_ES, alpha1_ES, s_ES = gha2_ES(ell, P0, P1, maxSegLen=ds)\n", " end = time.perf_counter()\n", " d_alpha0 = abs(alpha0_ES - alpha0_ell)\n", " d_alpha1 = abs(alpha1_ES - alpha1_ell)\n", " d_s = abs(s_ES - s)\n", " d_time = end - start\n", " example_results[f\"GHA2_ES_{dsPart}\"] = (d_alpha0, d_alpha1, d_s, d_time)\n", " except Exception as e:\n", " print(e)\n", " example_results[f\"GHA2_ES_{dsPart}\"] = (nan, nan, nan, nan)\n", "\n", " for dsPart in dsPart_gha2_approx:\n", " ds = ell.ax/dsPart\n", " start = time.perf_counter()\n", " try:\n", " alpha0_approx, alpha1_approx, s_approx = gha2_approx(ell, P0, P1, ds=ds)\n", " end = time.perf_counter()\n", " d_alpha0 = abs(alpha0_approx - alpha0_ell)\n", " d_alpha1 = abs(alpha1_approx - alpha1_ell)\n", " d_s = abs(s_approx - s)\n", " d_time = end - start\n", " example_results[f\"GHA2_approx_{dsPart}\"] = (d_alpha0, d_alpha1, d_s, d_time)\n", " except Exception as e:\n", " print(e)\n", " example_results[f\"GHA2_approx_{dsPart}\"] = (nan, nan, nan, nan)\n", "\n", " results[f\"beta0: {wu.rad2deg(beta0):.3f}, lamb0: {wu.rad2deg(lamb0):.3f}, alpha0: {wu.rad2deg(alpha0_ell):.3f}, s: {s}\"] = example_results" ], "id": "fc45e0f618a0e4d8", "outputs": [], "execution_count": null }, { "metadata": {}, "cell_type": "code", "source": [ "if test == \"Random\":\n", " results = {}\n", " for i, example in enumerate(examples):\n", " print(f\"----- Beispiel {i+1}/{len(examples)}\")\n", " example_results = {}\n", "\n", " beta0, lamb0, alpha0_ell, s = example\n", " P0 = ell.ell2cart(beta0, lamb0)\n", " _, _, alpha0_para = alpha_ell2para(ell, beta0, lamb0, alpha0_ell)\n", "\n", " # P1_ana, alpha1_ana_para = gha1_ana(ell, P0, alpha0_para, s, maxM=60, maxPartCircum=4)\n", " # beta1_ana, lamb1_ana = ell.cart2ell(P1_ana)\n", " # _, _, alpha1_ana = alpha_para2ell(ell, beta1_ana, lamb1_ana, alpha1_ana_para)\n", "\n", " P1, alpha1_ell = gha1_num(ell, P0, alpha0_ell, s, num=10000)\n", " beta1, lamb1 = ell.cart2ell(P1)\n", "\n", " for maxM in maxM_gha1_ana:\n", " for parts in parts_gha1_ana:\n", " start = time.perf_counter()\n", " try:\n", " P1_ana, alpha1_ana_para = gha1_ana(ell, P0, alpha0_para, s, maxM=maxM, maxPartCircum=parts)\n", " end = time.perf_counter()\n", " beta1_ana, lamb1_ana = ell.cart2ell(P1_ana)\n", " _, _, alpha1_ana_ell = alpha_para2ell(ell, beta1_ana, lamb1_ana, alpha1_ana_para)\n", " d_beta1 = abs(wu.rad2deg(beta1_ana - beta1)) / 3600\n", " d_lamb1 = abs(wu.rad2deg(lamb1_ana - lamb1)) / 3600\n", " d_alpha1 = abs(wu.rad2deg(alpha1_ana_ell - alpha1_ell)) / 3600\n", " d_time = end - start\n", " example_results[f\"GHA1_ana_{maxM}_{parts}\"] = (d_beta1, d_lamb1, d_alpha1, d_time)\n", " except Exception as e:\n", " print(e)\n", " example_results[f\"GHA1_ana_{maxM}_{parts}\"] = (nan, nan, nan, nan)\n", "\n", " for dsPart in dsPart_gha1_approx:\n", " ds = ell.ax/dsPart\n", " start = time.perf_counter()\n", " try:\n", " P1_approx, alpha1_approx = gha1_approx(ell, P0, alpha0_ell, s, ds=ds)\n", " end = time.perf_counter()\n", " beta1_approx, lamb1_approx = ell.cart2ell(P1_approx)\n", " d_beta1 = abs(wu.rad2deg(beta1_approx - beta1)) / 3600\n", " d_lamb1 = abs(wu.rad2deg(lamb1_approx - lamb1)) / 3600\n", " d_alpha1 = abs(wu.rad2deg(alpha1_approx - alpha1_ell)) / 3600\n", " d_time = end - start\n", " example_results[f\"GHA1_approx_{dsPart}\"] = (d_beta1, d_lamb1, d_alpha1, d_time)\n", " except Exception as e:\n", " print(e)\n", " example_results[f\"GHA1_approx_{dsPart}\"] = (nan, nan, nan, nan)\n", "\n", " for dsPart in dsPart_gha1_ES:\n", " ds = ell.ax/dsPart\n", " start = time.perf_counter()\n", " try:\n", " P1_ES, alpha1_ES = gha1_ES(ell, beta0, lamb0, alpha0_ell, s, maxSegLen=ds)\n", " end = time.perf_counter()\n", " beta1_ES, lamb1_ES = ell.cart2ell(P1_ES)\n", " d_beta1 = abs(beta1_ES - beta1)\n", " d_lamb1 = abs(lamb1_ES - lamb1)\n", " d_alpha1 = abs(alpha1_ES - alpha1_ell)\n", " d_time = end - start\n", " example_results[f\"GHA1_ES_{dsPart}\"] = (d_beta1, d_lamb1, d_alpha1, d_time)\n", " except Exception as e:\n", " print(e)\n", " example_results[f\"GHA1_ES_{dsPart}\"] = (nan, nan, nan, nan)\n", "\n", " for steps in steps_gha2_num:\n", " start = time.perf_counter()\n", " try:\n", " with warnings.catch_warnings():\n", " warnings.simplefilter(\"ignore\", RuntimeWarning)\n", " alpha0_num, alpha1_num_2, s_num = gha2_num(ell, beta0, lamb0, beta1, lamb1, n=steps)\n", " end = time.perf_counter()\n", " d_alpha0 = abs(wu.rad2deg(alpha0_num - alpha0_ell)) / 3600\n", " d_alpha1 = abs(wu.rad2deg(alpha1_num_2 - alpha1_ell)) / 3600\n", " d_s = abs(s_num - s) / 1000\n", " d_time = end - start\n", " example_results[f\"GHA2_num_{steps}\"] = (d_alpha0, d_alpha1, d_s, d_time)\n", " except Exception as e:\n", " print(e)\n", " example_results[f\"GHA2_num_{steps}\"] = (nan, nan, nan, nan)\n", "\n", " for dsPart in dsPart_gha2_ES:\n", " ds = ell.ax/dsPart\n", " start = time.perf_counter()\n", " try:\n", " with suppress_print():\n", " alpha0_ES, alpha1_ES, s_ES = gha2_ES(ell, P0, P1, maxSegLen=ds)\n", " end = time.perf_counter()\n", " d_alpha0 = abs(wu.rad2deg(alpha0_ES - alpha0_ell)) / 3600\n", " d_alpha1 = abs(wu.rad2deg(alpha1_ES - alpha1_ell)) / 3600\n", " d_s = abs(s_ES - s) / 1000\n", " d_time = end - start\n", " example_results[f\"GHA2_ES_{dsPart}\"] = (d_alpha0, d_alpha1, d_s, d_time)\n", " except Exception as e:\n", " print(e)\n", " example_results[f\"GHA2_ES_{dsPart}\"] = (nan, nan, nan, nan)\n", "\n", " for dsPart in dsPart_gha2_approx:\n", " ds = ell.ax/dsPart\n", " start = time.perf_counter()\n", " try:\n", " alpha0_approx, alpha1_approx, s_approx = gha2_approx(ell, P0, P1, ds=ds)\n", " end = time.perf_counter()\n", " d_alpha0 = abs(wu.rad2deg(alpha0_approx - alpha0_ell)) / 3600\n", " d_alpha1 = abs(wu.rad2deg(alpha1_approx - alpha1_ell)) / 3600\n", " d_s = abs(s_approx - s) / 1000\n", " d_time = end - start\n", " example_results[f\"GHA2_approx_{dsPart}\"] = (d_alpha0, d_alpha1, d_s, d_time)\n", " except Exception as e:\n", " print(e)\n", " example_results[f\"GHA2_approx_{dsPart}\"] = (nan, nan, nan, nan)\n", "\n", " results[f\"beta0: {wu.rad2deg(beta0):.3f}, lamb0: {wu.rad2deg(lamb0):.3f}, alpha0: {wu.rad2deg(alpha0_ell):.3f}, s: {s}\"] = example_results\n", "\n", "\n" ], "id": "6e20a077d522d5", "outputs": [], "execution_count": null }, { "metadata": {}, "cell_type": "code", "outputs": [], "execution_count": null, "source": [ "# with open(f\"gha_results{test}.pkl\", \"wb\") as f:\n", "# pickle.dump(results, f)" ], "id": "74fbd4d33c288839" }, { "metadata": { "ExecuteTime": { "end_time": "2026-02-06T15:21:05.121195Z", "start_time": "2026-02-06T15:21:04.930958Z" } }, "cell_type": "code", "source": [ "with open(f\"gha_results{test}.pkl\", \"rb\") as f:\n", " results = pickle.load(f)" ], "id": "4c20a0579c0f7038", "outputs": [], "execution_count": 26 }, { "metadata": { "ExecuteTime": { "end_time": "2026-02-06T14:29:13.359555Z", "start_time": "2026-02-06T14:29:13.127178Z" } }, "cell_type": "code", "source": [ "metrics_gha1 = ['dBeta [\"]', 'dLambda [\"]', 'dAlpha1 [\"]', 'time [s]']\n", "metrics_gha2 = ['dAlpha0 [\"]', 'dAlpha1 [\"]', 'dStrecke [m]', 'time [s]']\n", "listed_results = {}\n", "for example, example_metrics in results.items():\n", " for method, method_metrics in example_metrics.items():\n", " if \"GHA1\" in method:\n", " if method not in listed_results.keys():\n", " listed_results[method] = {metric: [] for metric in metrics_gha1}\n", " for i, metric in enumerate(method_metrics):\n", " if '[\"]' in metrics_gha1[i]:\n", " listed_results[method][metrics_gha1[i]].append(wu.rad2deg(metric)*3600)\n", " else:\n", " listed_results[method][metrics_gha1[i]].append(metric)\n", " if \"GHA2\" in method:\n", " if method not in listed_results.keys():\n", " listed_results[method] = {metric: [] for metric in metrics_gha2}\n", " for i, metric in enumerate(method_metrics):\n", " if '[\"]' in metrics_gha2[i]:\n", " listed_results[method][metrics_gha2[i]].append(wu.rad2deg(metric)*3600)\n", " else:\n", " listed_results[method][metrics_gha2[i]].append(metric)\n", " pass" ], "id": "2086b5bcd8416e33", "outputs": [], "execution_count": 61 }, { "metadata": {}, "cell_type": "code", "source": [ "def format_max(values, is_angle=False):\n", " arr = np.array(values, dtype=float)\n", " if arr.size==0:\n", " return np.nan\n", " maxi = np.nanmax(np.abs(arr))\n", " if maxi is None or (isinstance(maxi,float) and (math.isnan(maxi))):\n", " return \"nan\"\n", " if is_angle:\n", " maxi = wu.rad2deg(maxi)*3600\n", " if f\"{maxi:.3g}\" == 0:\n", " pass\n", " return f\"{maxi:.3g}\"\n", "\n", "\n", "def build_max_table(gha_prefix, title, group_value = None):\n", " if gha_prefix==\"GHA1\":\n", " metrics = ['dBeta [\"]', 'dLambda [\"]', 'dAlpha1 [\"]', 'time [s]']\n", " angle_mask = [True, True, True, False]\n", " else:\n", " metrics = ['dAlpha0 [\"]', 'dAlpha1 [\"]', 'dStrecke [m]', 'time [s]']\n", " angle_mask = [True, True, False, False]\n", "\n", " if group_value is None:\n", " example_keys = [example_key for example_key in list(results.keys())]\n", " else:\n", " example_keys = [example_key for example_key, group_index in zip(results.keys(), table_indices) if group_index==group_value]\n", " example_keys = example_keys[:14]\n", "\n", " algorithms = sorted({algorithm for example_key in example_keys for algorithm in results[example_key].keys() if algorithm.startswith(gha_prefix)})\n", "\n", " header = [\"Algorithmus\", \"Parameter\", \"NaN\"] + list(metrics)\n", " cells = [[] for i in range(len(metrics) + 3)]\n", " for algorithm in algorithms:\n", "\n", " ghaNr, variant, params = algorithm.split(\"_\", 2)\n", " cells[0].append(variant)\n", " cells[1].append(params)\n", " nan_values = []\n", " for example_key in example_keys:\n", " nan_values.append(results[example_key][algorithm][0])\n", " cells[2].append(np.sum(np.isnan(nan_values)))\n", " for i, metric in enumerate(metrics):\n", " values = []\n", " for example_key in example_keys:\n", " values.append(results[example_key][algorithm][i])\n", " cells[i+3].append(format_max(values, is_angle=angle_mask[i]))\n", "\n", " header = dict(\n", " values=header,\n", " align=\"center\",\n", " fill_color=\"lightgrey\",\n", " font=dict(size=13)\n", " )\n", " cells = dict(\n", " values=cells,\n", " align=\"center\"\n", " )\n", "\n", " fig = go.Figure(data=[go.Table(header=header, cells=cells)])\n", " fig.update_layout(title=title,\n", " template=\"simple_white\",\n", " width=800,\n", " height=280,\n", " margin=dict(l=20, r=20, t=60, b=20))\n", " return fig\n", "\n", "figs = []\n", "# if test == \"Panou\":\n", "# for table_index in sorted(set(table_indices)):\n", "# fig1 = build_max_table(\"GHA1\", f\"{test} - Gruppe {table_index} - GHA1\", table_index)\n", "# fig2 = build_max_table(\"GHA2\", f\"{test} - Gruppe {table_index} - GHA2\", table_index)\n", "# figs.append(fig1)\n", "# figs.append(fig2)\n", "# elif test == \"Karney\":\n", "fig1 = build_max_table(\"GHA1\", f\"{test} - GHA1\")\n", "fig2 = build_max_table(\"GHA2\", f\"{test} - GHA2\")\n", "figs.append(fig1)\n", "figs.append(fig2)\n", "\n", "for fig in figs:\n", " fig.show()" ], "id": "eeb5a204cc4bbf7d", "outputs": [], "execution_count": null }, { "metadata": { "ExecuteTime": { "end_time": "2026-02-06T15:21:25.399278Z", "start_time": "2026-02-06T15:21:25.145849Z" } }, "cell_type": "code", "source": [ "from collections import defaultdict\n", "\n", "def to_latex_sci(x, decimals=3, exp_digits=2):\n", " \"\"\"\n", " Immer wissenschaftliche Schreibweise in LaTeX mit:\n", " - fester Mantisse (z.B. 1.234)\n", " - Exponent immer mit Vorzeichen (+/-)\n", " - Exponent immer feste Stellenzahl (z.B. +03, -01)\n", "\n", " Beispiel:\n", " 0.216 -> $2.160\\\\cdot10^{-01}$\n", " 12.3 -> $1.230\\\\cdot10^{+01}$\n", " \"\"\"\n", "\n", " if x is None:\n", " return \"nan\"\n", " try:\n", " xf = float(x)\n", " except Exception:\n", " return str(x)\n", "\n", " if math.isnan(xf):\n", " return \"nan\"\n", "\n", " if xf == 0.0:\n", " exp_fmt = f\"+{0:0{exp_digits}d}\"\n", " mant = f\"{0:.{decimals}f}\"\n", " return f\"${mant}\\\\cdot10^{{{exp_fmt}}}$\"\n", "\n", " s = f\"{xf:.{decimals}e}\" # z.B. 2.160e-01\n", " mant, exp = s.split(\"e\")\n", " exp = int(exp)\n", "\n", " # Exponent formatieren: Vorzeichen + feste Länge\n", " sign = \"+\" if exp >= 0 else \"-\"\n", " exp_abs = abs(exp)\n", " exp_fmt = f\"{sign}{exp_abs:0{exp_digits}d}\"\n", "\n", " return f\"${mant}\\\\cdot10^{{{exp_fmt}}}$\"\n", "\n", "\n", "def nan_count_for_algorithm(results, example_keys, algorithm):\n", " vals = []\n", " for k in example_keys:\n", " vals.append(results[k][algorithm][0])\n", " return int(np.sum(np.isnan(np.array(vals, dtype=float))))\n", "\n", "\n", "def max_abs_metric(results, example_keys, algorithm, metric_index, is_angle=False, wu=None):\n", " \"\"\"\n", " Echter Max(|...|) über alle example_keys.\n", " Wenn is_angle=True: Werte werden als rad angenommen und in Bogensekunden umgerechnet.\n", " \"\"\"\n", " arr = []\n", " for k in example_keys:\n", " arr.append(results[k][algorithm][metric_index])\n", " arr = np.array(arr, dtype=float)\n", "\n", " if arr.size == 0:\n", " return np.nan\n", " m = np.nanmax(np.abs(arr))\n", " if is_angle:\n", " if wu is None:\n", " raise ValueError(\"wu wird benötigt für rad2deg, wenn is_angle=True\")\n", " m = wu.rad2deg(m) * 3600.0\n", " return m\n", "\n", "\n", "def parse_variant_params(algorithm_key):\n", " \"\"\"\n", " Erwartet: GHA1_ana_20_4 -> variant='ana', params='20_4'\n", " Gibt zusätzlich eine hübsche Parameterdarstellung zurück.\n", " \"\"\"\n", " ghaNr, variant, params = algorithm_key.split(\"_\", 2)\n", "\n", " # Standard: params 그대로\n", " pretty = params\n", "\n", " # Für deine Tabellen: ana hat z.B. '20_4' -> '4, 20' (Segmentgröße, Ordnung)\n", " if variant == \"ana\":\n", " # bei dir: params = '20_4' oder '50_8' -> Ordnung_Segment\n", " # du willst aber: Segment, Ordnung -> '4, 20'\n", " a, b = params.split(\"_\")\n", " order = a\n", " seg = b\n", " pretty = f\"{seg}, {order}\"\n", " else:\n", " # num: '2000' bleibt '2000'\n", " # approx/ES: oft eine Zahl mit Punkt/Unterstrich? -> 그대로\n", " pretty = params.replace(\"_\", \", \")\n", "\n", " return variant, params, pretty\n", "\n", "\n", "def build_latex_table_from_results(\n", " results,\n", " gha_prefix=\"GHA1\",\n", " example_keys=None,\n", " caption=\"\",\n", " label=\"tab:results_algorithms\",\n", " include_nan_col=False,\n", " wu=None\n", "):\n", " \"\"\"\n", " Erzeugt LaTeX Tabular (inkl. table-Umgebung) im gewünschten Stil.\n", " \"\"\"\n", "\n", " if example_keys is None:\n", " example_keys = list(results.keys())\n", "\n", " # Metriken & Winkel-Maske wie bei dir\n", " if gha_prefix == \"GHA1\":\n", " metric_headers = [\n", " r\"$\\max(|\\Delta \\beta|)$ [$''$]\",\n", " r\"$\\max(|\\Delta \\lambda|)$ [$''$]\",\n", " r\"$\\max(|\\Delta \\alpha_1|)$ [$''$]\",\n", " r\"time [s]\"\n", " ]\n", " angle_mask = [True, True, True, False]\n", " else:\n", " metric_headers = [\n", " r\"$\\max(|\\Delta \\alpha_0|)$ [$''$]\",\n", " r\"$\\max(|\\Delta \\alpha_1|)$ [$''$]\",\n", " r\"$\\max(|\\Delta s|)$ [m]\",\n", " r\"time [s]\"\n", " ]\n", " angle_mask = [True, True, False, False]\n", "\n", " # Alle Algorithmen sammeln\n", " algorithms = sorted({\n", " alg for k in example_keys\n", " for alg in results[k].keys()\n", " if alg.startswith(gha_prefix)\n", " })\n", "\n", " # Gruppieren nach variant (ana, num, approx, ES, ...)\n", " grouped = defaultdict(list)\n", " for alg in algorithms:\n", " variant, raw_params, pretty = parse_variant_params(alg)\n", " grouped[variant].append((alg, pretty))\n", "\n", " # gewünschte Reihenfolge (falls vorhanden)\n", " variant_order = [\"ana\", \"num\", \"approx\", \"ES\"]\n", " ordered_variants = [v for v in variant_order if v in grouped] + [v for v in grouped.keys() if v not in variant_order]\n", "\n", " # LaTeX Header\n", " cols = 2 + (1 if include_nan_col else 0) + len(metric_headers)\n", " colspec = \"|\" + \"|\".join([\"c\"] * cols) + \"|\"\n", "\n", " header_cells = [\"Methode\", \"Parameterwerte\"]\n", " if include_nan_col:\n", " header_cells.append(\"NaN\")\n", " header_cells += metric_headers\n", "\n", " lines = []\n", " lines.append(r\"\\begin{table}[H]\")\n", " lines.append(r\"\\centering\")\n", " if caption:\n", " lines.append(rf\"\\caption{{{caption}}}\")\n", " lines.append(rf\"\\label{{{label}}}\")\n", " lines.append(rf\"\\begin{{tabular}}{{{colspec}}}\")\n", " lines.append(r\"\\hline\")\n", " lines.append(\" & \".join(header_cells) + r\" \\\\\")\n", " lines.append(r\"\\Xhline{1.5pt}\")\n", "\n", " # Zeilen bauen\n", " for variant in ordered_variants:\n", " rows = grouped[variant]\n", " # für stable output: sort by pretty param (numerisch)\n", " # (du kannst das ändern, wenn du eine andere Reihenfolge willst)\n", " def sort_key(t):\n", " _, pretty = t\n", " # versuche numerisch zu sortieren\n", " try:\n", " parts = [float(p.strip()) for p in pretty.split(\",\")]\n", " return parts\n", " except Exception:\n", " return [pretty]\n", " rows = sorted(rows, key=sort_key)\n", "\n", " multi_n = len(rows)\n", " method_name = {\n", " \"ana\": \"analytisch\",\n", " \"num\": \"numerisch\",\n", " \"approx\": \"approximiert\"\n", " }.get(variant, variant)\n", "\n", " for idx, (alg, pretty_param) in enumerate(rows):\n", " row_cells = []\n", "\n", " if multi_n > 1:\n", " if idx == 0:\n", " row_cells.append(rf\"\\multirow{{{multi_n}}}{{*}}{{{method_name}}}\")\n", " else:\n", " row_cells.append(\"\") # Multirow fortsetzen\n", " else:\n", " row_cells.append(method_name)\n", "\n", " row_cells.append(pretty_param)\n", "\n", " if include_nan_col:\n", " nans = nan_count_for_algorithm(results, example_keys, alg)\n", " row_cells.append(str(nans))\n", "\n", " # Metriken\n", " for mi in range(len(metric_headers)):\n", " m = max_abs_metric(results, example_keys, alg, mi, is_angle=angle_mask[mi], wu=wu)\n", " row_cells.append(to_latex_sci(m))\n", "\n", " # Zeile + Linienlogik wie in deinem Beispiel\n", " latex_row = \" & \".join(row_cells) + r\" \\\\\"\n", "\n", " # nach letzter Zeile einer Methode eine \\hline (wie bei dir)\n", " if idx == multi_n - 1:\n", " latex_row += r\"\\hline\"\n", " lines.append(latex_row)\n", "\n", " lines.append(r\"\\end{tabular}\")\n", " lines.append(r\"\\end{table}\")\n", " lines.append(r\"\\noindent\")\n", "\n", " return \"\\n\".join(lines)\n", "\n", "\n", "# --- Beispielaufruf ---\n", "example_keys = list(key for i, key in enumerate(results.keys()))\n", "if test == \"Panou\":\n", " example_keys = example_keys[:14]\n", "gha = \"GHA2\"\n", "# example_keys = list(key for i, key in enumerate(results.keys()) if table_indices[i] == 3) # gefiltert auf Panou Gruppe etc.\n", "latex = build_latex_table_from_results(\n", " results,\n", " gha_prefix=gha,\n", " example_keys=example_keys,\n", " caption=f\"Ergebnisse der Lösungsmethoden der {gha[3]}. GHA ({test})\",\n", " label=f\"tab:results_{test}_{gha}\",\n", " include_nan_col=True, # True, wenn du NaN-Spalte willst\n", " wu=wu # wichtig, falls Winkelwerte rad sind\n", ")\n", "print(latex)" ], "id": "12591c3b707da905", "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\\begin{table}[H]\n", "\\centering\n", "\\caption{Ergebnisse der Lösungsmethoden der 2. GHA (Random)}\n", "\\label{tab:results_Random_GHA2}\n", "\\begin{tabular}{|c|c|c|c|c|c|c|}\n", "\\hline\n", "Methode & Parameterwerte & NaN & $\\max(|\\Delta \\alpha_0|)$ [$''$] & $\\max(|\\Delta \\alpha_1|)$ [$''$] & $\\max(|\\Delta s|)$ [m] & time [s] \\\\\n", "\\Xhline{1.5pt}\n", "\\multirow{3}{*}{approximiert} & 600 & 0 & $2.075\\cdot10^{+04}$ & $2.063\\cdot10^{+04}$ & $1.730\\cdot10^{-01}$ & $2.396\\cdot10^{-01}$ \\\\\n", " & 1250 & 0 & $2.075\\cdot10^{+04}$ & $2.063\\cdot10^{+04}$ & $1.744\\cdot10^{-01}$ & $4.663\\cdot10^{-01}$ \\\\\n", " & 6000 & 0 & $2.075\\cdot10^{+04}$ & $2.063\\cdot10^{+04}$ & $1.749\\cdot10^{-01}$ & $3.877\\cdot10^{+00}$ \\\\\\hline\n", "\\end{tabular}\n", "\\end{table}\n", "\\noindent\n" ] } ], "execution_count": 28 }, { "metadata": {}, "cell_type": "code", "outputs": [], "execution_count": null, "source": "", "id": "44f20396e6c5493c" } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.6" } }, "nbformat": 4, "nbformat_minor": 5 }