Files
Masterprojekt/Tests/algorithms_test.ipynb
2026-02-05 21:35:48 +01:00

847 lines
34 KiB
Plaintext

{
"cells": [
{
"cell_type": "code",
"id": "initial_id",
"metadata": {
"collapsed": true,
"ExecuteTime": {
"end_time": "2026-02-04T17:56:25.185202Z",
"start_time": "2026-02-04T17:56:22.991833Z"
}
},
"source": [
"%load_ext autoreload\n",
"%autoreload 2"
],
"outputs": [],
"execution_count": 1
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-02-04T17:56:35.920624Z",
"start_time": "2026-02-04T17:56:25.201916Z"
}
},
"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": "961cb22764c5bcb9",
"outputs": [],
"execution_count": 2
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-02-04T17:56:36.470974Z",
"start_time": "2026-02-04T17:56:35.937646Z"
}
},
"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": "e4740625a366ac13",
"outputs": [],
"execution_count": 3
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-02-04T18:11:14.405810Z",
"start_time": "2026-02-04T18:11:14.169636Z"
}
},
"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": "96093cdde03f8d57",
"outputs": [],
"execution_count": 16
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-02-04T18:11:15.988345Z",
"start_time": "2026-02-04T18:11:15.774321Z"
}
},
"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(10):\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": "6e384cc01c2dbe",
"outputs": [],
"execution_count": 17
},
{
"metadata": {},
"cell_type": "code",
"outputs": [],
"execution_count": null,
"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",
" start = time.perf_counter()\n",
" try:\n",
" P1_ES, alpha1_ES = gha1_ES(ell, beta0, lamb0, alpha0_ell, s, maxSegLen=dsPart)\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": "2a87e028089a215"
},
{
"metadata": {},
"cell_type": "code",
"outputs": [],
"execution_count": null,
"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 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": "d8868b5f0e6f9b42"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-02-04T14:35:09.900827Z",
"start_time": "2026-02-04T14:35:09.690955Z"
}
},
"cell_type": "code",
"source": [
"# with open(f\"gha_results{test}.pkl\", \"wb\") as f:\n",
"# pickle.dump(results, f)"
],
"id": "664105ea35d50a7b",
"outputs": [],
"execution_count": 7
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-02-04T14:35:10.113762Z",
"start_time": "2026-02-04T14:35:09.910687Z"
}
},
"cell_type": "code",
"source": [
"# with open(f\"gha_results{test}.pkl\", \"rb\") as f:\n",
"# results = pickle.load(f)"
],
"id": "ad8aa9dcc8af4a05",
"outputs": [],
"execution_count": 8
},
{
"metadata": {},
"cell_type": "code",
"outputs": [],
"execution_count": null,
"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": "8fd6f220440f4494"
},
{
"metadata": {},
"cell_type": "code",
"outputs": [],
"execution_count": null,
"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",
"\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": "f1fb73407f5b1c8a"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-02-04T18:08:09.603687Z",
"start_time": "2026-02-04T18:08:09.269698Z"
}
},
"cell_type": "code",
"source": [
"from collections import defaultdict\n",
"\n",
"def to_latex_sci(x, sig=3):\n",
" \"\"\"\n",
" Formatiert eine Zahl als LaTeX, z.B. 8.02e-08 -> $8.02\\\\cdot10^{-8}$.\n",
" Für normale Zahlen -> $0.216$.\n",
" Für nan -> nan (ohne $...$).\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",
" # nahe 0 -> 0\n",
" if xf == 0.0:\n",
" return \"$0$\"\n",
"\n",
" s = f\"{xf:.{sig}g}\" # z.B. '8.02e-08' oder '0.216'\n",
" if \"e\" in s or \"E\" in s:\n",
" mant, exp = s.lower().split(\"e\")\n",
" exp = int(exp)\n",
" return f\"${mant}\\\\cdot10^{{{exp}}}$\"\n",
" else:\n",
" return f\"${s}$\"\n",
"\n",
"\n",
"def nan_count_for_algorithm(results, example_keys, algorithm):\n",
" vals = []\n",
" for k in example_keys:\n",
" vals.extend(results[k][algorithm])\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(\"\")\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, sig=3))\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(\"\")\n",
" lines.append(r\"\\end{table}\")\n",
"\n",
" return \"\\n\".join(lines)\n",
"\n",
"\n",
"# --- Beispielaufruf ---\n",
"example_keys = list(key for i, key in enumerate(results.keys()) if table_indices[i] == 3) # oder gefiltert auf Panou Gruppe etc.\n",
"latex = build_latex_table_from_results(\n",
" results,\n",
" gha_prefix=\"GHA1\",\n",
" example_keys=example_keys,\n",
" caption=r\"Ergebnisse der Lösungsmethoden der 1. \\gls{GHA} auf einem erdähnlichen Ellipsoid (Gruppe 3)\",\n",
" label=\"tab:results_gha1_g1\",\n",
" include_nan_col=False, # True, wenn du NaN-Spalte willst\n",
" wu=wu # wichtig, falls Winkelwerte rad sind\n",
")\n",
"print(latex)"
],
"id": "98de5e2a4f419483",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\\begin{table}[H]\n",
"\\centering\n",
"\\caption{Ergebnisse der Lösungsmethoden der 1. \\gls{GHA} auf einem erdähnlichen Ellipsoid}\n",
"\\label{tab:results_algorithms}\n",
"\n",
"\\begin{tabular}{|c|c|c|c|c|c|}\n",
"\\hline\n",
"Methode & Parameterwerte & $\\max(|\\Delta \\alpha_0|)$ [$''$] & $\\max(|\\Delta \\alpha_1|)$ [$''$] & $\\max(|\\Delta s|)$ [m] & time [s] \\\\\n",
"\\Xhline{1.5pt}\n",
"numerisch & 2000 & nan & nan & nan & nan \\\\\\hline\n",
"approximiert & 600 & $9.95\\cdot10^{3}$ & $2.77\\cdot10^{3}$ & $0.000888$ & $0.108$ \\\\\\hline\n",
"ES & 20 & $1.07\\cdot10^{4}$ & $4.35\\cdot10^{3}$ & $0.000886$ & $1.47$ \\\\\\hline\n",
"\\end{tabular}\n",
"\n",
"\\end{table}\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"C:\\Users\\moell\\AppData\\Local\\Temp\\ipykernel_25588\\1918125892.py:53: RuntimeWarning:\n",
"\n",
"All-NaN slice encountered\n",
"\n"
]
}
],
"execution_count": 15
},
{
"metadata": {},
"cell_type": "code",
"outputs": [],
"execution_count": null,
"source": "",
"id": "a431f99070cdee3c"
}
],
"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
}