Compare commits

...

4 Commits

Author SHA1 Message Date
Tammo.Weber
cfeb069e29 Zusammenführung 2025-12-16 16:39:33 +01:00
Tammo.Weber
f19373ed82 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	dashboard.py
2025-12-16 16:33:57 +01:00
Tammo.Weber
0f47be3a9f Berechnungsverfahren und Darstellung 2025-12-16 16:31:24 +01:00
Tammo.Weber
30a610ccf6 Hansen Skript roh 2025-12-16 16:25:00 +01:00
2 changed files with 254 additions and 58 deletions

119
Hansen_ES_CMA.py Normal file
View File

@@ -0,0 +1,119 @@
import numpy as np
def felli(x):
N = x.shape[0]
if N < 2:
raise ValueError("dimension must be greater than one")
exponents = np.arange(N) / (N - 1)
return float(np.sum((1e6 ** exponents) * (x ** 2)))
def escma():
#Initialization
# User defined input parameters
N = 10
xmean = np.random.rand(N)
sigma = 0.5
stopfitness = 1e-10
stopeval = int(1e3 * N**2)
# Strategy parameter setting: Selection
lambda_ = 4 + int(np.floor(3 * np.log(N)))
mu = lambda_ / 2.0
# muXone recombination weights
weights = np.log(mu + 0.5) - np.log(np.arange(1, int(mu) + 1))
mu = int(np.floor(mu))
weights = weights / np.sum(weights)
mueff = np.sum(weights)**2 / np.sum(weights**2)
# Strategy parameter setting: Adaptation
cc = (4 + mueff / N) / (N + 4 + 2 * mueff / N)
cs = (mueff + 2) / (N + mueff + 5)
c1 = 2 / ((N + 1.3)**2 + mueff)
cmu = min(1 - c1,
2 * (mueff - 2 + 1 / mueff) / ((N + 2)**2 + 2 * mueff))
damps = 1 + 2 * max(0, np.sqrt((mueff - 1) / (N + 1)) - 1) + cs
# Initialize dynamic (internal) strategy parameters and constants
pc = np.zeros(N)
ps = np.zeros(N)
B = np.eye(N)
D = np.eye(N)
C = B @ D @ (B @ D).T
eigeneval = 0
chiN = np.sqrt(N) * (1 - 1/(4*N) + 1/(21 * N**2))
#Generation Loop
counteval = 0
arx = np.zeros((N, lambda_))
arz = np.zeros((N, lambda_))
arfitness = np.zeros(lambda_)
while counteval < stopeval:
# Generate and evaluate lambda offspring
for k in range(lambda_):
arz[:, k] = np.random.randn(N)
arx[:, k] = xmean + sigma * (B @ D @ arz[:, k])
arfitness[k] = felli(arx[:, k])
counteval += 1
# Sort by fitness and compute weighted mean into xmean
idx = np.argsort(arfitness)
arfitness = arfitness[idx]
arindex = idx
xold = xmean.copy()
xmean = arx[:, arindex[:mu]] @ weights
zmean = arz[:, arindex[:mu]] @ weights
# Cumulation: Update evolution paths
ps = (1 - cs) * ps + np.sqrt(cs * (2 - cs) * mueff) * (B @ zmean)
norm_ps = np.linalg.norm(ps)
hsig = norm_ps / np.sqrt(1 - (1 - cs)**(2 * counteval / lambda_)) / chiN < \
(1.4 + 2 / (N + 1))
hsig = 1.0 if hsig else 0.0
pc = (1 - cc) * pc + hsig * np.sqrt(cc * (2 - cc) * mueff) * (B @ D @ zmean)
# Adapt covariance matrix C
BDz = B @ D @ arz[:, arindex[:mu]]
C = (1 - c1 - cmu) * C \
+ c1 * (np.outer(pc, pc) + (1 - hsig) * cc * (2 - cc) * C) \
+ cmu * BDz @ np.diag(weights) @ BDz.T
# Adapt step-size sigma
sigma = sigma * np.exp((cs / damps) * (norm_ps / chiN - 1))
# Update B and D from C (Eigenzerlegung, O(N^2))
if counteval - eigeneval > lambda_ / ((c1 + cmu) * N * 10):
eigeneval = counteval
# enforce symmetry
C = (C + C.T) / 2.0
eigvals, B = np.linalg.eigh(C)
D = np.diag(np.sqrt(eigvals))
# Break, if fitness is good enough
if arfitness[0] <= stopfitness:
break
# Escape flat fitness, or better terminate?
if arfitness[0] == arfitness[int(np.ceil(0.7 * lambda_)) - 1]:
sigma = sigma * np.exp(0.2 + cs / damps)
print("warning: flat fitness, consider reformulating the objective")
print(f"{counteval}: {arfitness[0]}")
#Final Message
print(f"{counteval}: {arfitness[0]}")
xmin = arx[:, arindex[0]]
return xmin
if __name__ == "__main__":
xmin = escma()
print("Bestes gefundenes x:", xmin)
print("f(xmin) =", felli(xmin))

View File

@@ -4,9 +4,11 @@ import plotly.graph_objects as go
import numpy as np
from GHA_triaxial.panou import gha1_ana
from GHA_triaxial.panou import gha1_num
from GHA_triaxial.panou_2013_2GHA_num import gha2_num
from ellipsoide import EllipsoidTriaxial
import winkelumrechnungen as wu
import ausgaben as aus
app = Dash(__name__, suppress_callback_exceptions=True)
@@ -149,15 +151,16 @@ def figure_lines(fig, lines):
return fig
app.layout = html.Div(
style={"fontFamily": "Arial", "margin": "40px"},
style={"fontFamily": "Arial", "padding": "5px", "width": "70%", "margin-left": "auto"},
children=[
html.H1("Geodätische Hauptaufgaben"),
html.H2("für dreiachsige Ellipsoide"),
html.Label("Ellipsoid wählen:"),
dcc.Dropdown(
id="dropdown_ellispoid",
id="my-dropdown",
options=[
{"label": "BursaFialova1993", "value": "BursaFialova1993"},
{"label": "BursaSima1980", "value": "BursaSima1980"},
@@ -165,7 +168,7 @@ app.layout = html.Div(
{"label": "Eitschberger1978", "value": "Eitschberger1978"},
{"label": "Bursa1972", "value": "Bursa1972"},
{"label": "Bursa1970", "value": "Bursa1970"},
{"label": "Bessel-biaxial", "value": "Bessel-biaxial"},
{"label": "BesselBiaxial", "value": "BesselBiaxial"},
{"label": "Fiction", "value": "Fiction"},
#{"label": "Ei", "value": "Ei"},
],
@@ -175,26 +178,29 @@ app.layout = html.Div(
html.Label("Halbachsen:"),
dcc.Input(
id="input_ax",
id="input-1",
type="number",
min=0,
placeholder="ax...[m]",
style={"marginBottom": "10px", "display": "block", "width": "300px"},
),
dcc.Input(
id="input_ay",
id="input-2",
type="number",
min=0,
placeholder="ay...[m]",
style={"marginBottom": "10px", "display": "block", "width": "300px"},
),
dcc.Input(
id="input_b",
id="input-3",
type="number",
min=0,
placeholder="b...[m]",
style={"marginBottom": "20px", "display": "block", "width": "300px"},
),
html.Button(
"Ellipsoid Berechnen",
"Ellipsoid berechnen",
id="calc-ell",
n_clicks=0,
style={"marginRight": "10px", "marginBottom": "20px"},
@@ -229,11 +235,9 @@ app.layout = html.Div(
html.P(
"© 2025",
style={
"margin": 0,
"fontSize": "12px",
"color": "gray",
"textAlign": "center",
"padding": "5px 0",
},
),
],
@@ -241,15 +245,16 @@ app.layout = html.Div(
@app.callback(
Output("input_ax", "value"),
Output("input_ay", "value"),
Output("input_b", "value"),
Input("dropdown_ellispoid", "value"),
Output("input-1", "value"),
Output("input-2", "value"),
Output("input-3", "value"),
Input("my-dropdown", "value"),
)
def fill_inputs_from_dropdown(selected_ell):
if not selected_ell:
return None, None, None
ell = EllipsoidTriaxial.init_name(selected_ell)
ax = ell.ax
ay = ell.ay
@@ -260,15 +265,19 @@ def fill_inputs_from_dropdown(selected_ell):
@app.callback(
Output("output-area", "children"),
Input("calc-ell", "n_clicks"),
State("input_ax", "value"),
State("input_b", "value"),
State("input-1", "value"),
State("input-2", "value"),
State("input-3", "value"),
)
def update_output(n_clicks, ax, b):
if not n_clicks or ax is None or b is None:
def update_output(n_clicks, ax, ay, b):
if not n_clicks:
return ""
f = abplattung(ax, b)
return f"Abplattung f = {f:.10e}"
if n_clicks and ax is None or ay is None or b is None:
return html.Span("Bitte Ellipsoid auswählen!", style={"color": "red"})
if ay >= ax or b >= ay or ax <= 0 or ay <= 0 or b <= 0:
return html.Span("Eingabe inkorrekt.", style={"color": "red"})
ell = EllipsoidTriaxial(ax, ay, b)
return f"ex = {round(ell.ex, 6)}, ", f"ey = {round(ell.ey, 6)}, ", f"ee = {round(ell.ee, 6)}"
@app.callback(
Output("tabs-GHA-out", "children"),
@@ -280,13 +289,13 @@ def render_content(tab):
pane_gha1 = html.Div(
[
dcc.Input(id="input-GHA1-beta1", type="number", placeholder="β1...[°]",
dcc.Input(id="input-GHA1-beta1", type="number", min=-90, max=90, placeholder="β1...[°]",
style={"marginBottom": "20px", "display": "block", "width": "300px"}),
dcc.Input(id="input-GHA1-lamb1", type="number", placeholder="λ1...[°]",
dcc.Input(id="input-GHA1-lamb1", type="number", min=-180, max=180, placeholder="λ1...[°]",
style={"marginBottom": "20px", "display": "block", "width": "300px"}),
dcc.Input(id="input-GHA1-s", type="number", placeholder="s...[m]",
dcc.Input(id="input-GHA1-s", type="number", min=0, placeholder="s...[m]",
style={"marginBottom": "20px", "display": "block", "width": "300px"}),
dcc.Input(id="input-GHA1-a", type="number", placeholder="α...[°]",
dcc.Input(id="input-GHA1-a", type="number", min=0, max=360, placeholder="α...[°]",
style={"marginBottom": "20px", "display": "block", "width": "300px"}),
dcc.Checklist(
@@ -317,19 +326,18 @@ def render_content(tab):
pane_gha2 = html.Div(
[
dcc.Input(id="input-GHA2-beta1", type="number", placeholder="β1...[°]",
dcc.Input(id="input-GHA2-beta1", type="number", min=-90, max=90, placeholder="β1...[°]",
style={"marginBottom": "20px", "display": "block", "width": "300px"}),
dcc.Input(id="input-GHA2-lamb1", type="number", placeholder="λ1...[°]",
dcc.Input(id="input-GHA2-lamb1", type="number", min=-180, max=180, placeholder="λ1...[°]",
style={"marginBottom": "20px", "display": "block", "width": "300px"}),
dcc.Input(id="input-GHA2-beta2", type="number", placeholder="β2...[°]",
dcc.Input(id="input-GHA2-beta2", type="number", min=-90, max=90, placeholder="β2...[°]",
style={"marginBottom": "20px", "display": "block", "width": "300px"}),
dcc.Input(id="input-GHA2-lamb2", type="number", placeholder="λ2...[°]",
dcc.Input(id="input-GHA2-lamb2", type="number", min=-180, max=180, placeholder="λ2...[°]",
style={"marginBottom": "20px", "display": "block", "width": "300px"}),
dcc.Checklist(
id="method-checklist-2",
options=[
{"label": "Analytisch", "value": "analytisch"},
{"label": "Numerisch", "value": "numerisch"},
{"label": "Stochastisch (ES)", "value": "stochastisch"},
],
@@ -369,25 +377,31 @@ def render_content(tab):
State("input-GHA2-lamb1", "value"),
State("input-GHA2-beta2", "value"),
State("input-GHA2-lamb2", "value"),
State("dropdown_ellispoid", "value"),
State("input-1", "value"),
State("input-2", "value"),
State("input-3", "value"),
State("method-checklist-1", "value"),
State("method-checklist-2", "value"),
prevent_initial_call=True,
)
def calc_and_plot(n1, n2,
beta11, lamb11, s, a_deg,
beta1, lamb1, beta2, lamb2,
ell_name):
beta21, lamb21, beta22, lamb22,
ax, ay, b, method1, method2):
if not (n1 or n2):
return no_update, no_update, no_update
if not ell_name:
return "Bitte Ellipsoid wählen.", "", go.Figure()
if not ax or not ay or not b:
return html.Span("Bitte Ellipsoid auswählen!", style={"color": "red"}), "", go.Figure()
ell = EllipsoidTriaxial.init_name(ell_name)
ell = EllipsoidTriaxial(ax, ay, b)
if dash.ctx.triggered_id == "button-calc-gha1":
if None in (beta11, lamb11, s, a_deg):
return "Bitte β₁, λ₁, s und α eingeben.", "", go.Figure()
return html.Span("Bitte β₁, λ₁, s und α eingeben.", style={"color": "red"}), "", go.Figure()
beta_rad = wu.deg2rad(float(beta11))
lamb_rad = wu.deg2rad(float(lamb11))
@@ -395,39 +409,102 @@ def calc_and_plot(n1, n2,
s_val = float(s)
p1 = tuple(map(float, ell.ell2cart(beta_rad, lamb_rad)))
out1 = []
if "analytisch" in method1:
# ana
x2, y2, z2 = gha1_ana(ell, p1, alpha_rad, s_val, 70)
p2 = (float(x2), float(y2), float(z2))
p2_ana = (float(x2), float(y2), float(z2))
beta2, lamb2 = ell.cart2ell([x2, y2, z2])
#out1 += f"kartesisch: x₂={p2[0]:.5f} m, y₂={p2[1]:.5f} m, z₂={p2[2]:.5f} m; ellipsoidisch: {aus.gms("β₂", beta2, 5)}, {aus.gms("λ₂", lamb2, 5)},"
out1.append(
html.Div([
html.Strong("Analytisch: "),
html.Br(),
html.Span(f"kartesisch: x₂={x2:.4f} m, y₂={y2:.4f} m, z₂={z2:.4f} m"),
html.Br(),
html.Span(f"ellipsoidisch: {aus.gms('β₂', beta2, 4)}, {aus.gms('λ₂', lamb2, 4)}")
])
)
if "numerisch" in method1:
# num
#p2_num = gha1_num(ell, p1, alpha_rad, s_val, 1000)
p2_num = 5
#out1 += f" {p2_num}"
out1.append(
html.Div([
html.Strong("Numerisch: "),
html.Span(f"{p2_num}")
])
)
if "stochastisch" in method1:
# stoch
p2_stoch = "noch nicht implementiert.."
out1.append(
html.Div([
html.Strong("Stochastisch (ES): "),
html.Span(f"{p2_stoch}")
])
)
if not method1:
return html.Span("Bitte Berechnungsverfahren auswählen!", style={"color": "red"}), "", go.Figure()
fig = ellipsoid_figure(ell, title="Erste Hauptaufgabe - analystisch")
fig = figure_constant_lines(fig, ell, "geod")
#fig = figure_constant_lines(fig, ell, "geod")
fig = figure_constant_lines(fig, ell, "ell")
fig = figure_constant_lines(fig, ell, "para")
fig = figure_points(fig, [("P1", p1, "black"), ("P2", p2, "red")])
fig = figure_lines(fig, [(p1, p2, "red")])
#fig = figure_constant_lines(fig, ell, "para")
fig = figure_points(fig, [("P1", p1, "black"), ("P2", p2_ana, "red")])
out1 = f"x₂={p2[0]:.3f}, y₂={p2[1]:.3f}, z₂={p2[2]:.3f}"
#out1 = f"kartesisch: x₂={p2[0]:.5f} m, y₂={p2[1]:.5f} m, z₂={p2[2]:.5f} m; ellipsoidisch: {aus.gms("β₂", beta2, 5)}, {aus.gms("λ₂", lamb2, 5)}, {p2_num}"
return out1, "", fig
if dash.ctx.triggered_id == "button-calc-gha2":
if None in (beta1, lamb1, beta2, lamb2):
return "", "Bitte β₁, λ₁, β₂, λ₂ eingeben.", go.Figure()
if None in (beta21, lamb21, beta22, lamb22):
return html.Span("Bitte β₁, λ₁, β₂, λ₂ eingeben.", style={"color": "red"}), "", go.Figure()
p1 = tuple(ell.ell2cart(np.deg2rad(float(beta21)), np.deg2rad(float(lamb21))))
p2 = tuple(ell.ell2cart(np.deg2rad(float(beta22)), np.deg2rad(float(lamb22))))
out2 = []
if "numerisch" in method2:
alpha_1, alpha_2, s12 = gha2_num(
ell,
np.deg2rad(float(beta1)), np.deg2rad(float(lamb1)),
np.deg2rad(float(beta2)), np.deg2rad(float(lamb2))
np.deg2rad(float(beta21)), np.deg2rad(float(lamb21)),
np.deg2rad(float(beta22)), np.deg2rad(float(lamb22))
)
p1 = tuple(ell.ell2cart(np.deg2rad(float(beta1)), np.deg2rad(float(lamb1))))
p2 = tuple(ell.ell2cart(np.deg2rad(float(beta2)), np.deg2rad(float(lamb2))))
out2.append(
html.Div([
html.Strong("Numerisch: "),
html.Span(f"{aus.gms('α₁₂', alpha_1, 4)}, {aus.gms('α₂₁', alpha_2, 4)}, s = {s12:.4f} m"),
])
)
fig = ellipsoid_figure(ell, title="Zweite Hauptaufgabe - numerisch")
fig = figure_constant_lines(fig, ell, "para")
if "stochastisch" in method2:
# stoch
a_stoch = "noch nicht implementiert.."
out2.append(
html.Div([
html.Strong("Stochastisch (ES): "),
html.Span(f"{a_stoch}")
])
)
if not method2:
return html.Span("Bitte Berechnungsverfahren auswählen!", style={"color": "red"}), "", go.Figure()
fig = ellipsoid_figure(ell, title="Zweite Hauptaufgabe")
fig = figure_constant_lines(fig, ell, "ell")
fig = figure_points(fig, [("P1", p1, "black"), ("P2", p2, "red")])
fig = figure_lines(fig, [(p1, p2, "red")])
out2 = f"a₁₂={np.rad2deg(alpha_1):.6f}°, a₂₁={np.rad2deg(alpha_2):.6f}°, s={s12:.4f} m"
return "", out2, fig
return no_update, no_update, no_update