Abgabe fertig
This commit is contained in:
@@ -1,277 +0,0 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from codeop import PyCF_ALLOW_INCOMPLETE_INPUT
|
||||
from typing import List, Optional, Tuple
|
||||
import numpy as np
|
||||
from ellipsoide import EllipsoidTriaxial
|
||||
from GHA_triaxial.gha1_ana import gha1_ana
|
||||
from GHA_triaxial.gha1_approx import gha1_approx
|
||||
from Hansen_ES_CMA import escma
|
||||
from utils_angle import wrap_mpi_pi
|
||||
from numpy.typing import NDArray
|
||||
import winkelumrechnungen as wu
|
||||
|
||||
|
||||
def ellipsoid_formparameter(ell: EllipsoidTriaxial):
|
||||
"""
|
||||
Berechnet die Formparameter des dreiachsigen Ellipsoiden nach Karney (2025), Gl. (2)
|
||||
:param ell: Ellipsoid
|
||||
:return: e, k und k'
|
||||
"""
|
||||
nenner = np.sqrt(max(ell.ax * ell.ax - ell.b * ell.b, 0.0))
|
||||
k = np.sqrt(max(ell.ay * ell.ay - ell.b * ell.b, 0.0)) / nenner
|
||||
k_ = np.sqrt(max(ell.ax * ell.ax - ell.ay * ell.ay, 0.0)) / nenner
|
||||
e = np.sqrt(max(ell.ax * ell.ax - ell.b * ell.b, 0.0)) / ell.ay
|
||||
|
||||
return e, k, k_
|
||||
|
||||
|
||||
def ENU_beta_omega(beta: float, omega: float, ell: EllipsoidTriaxial) \
|
||||
-> Tuple[NDArray, NDArray, NDArray, float, float, NDArray]:
|
||||
"""
|
||||
Analytische ENU-Basis in ellipsoidische Koordinaten (β, ω) nach Karney (2025), S. 2
|
||||
:param beta: Beta Koordinate
|
||||
:param omega: Omega Koordinate
|
||||
:param ell: Ellipsoid
|
||||
:return: E_hat = Einheitsrichtung entlang wachsendem ω (East)
|
||||
N_hat = Einheitsrichtung entlang wachsendem β (North)
|
||||
U_hat = Einheitsnormale (Up)
|
||||
En & Nn = Längen der unnormierten Ableitungen
|
||||
R (XYZ) = Punkt in XYZ
|
||||
"""
|
||||
# Berechnungshilfen
|
||||
omega = wrap_mpi_pi(omega)
|
||||
cb = np.cos(beta)
|
||||
sb = np.sin(beta)
|
||||
co = np.cos(omega)
|
||||
so = np.sin(omega)
|
||||
# D = sqrt(a^2 - c^2)
|
||||
D = np.sqrt(ell.ax*ell.ax - ell.b*ell.b)
|
||||
# Sx = sqrt(a^2 - b^2 sin^2β - c^2 cos^2β)
|
||||
Sx = np.sqrt(ell.ax*ell.ax - ell.ay*ell.ay*(sb*sb) - ell.b*ell.b*(cb*cb))
|
||||
# Sz = sqrt(a^2 sin^2ω + b^2 cos^2ω - c^2)
|
||||
Sz = np.sqrt(ell.ax*ell.ax*(so*so) + ell.ay*ell.ay*(co*co) - ell.b*ell.b)
|
||||
|
||||
# Karney Gl. (4)
|
||||
X = ell.ax * co * Sx / D
|
||||
Y = ell.ay * cb * so
|
||||
Z = ell.b * sb * Sz / D
|
||||
R = np.array([X, Y, Z], dtype=float)
|
||||
|
||||
# --- Ableitungen - Karney Gl. (5a,b,c)---
|
||||
# E = ∂R/∂ω
|
||||
dX_dw = -ell.ax * so * Sx / D
|
||||
dY_dw = ell.ay * cb * co
|
||||
dZ_dw = ell.b * sb * (so * co * (ell.ax*ell.ax - ell.ay*ell.ay) / Sz) / D
|
||||
E = np.array([dX_dw, dY_dw, dZ_dw], dtype=float)
|
||||
|
||||
# N = ∂R/∂β
|
||||
dX_db = ell.ax * co * (sb * cb * (ell.b*ell.b - ell.ay*ell.ay) / Sx) / D
|
||||
dY_db = -ell.ay * sb * so
|
||||
dZ_db = ell.b * cb * Sz / D
|
||||
N = np.array([dX_db, dY_db, dZ_db], dtype=float)
|
||||
|
||||
# U = Grad(x^2/a^2 + y^2/b^2 + z^2/c^2 - 1)
|
||||
U = np.array([X/(ell.ax*ell.ax), Y/(ell.ay*ell.ay), Z/(ell.b*ell.b)], dtype=float)
|
||||
|
||||
En = np.linalg.norm(E)
|
||||
Nn = np.linalg.norm(N)
|
||||
Un = np.linalg.norm(U)
|
||||
|
||||
N_hat = N / Nn
|
||||
E_hat = E / En
|
||||
U_hat = U / Un
|
||||
E_hat = E_hat - float(np.dot(E_hat, N_hat)) * N_hat
|
||||
E_hat = E_hat / max(np.linalg.norm(E_hat), 1e-18)
|
||||
|
||||
return E_hat, N_hat, U_hat, En, Nn, R
|
||||
|
||||
|
||||
def jacobi_konstante(beta: float, omega: float, alpha: float, ell: EllipsoidTriaxial) -> float:
|
||||
"""
|
||||
Jacobi-Konstante nach Karney (2025), Gl. (14)
|
||||
:param beta: Beta Koordinate
|
||||
:param omega: Omega Koordinate
|
||||
:param alpha: Azimut alpha
|
||||
:param ell: Ellipsoid
|
||||
:return: Jacobi-Konstante
|
||||
"""
|
||||
e, k, k_ = ellipsoid_formparameter(ell)
|
||||
gamma_jacobi = float((k ** 2) * (np.cos(beta) ** 2) * (np.sin(alpha) ** 2) - (k_ ** 2) * (np.sin(omega) ** 2) * (np.cos(alpha) ** 2))
|
||||
|
||||
return gamma_jacobi
|
||||
|
||||
|
||||
def azimuth_at_ESpoint(P_prev: NDArray, P_curr: NDArray, E_hat_curr: NDArray, N_hat_curr: NDArray, U_hat_curr: NDArray) -> float:
|
||||
"""
|
||||
Berechnet das Azimut in der lokalen Tangentialebene am aktuellen Punkt P_curr, gemessen
|
||||
an der Bewegungsrichtung vom vorherigen Punkt P_prev nach P_curr.
|
||||
:param P_prev: vorheriger Punkt
|
||||
:param P_curr: aktueller Punkt
|
||||
:param E_hat_curr: Einheitsvektor der lokalen Tangentialrichtung am Punkt P_curr
|
||||
:param N_hat_curr: Einheitsvektor der lokalen Tangentialrichtung am Punkt P_curr
|
||||
:param U_hat_curr: Einheitsnormalenvektor am Punkt P_curr
|
||||
:return: Azimut in Radiant
|
||||
"""
|
||||
v = (P_curr - P_prev).astype(float)
|
||||
vT = v - float(np.dot(v, U_hat_curr)) * U_hat_curr
|
||||
vTn = max(np.linalg.norm(vT), 1e-18)
|
||||
vT_hat = vT / vTn
|
||||
#vT_hat = vT / np.linalg.norm(vT)
|
||||
sE = float(np.dot(vT_hat, E_hat_curr))
|
||||
sN = float(np.dot(vT_hat, N_hat_curr))
|
||||
|
||||
return wrap_mpi_pi(float(np.arctan2(sE, sN)))
|
||||
|
||||
|
||||
def optimize_next_point(beta_i: float, omega_i: float, alpha_i: float, ds: float, gamma0: float,
|
||||
ell: EllipsoidTriaxial, maxSegLen: float = 1000.0, sigma0: float = None) -> Tuple[float, float, NDArray, float]:
|
||||
"""
|
||||
Berechnung der 1. GHA mithilfe der CMA-ES.
|
||||
Die CMA-ES optimiert sukzessive einen Punkt, der maxSegLen vom vorherigen Punkt entfernt und zusätzlich auf der
|
||||
geodätischen Linien liegt. Somit entsteht ein Geodäten ähnlicher Polygonzug auf der Oberfläche des dreiachsigen Ellipsoids.
|
||||
:param beta_i: Beta Koordinate am Punkt i
|
||||
:param omega_i: Omega Koordinate am Punkt i
|
||||
:param alpha_i: Azimut am Punkt i
|
||||
:param ds: Gesamtlänge
|
||||
:param gamma0: Jacobi-Konstante am Startpunkt
|
||||
:param ell: Ellipsoid
|
||||
:param maxSegLen: maximale Segmentlänge
|
||||
:param sigma0:
|
||||
:return:
|
||||
"""
|
||||
# Startbasis
|
||||
E_i, N_i, U_i, En_i, Nn_i, P_i = ENU_beta_omega(beta_i, omega_i, ell)
|
||||
# Prediktor: dβ ≈ ds cosα / |N|, dω ≈ ds sinα / |E|
|
||||
|
||||
En_eff = max(En_i, 1e-9)
|
||||
Nn_eff = max(Nn_i, 1e-9)
|
||||
|
||||
d_beta = ds * np.cos(alpha_i) / Nn_eff
|
||||
d_omega = ds * np.sin(alpha_i) / En_eff
|
||||
|
||||
# optional: harte Schritt-Clamps (verhindert wrap-chaos)
|
||||
d_beta = float(np.clip(d_beta, -0.2, 0.2)) # rad
|
||||
d_omega = float(np.clip(d_omega, -0.2, 0.2)) # rad
|
||||
|
||||
|
||||
#d_beta = ds * float(np.cos(alpha_i)) / Nn_i
|
||||
#d_omega = ds * float(np.sin(alpha_i)) / En_i
|
||||
beta_pred = beta_i + d_beta
|
||||
omega_pred = wrap_mpi_pi(omega_i + d_omega)
|
||||
|
||||
xmean = np.array([beta_pred, omega_pred], dtype=float)
|
||||
|
||||
if sigma0 is None:
|
||||
R0 = (ell.ax + ell.ay + ell.b) / 3
|
||||
sigma0 = 1e-5 * (ds / R0)
|
||||
|
||||
def fitness(x: NDArray) -> float:
|
||||
"""
|
||||
Fitnessfunktion: Fitnesscheck erfolgt anhand der Segmentlänge und der Jacobi-Konstante.
|
||||
Die Segmentlänge muss möglichst gut zum Sollwert passen. Die Jacobi-Konstante am Punkt x muss zur
|
||||
Jacobi-Konstanten am Startpunkt passen, damit der Polygonzug auf derselben geodätischen Linie bleibt.
|
||||
:param x: Koordinate in beta, lambda aus der CMA-ES
|
||||
:return: Fitnesswert (f)
|
||||
"""
|
||||
beta = x[0]
|
||||
omega = wrap_mpi_pi(x[1])
|
||||
|
||||
P = ell.ell2cart_karney(beta, omega) # in kartesischer Koordinaten
|
||||
d = float(np.linalg.norm(P - P_i)) # Distanz zwischen
|
||||
|
||||
# maxSegLen einhalten
|
||||
J_len = ((d - ds) / ds) ** 2
|
||||
w_len = 1.0
|
||||
|
||||
# Azimut für Jacobi-Konstante
|
||||
E_j, N_j, U_j, _, _, _ = ENU_beta_omega(beta, omega, ell)
|
||||
alpha_end = azimuth_at_ESpoint(P_i, P, E_j, N_j, U_j)
|
||||
|
||||
# Jacobi-Konstante
|
||||
g_end = jacobi_konstante(beta, omega, alpha_end, ell)
|
||||
J_gamma = (g_end - gamma0) ** 2
|
||||
w_gamma = 10
|
||||
|
||||
f = float(w_len * J_len + w_gamma * J_gamma)
|
||||
|
||||
return f
|
||||
|
||||
|
||||
xb = escma(fitness, N=2, xmean=xmean, sigma=sigma0) # Aufruf CMA-ES
|
||||
|
||||
beta_best = xb[0]
|
||||
omega_best = wrap_mpi_pi(xb[1])
|
||||
P_best = ell.ell2cart_karney(beta_best, omega_best)
|
||||
E_j, N_j, U_j, _, _, _ = ENU_beta_omega(beta_best, omega_best, ell)
|
||||
alpha_end = azimuth_at_ESpoint(P_i, P_best, E_j, N_j, U_j)
|
||||
|
||||
return beta_best, omega_best, P_best, alpha_end
|
||||
|
||||
|
||||
def gha1_ES(ell: EllipsoidTriaxial, beta0: float, omega0: float, alpha0: float, s_total: float, maxSegLen: float = 1000, all_points: boolean = False)\
|
||||
-> Tuple[NDArray, float, NDArray] | Tuple[NDArray, float]:
|
||||
"""
|
||||
Aufruf der 1. GHA mittels CMA-ES
|
||||
:param ell: Ellipsoid
|
||||
:param beta0: Beta Startkoordinate
|
||||
:param omega0: Omega Startkoordinate
|
||||
:param alpha0: Azimut Startkoordinate
|
||||
:param s_total: Gesamtstrecke
|
||||
:param maxSegLen: maximale Segmentlänge
|
||||
:param all_points: Alle Punkte ausgeben?
|
||||
:return: Zielpunkt Pk, Azimut am Zielpunkt und Punktliste
|
||||
"""
|
||||
beta = float(beta0)
|
||||
omega = wrap_mpi_pi(float(omega0))
|
||||
alpha = wrap_mpi_pi(float(alpha0))
|
||||
|
||||
gamma0 = jacobi_konstante(beta, omega, alpha, ell) # Referenz-γ0
|
||||
|
||||
P_all: List[NDArray] = [ell.ell2cart_karney(beta, omega)]
|
||||
alpha_end: List[float] = [alpha]
|
||||
|
||||
s_acc = 0.0
|
||||
step = 0
|
||||
nsteps_est = int(np.ceil(s_total / maxSegLen))
|
||||
while s_acc < s_total - 1e-9:
|
||||
step += 1
|
||||
ds = min(maxSegLen, s_total - s_acc)
|
||||
# print(f"[GHA1-ES] Step {step}/{nsteps_est} ds={ds:.3f} m s_acc={s_acc:.3f} m beta={beta:.6f} omega={omega:.6f} alpha={alpha:.6f}")
|
||||
|
||||
beta, omega, P, alpha = optimize_next_point(beta_i=beta, omega_i=omega, alpha_i=alpha, ds=ds, gamma0=gamma0,
|
||||
ell=ell, maxSegLen=maxSegLen)
|
||||
s_acc += ds
|
||||
P_all.append(P)
|
||||
alpha_end.append(wrap_mpi_pi(alpha))
|
||||
if step > nsteps_est + 50:
|
||||
raise RuntimeError("GHA1_ES: Zu viele Schritte – vermutlich Konvergenzproblem / falsche Azimut-Konvention.")
|
||||
Pk = P_all[-1]
|
||||
alpha1 = float(alpha_end[-1])
|
||||
|
||||
if all_points:
|
||||
return Pk, alpha1, np.array(P_all)
|
||||
else:
|
||||
return Pk, alpha1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
ell = EllipsoidTriaxial.init_name("BursaSima1980round")
|
||||
s = 180000
|
||||
#alpha0 = 3
|
||||
alpha0 = wu.gms2rad([5 ,0 ,0])
|
||||
beta = 0
|
||||
omega = 0
|
||||
P0 = ell.ell2cart(beta, omega)
|
||||
point1, alpha1 = gha1_ana(ell, P0, alpha0=alpha0, s=s, maxM=100, maxPartCircum=32)
|
||||
point1app, alpha1app = gha1_approx(ell, P0, alpha0=alpha0, s=s, ds=1000)
|
||||
|
||||
res, alpha, points = gha1_ES(ell, beta0=beta, omega0=-omega, alpha0=alpha0, s_total=s, maxSegLen=1000)
|
||||
|
||||
print(point1)
|
||||
print(res)
|
||||
print(alpha)
|
||||
print(points)
|
||||
#print("alpha1 (am Endpunkt):", res.alpha1)
|
||||
print(res - point1)
|
||||
print(point1app - point1, "approx")
|
||||
@@ -3,13 +3,13 @@ from math import comb
|
||||
from typing import Tuple
|
||||
|
||||
import numpy as np
|
||||
from numpy import sin, cos, arctan2
|
||||
from numpy import arctan2, cos, sin
|
||||
from numpy.typing import NDArray
|
||||
import winkelumrechnungen as wu
|
||||
from utils_angle import wrap_0_2pi
|
||||
|
||||
from ellipsoide import EllipsoidTriaxial
|
||||
import winkelumrechnungen as wu
|
||||
from GHA_triaxial.utils import pq_para
|
||||
from ellipsoid_triaxial import EllipsoidTriaxial
|
||||
from utils_angle import wrap_0_2pi
|
||||
|
||||
|
||||
def gha1_ana_step(ell: EllipsoidTriaxial, point: NDArray, alpha0: float, s: float, maxM: int) -> Tuple[NDArray, float]:
|
||||
@@ -143,4 +143,3 @@ if __name__ == "__main__":
|
||||
p0 = ell.ell2cart(wu.deg2rad(10), wu.deg2rad(20))
|
||||
p1, alpha1 = gha1_ana(ell, p0, wu.deg2rad(36), 200000, 70)
|
||||
print(p1, wu.rad2gms(alpha1))
|
||||
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
import numpy as np
|
||||
from numpy import sin, cos
|
||||
from numpy.typing import NDArray
|
||||
from ellipsoide import EllipsoidTriaxial
|
||||
from GHA_triaxial.gha1_ana import gha1_ana
|
||||
from GHA_triaxial.utils import func_sigma_ell, louville_constant, pq_ell
|
||||
import plotly.graph_objects as go
|
||||
import winkelumrechnungen as wu
|
||||
from utils_angle import wrap_0_2pi, wrap_mhalfpi_halfpi, wrap_mpi_pi
|
||||
from typing import Tuple
|
||||
|
||||
def gha1_approx(ell: EllipsoidTriaxial, p0: np.ndarray, alpha0: float, s: float, ds: float, all_points: bool = False) -> Tuple[NDArray, float] | Tuple[NDArray, float, NDArray]:
|
||||
import numpy as np
|
||||
import plotly.graph_objects as go
|
||||
from numpy import cos, sin
|
||||
from numpy.typing import NDArray
|
||||
|
||||
import winkelumrechnungen as wu
|
||||
from GHA_triaxial.utils import louville_constant, pq_ell
|
||||
from ellipsoid_triaxial import EllipsoidTriaxial
|
||||
from utils_angle import wrap_0_2pi
|
||||
|
||||
|
||||
def gha1_approx(ell: EllipsoidTriaxial, p0: np.ndarray, alpha0: float, s: float, ds: float, all_points: bool = False) \
|
||||
-> Tuple[NDArray, float] | Tuple[NDArray, float, NDArray, NDArray]:
|
||||
"""
|
||||
Berechung einer Näherungslösung der ersten Hauptaufgabe
|
||||
:param ell: Ellipsoid
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
from typing import Callable, List, Tuple
|
||||
|
||||
import numpy as np
|
||||
from numpy import sin, cos, arctan2
|
||||
import ellipsoide
|
||||
import runge_kutta as rk
|
||||
import winkelumrechnungen as wu
|
||||
import GHA_triaxial.numeric_examples_karney as ne_karney
|
||||
from GHA_triaxial.gha1_ana import gha1_ana
|
||||
from ellipsoide import EllipsoidTriaxial
|
||||
from typing import Callable, Tuple, List
|
||||
from numpy import arctan2, cos, sin
|
||||
from numpy.typing import NDArray
|
||||
|
||||
import GHA_triaxial.numeric_examples_karney as ne_karney
|
||||
import runge_kutta as rk
|
||||
import winkelumrechnungen as wu
|
||||
from GHA_triaxial.gha1_ana import gha1_ana
|
||||
from GHA_triaxial.utils import alpha_ell2para, pq_ell
|
||||
from ellipsoid_triaxial import EllipsoidTriaxial
|
||||
from utils_angle import wrap_0_2pi
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ if __name__ == "__main__":
|
||||
# diffs_panou[mask_360] = np.abs(diffs_panou[mask_360] - 360)
|
||||
# print(diffs_panou)
|
||||
|
||||
ell: EllipsoidTriaxial = ellipsoide.EllipsoidTriaxial.init_name("KarneyTest2024")
|
||||
ell: EllipsoidTriaxial = EllipsoidTriaxial.init_name("KarneyTest2024")
|
||||
diffs_karney = []
|
||||
# examples_karney = ne_karney.get_examples((30499, 30500, 40500))
|
||||
examples_karney = ne_karney.get_random_examples(20)
|
||||
|
||||
@@ -1,186 +0,0 @@
|
||||
import numpy as np
|
||||
from Hansen_ES_CMA import escma
|
||||
from ellipsoide import EllipsoidTriaxial
|
||||
from numpy.typing import NDArray
|
||||
from typing import Tuple
|
||||
import plotly.graph_objects as go
|
||||
from GHA_triaxial.gha2_num import gha2_num
|
||||
from GHA_triaxial.utils import sigma2alpha, pq_ell
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def Sehne(P1: NDArray, P2: NDArray) -> float:
|
||||
"""
|
||||
Berechnung der 3D-Distanz zwischen zwei kartesischen Punkten
|
||||
:param P1: kartesische Koordinate Punkt 1
|
||||
:param P2: kartesische Koordinate Punkt 2
|
||||
:return: Bogenlänge s
|
||||
"""
|
||||
R12 = P2-P1
|
||||
s = np.linalg.norm(R12)
|
||||
|
||||
return s
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def gha2_ES(ell: EllipsoidTriaxial, P0: NDArray, Pk: NDArray, maxSegLen: float = None, all_points: bool = False) -> Tuple[float, float, float, NDArray] | Tuple[float, float, float]:
|
||||
"""
|
||||
Berechnen der 2. GHA mithilfe der CMA-ES.
|
||||
Die CMA-ES optimiert sukzessive den Mittelpunkt zwischen Start- und Zielpunkt. Der Abbruch der Berechnung erfolgt, wenn alle Segmentlängen <= maxSegLen sind.
|
||||
Die Distanzen zwischen den einzelnen Punkten werden als direkte 3D-Distanzen berechnet und aufaddiert.
|
||||
:param ell: Ellipsoid
|
||||
:param P0: Startpunkt
|
||||
:param Pk: Zielpunkt
|
||||
:param maxSegLen: maximale Segmentlänge
|
||||
:param all_points: Ergebnisliste mit allen Punkte, die wahlweise mit ausgegeben wird
|
||||
:return: Richtungswinkel in RAD des Start- und Zielpunktes und Gesamtlänge
|
||||
"""
|
||||
P_left: NDArray = None
|
||||
P_right: NDArray = None
|
||||
|
||||
def midpoint_fitness(x: tuple) -> float:
|
||||
"""
|
||||
Fitness für einen Mittelpunkt P_middle zwischen P_left und P_right auf dem triaxialen Ellipsoid:
|
||||
- Minimiert d(P_left, P_middle) + d(P_middle, P_right)
|
||||
- Erzwingt d(P_left,P_middle) ≈ d(P_middle,P_right) (echter Mittelpunkt im Sinne der Polygonkette)
|
||||
:param x: enthält die Startwerte von u und v
|
||||
:return: Fitnesswert (f)
|
||||
"""
|
||||
nonlocal P_left, P_right, ell
|
||||
|
||||
u, v = x
|
||||
P_middle = ell.para2cart(u, v)
|
||||
d1 = Sehne(P_left, P_middle)
|
||||
d2 = Sehne(P_middle, P_right)
|
||||
base = d1 + d2
|
||||
|
||||
# midpoint penalty (dimensionslos)
|
||||
# relative Differenz, skaliert über verschiedene Segmentlängen
|
||||
denom = max(base, 1e-9)
|
||||
pen_equal = ((d1 - d2) / denom) ** 2
|
||||
w_equal = 10.0
|
||||
|
||||
f = base + denom * w_equal * pen_equal
|
||||
|
||||
return f
|
||||
|
||||
R0 = (ell.ax + ell.ay + ell.b) / 3
|
||||
if maxSegLen is None:
|
||||
maxSegLen = R0 * 1 / (637.4*2) # 10km Segment bei mittleren Erdradius
|
||||
|
||||
sigma_uv_nom = 1e-3 * (maxSegLen / R0) # ~1e-5
|
||||
points: list[NDArray] = [P0, Pk]
|
||||
startIter = 0
|
||||
level = 0
|
||||
|
||||
while True:
|
||||
seg_lens = [Sehne(points[i], points[i+1]) for i in range(len(points)-1)]
|
||||
max_len = max(seg_lens)
|
||||
if max_len <= maxSegLen:
|
||||
break
|
||||
|
||||
level += 1
|
||||
new_points: list[NDArray] = [points[0]]
|
||||
for i in range(len(points) - 1):
|
||||
A = points[i]
|
||||
B = points[i+1]
|
||||
dAB = Sehne(A, B)
|
||||
# print(dAB)
|
||||
|
||||
if dAB > maxSegLen:
|
||||
# global P_left, P_right
|
||||
P_left, P_right = A, B
|
||||
Au, Av = ell.cart2para(A)
|
||||
Bu, Bv = ell.cart2para(B)
|
||||
u0 = (Au + Bu) / 2
|
||||
v0 = Av + 0.5 * np.arctan2(np.sin(Bv - Av), np.cos(Bv - Av))
|
||||
xmean = [u0, v0]
|
||||
|
||||
sigmaStep = sigma_uv_nom * (Sehne(A, B) / maxSegLen)
|
||||
|
||||
u, v = escma(midpoint_fitness, N=2, xmean=xmean, sigma=sigmaStep) # Aufruf CMA-ES
|
||||
|
||||
P_next = ell.para2cart(u, v)
|
||||
new_points.append(P_next)
|
||||
startIter += 1
|
||||
maxIter = 10000
|
||||
if startIter > maxIter:
|
||||
raise RuntimeError("GHA2_ES: maximale Iterationen überschritten")
|
||||
new_points.append(B)
|
||||
|
||||
points = new_points
|
||||
# print(f"[Level {level}] Punkte: {len(points)} | max Segment: {max_len:.3f} m")
|
||||
|
||||
P_all = np.vstack(points)
|
||||
totalLen = float(np.sum(np.linalg.norm(P_all[1:] - P_all[:-1], axis=1)))
|
||||
|
||||
if len(points) >= 3:
|
||||
p0i = ell.point_onto_ellipsoid(P0 + 10.0 * (points[1] - P0) / np.linalg.norm(points[1] - P0))
|
||||
sigma0 = (p0i - P0) / np.linalg.norm(p0i - P0)
|
||||
alpha0 = sigma2alpha(ell, sigma0, P0)
|
||||
|
||||
p1i = ell.point_onto_ellipsoid(Pk - 10.0 * (Pk - points[-2]) / np.linalg.norm(Pk - points[-2]))
|
||||
sigma1 = (Pk - p1i) / np.linalg.norm(Pk - p1i)
|
||||
alpha1 = sigma2alpha(ell, sigma1, Pk)
|
||||
else:
|
||||
alpha0 = None
|
||||
alpha1 = None
|
||||
|
||||
if all_points:
|
||||
return alpha0, alpha1, totalLen, P_all
|
||||
return alpha0, alpha1, totalLen
|
||||
|
||||
|
||||
def show_points(points: NDArray, pointsES: NDArray, p0: NDArray, p1: NDArray):
|
||||
"""
|
||||
Anzeigen der Punkte
|
||||
:param points: wahre Punkte der Linie
|
||||
:param pointsES: Punkte der Linie aus ES
|
||||
:param p0: wahrer Startpunkt
|
||||
:param p1: wahrer Endpunkt
|
||||
"""
|
||||
fig = go.Figure()
|
||||
|
||||
fig.add_scatter3d(x=pointsES[:, 0], y=pointsES[:, 1], z=pointsES[:, 2],
|
||||
mode='lines', line=dict(color="green", width=3), name="Numerisch")
|
||||
fig.add_scatter3d(x=points[:, 0], y=points[:, 1], z=points[:, 2],
|
||||
mode='lines', line=dict(color="red", width=3), name="ES")
|
||||
fig.add_scatter3d(x=[p0[0]], y=[p0[1]], z=[p0[2]],
|
||||
mode='markers', marker=dict(color="black"), name="P0")
|
||||
fig.add_scatter3d(x=[p1[0]], y=[p1[1]], z=[p1[2]],
|
||||
mode='markers', marker=dict(color="black"), name="P1")
|
||||
|
||||
fig.update_layout(
|
||||
scene=dict(xaxis_title='X [km]',
|
||||
yaxis_title='Y [km]',
|
||||
zaxis_title='Z [km]',
|
||||
aspectmode='data'))
|
||||
|
||||
fig.show()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
ell = EllipsoidTriaxial.init_name("Bursa1970")
|
||||
|
||||
beta0, lamb0 = (0.2, 0.1)
|
||||
P0 = ell.ell2cart(beta0, lamb0)
|
||||
beta1, lamb1 = (0.3, 0.2)
|
||||
P1 = ell.ell2cart(beta1, lamb1)
|
||||
|
||||
alpha0, alpha1, s_num, betas, lambs = gha2_num(ell, beta0, lamb0, beta1, lamb1, n=1000, all_points=True)
|
||||
points_num = []
|
||||
for beta, lamb in zip(betas, lambs):
|
||||
points_num.append(ell.ell2cart(beta, lamb))
|
||||
points_num = np.array(points_num)
|
||||
|
||||
alpha0, alpha1, s, points = gha2_ES(ell, P0, P1)
|
||||
print(s_num)
|
||||
print(s)
|
||||
print(alpha0)
|
||||
print(alpha1)
|
||||
print(s - s_num)
|
||||
show_points(points, points_num, P0, P1)
|
||||
@@ -1,12 +1,13 @@
|
||||
import numpy as np
|
||||
from ellipsoide import EllipsoidTriaxial
|
||||
from GHA_triaxial.gha2_num import gha2_num
|
||||
import plotly.graph_objects as go
|
||||
import winkelumrechnungen as wu
|
||||
from numpy.typing import NDArray
|
||||
from typing import Tuple
|
||||
|
||||
import numpy as np
|
||||
import plotly.graph_objects as go
|
||||
from numpy.typing import NDArray
|
||||
|
||||
import winkelumrechnungen as wu
|
||||
from GHA_triaxial.gha2_num import gha2_num
|
||||
from GHA_triaxial.utils import sigma2alpha
|
||||
from ellipsoid_triaxial import EllipsoidTriaxial
|
||||
|
||||
|
||||
def gha2_approx(ell: EllipsoidTriaxial, p0: NDArray, p1: NDArray, ds: float, all_points: bool = False) -> Tuple[float, float, float] | Tuple[float, float, float, NDArray]:
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import numpy as np
|
||||
from ellipsoide import EllipsoidTriaxial
|
||||
from runge_kutta import rk4, rk4_step, rk4_end, rk4_integral
|
||||
import GHA_triaxial.numeric_examples_karney as ne_karney
|
||||
import GHA_triaxial.numeric_examples_panou as ne_panou
|
||||
import winkelumrechnungen as wu
|
||||
from typing import Tuple
|
||||
|
||||
import numpy as np
|
||||
from numpy.typing import NDArray
|
||||
|
||||
import ausgaben as aus
|
||||
from utils_angle import cot, arccot, wrap_mpi_pi, wrap_0_2pi
|
||||
import numeric_examples_karney as ne_karney
|
||||
import numeric_examples_panou as ne_panou
|
||||
import winkelumrechnungen as wu
|
||||
from ellipsoid_triaxial import EllipsoidTriaxial
|
||||
from runge_kutta import rk4, rk4_end, rk4_integral
|
||||
from utils_angle import cot, wrap_0_2pi, wrap_mpi_pi
|
||||
|
||||
|
||||
def norm_a(a: float) -> float:
|
||||
@@ -176,7 +178,7 @@ def gha2_num(
|
||||
)
|
||||
p_00 = 0.5 * ((E * G_beta_beta - E_beta * G_beta) / (E**2))
|
||||
|
||||
return (BETA, LAMBDA, E, G, p_3, p_2, p_1, p_0, p_33, p_22, p_11, p_00)
|
||||
return BETA, LAMBDA, E, G, p_3, p_2, p_1, p_0, p_33, p_22, p_11, p_00
|
||||
|
||||
# Berechnung der ODE Koeffizienten für Fall 2 (lambda_0 == lambda_1)
|
||||
def q_coef(beta, lamb):
|
||||
@@ -589,53 +591,53 @@ def gha2_num(
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# ell = EllipsoidTriaxial.init_name("BursaSima1980round")
|
||||
# beta1 = np.deg2rad(75)
|
||||
# lamb1 = np.deg2rad(-90)
|
||||
# beta2 = np.deg2rad(75)
|
||||
# lamb2 = np.deg2rad(66)
|
||||
# a0, a1, s = gha2_num(ell, beta1, lamb1, beta2, lamb2, n=5000)
|
||||
# print(aus.gms("a0", a0, 4))
|
||||
# print(aus.gms("a1", a1, 4))
|
||||
# print("s: ", s)
|
||||
# # print(aus.gms("a2", a2, 4))
|
||||
# # print(s)
|
||||
# cart1 = ell.para2cart(0, 0)
|
||||
# cart2 = ell.para2cart(0.4, 1.4)
|
||||
# beta1, lamb1 = ell.cart2ell(cart1)
|
||||
# beta2, lamb2 = ell.cart2ell(cart2)
|
||||
#
|
||||
# a1, a2, s = gha2_num(ell, beta1, lamb1, beta2, lamb2, n=5000)
|
||||
ell = EllipsoidTriaxial.init_name("BursaSima1980round")
|
||||
beta1 = np.deg2rad(75)
|
||||
lamb1 = np.deg2rad(-90)
|
||||
beta2 = np.deg2rad(75)
|
||||
lamb2 = np.deg2rad(66)
|
||||
a0, a1, s = gha2_num(ell, beta1, lamb1, beta2, lamb2, n=100)
|
||||
print(aus.gms("a0", a0, 4))
|
||||
print(aus.gms("a1", a1, 4))
|
||||
print("s: ", s)
|
||||
# print(aus.gms("a2", a2, 4))
|
||||
# print(s)
|
||||
cart1 = ell.para2cart(0, 0)
|
||||
cart2 = ell.para2cart(0.4, 1.4)
|
||||
beta1, lamb1 = ell.cart2ell(cart1)
|
||||
beta2, lamb2 = ell.cart2ell(cart2)
|
||||
|
||||
# ell = EllipsoidTriaxial.init_name("BursaSima1980round")
|
||||
# diffs_panou = []
|
||||
# examples_panou = ne_panou.get_random_examples(4)
|
||||
# for example in examples_panou:
|
||||
# beta0, lamb0, beta1, lamb1, _, alpha0, alpha1, s = example
|
||||
# P0 = ell.ell2cart(beta0, lamb0)
|
||||
# try:
|
||||
# alpha0_num, alpha1_num, s_num = gha2_num(ell, beta0, lamb0, beta1, lamb1, n=4000, iter_max=10)
|
||||
# diffs_panou.append(
|
||||
# (wu.rad2deg(abs(alpha0 - alpha0_num)), wu.rad2deg(abs(alpha1 - alpha1_num)), abs(s - s_num)))
|
||||
# except:
|
||||
# print(f"Fehler für {beta0}, {lamb0}, {beta1}, {lamb1}")
|
||||
# diffs_panou = np.array(diffs_panou)
|
||||
# print(diffs_panou)
|
||||
#
|
||||
# ell = EllipsoidTriaxial.init_name("KarneyTest2024")
|
||||
# diffs_karney = []
|
||||
# # examples_karney = ne_karney.get_examples((30500, 40500))
|
||||
# examples_karney = ne_karney.get_random_examples(2)
|
||||
# for example in examples_karney:
|
||||
# beta0, lamb0, alpha0, beta1, lamb1, alpha1, s = example
|
||||
#
|
||||
# try:
|
||||
# alpha0_num, alpha1_num, s_num = gha2_num(ell, beta0, lamb0, beta1, lamb1, n=4000, iter_max=10)
|
||||
# diffs_karney.append((wu.rad2deg(abs(alpha0-alpha0_num)), wu.rad2deg(abs(alpha1-alpha1_num)), abs(s-s_num)))
|
||||
# except:
|
||||
# print(f"Fehler für {beta0}, {lamb0}, {beta1}, {lamb1}")
|
||||
# diffs_karney = np.array(diffs_karney)
|
||||
# print(diffs_karney)
|
||||
a1, a2, s = gha2_num(ell, beta1, lamb1, beta2, lamb2, n=5000)
|
||||
print(s)
|
||||
|
||||
ell = EllipsoidTriaxial.init_name("BursaSima1980round")
|
||||
diffs_panou = []
|
||||
examples_panou = ne_panou.get_random_examples(4)
|
||||
for example in examples_panou:
|
||||
beta0, lamb0, beta1, lamb1, _, alpha0, alpha1, s = example
|
||||
P0 = ell.ell2cart(beta0, lamb0)
|
||||
try:
|
||||
alpha0_num, alpha1_num, s_num = gha2_num(ell, beta0, lamb0, beta1, lamb1, n=4000, iter_max=10)
|
||||
diffs_panou.append(
|
||||
(wu.rad2deg(abs(alpha0 - alpha0_num)), wu.rad2deg(abs(alpha1 - alpha1_num)), abs(s - s_num)))
|
||||
except:
|
||||
print(f"Fehler für {beta0}, {lamb0}, {beta1}, {lamb1}")
|
||||
diffs_panou = np.array(diffs_panou)
|
||||
print(diffs_panou)
|
||||
|
||||
ell = EllipsoidTriaxial.init_name("KarneyTest2024")
|
||||
diffs_karney = []
|
||||
# examples_karney = ne_karney.get_examples((30500, 40500))
|
||||
examples_karney = ne_karney.get_random_examples(2)
|
||||
for example in examples_karney:
|
||||
beta0, lamb0, alpha0, beta1, lamb1, alpha1, s = example
|
||||
|
||||
try:
|
||||
alpha0_num, alpha1_num, s_num = gha2_num(ell, beta0, lamb0, beta1, lamb1, n=4000, iter_max=10)
|
||||
diffs_karney.append((wu.rad2deg(abs(alpha0-alpha0_num)), wu.rad2deg(abs(alpha1-alpha1_num)), abs(s-s_num)))
|
||||
except:
|
||||
print(f"Fehler für {beta0}, {lamb0}, {beta1}, {lamb1}")
|
||||
diffs_karney = np.array(diffs_karney)
|
||||
print(diffs_karney)
|
||||
|
||||
pass
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import random
|
||||
from typing import List
|
||||
|
||||
import winkelumrechnungen as wu
|
||||
from typing import List, Tuple
|
||||
import numpy as np
|
||||
from ellipsoide import EllipsoidTriaxial
|
||||
from GHA_triaxial.gha1_ES import jacobi_konstante
|
||||
from GHA_triaxial.utils import jacobi_konstante
|
||||
from ellipsoid_triaxial import EllipsoidTriaxial
|
||||
|
||||
ell = EllipsoidTriaxial.init_name("KarneyTest2024")
|
||||
file_path = r"Karney_2024_Testset.txt"
|
||||
|
||||
def line2example(line: str) -> List:
|
||||
"""
|
||||
@@ -31,7 +32,7 @@ def get_random_examples(num: int, seed: int = None) -> List:
|
||||
"""
|
||||
if seed is not None:
|
||||
random.seed(seed)
|
||||
with open(r"C:\Users\moell\OneDrive\Desktop\Vorlesungen\Master-Projekt\Python_Masterprojekt\GHA_triaxial\Karney_2024_Testset.txt") as datei:
|
||||
with open(file_path) as datei:
|
||||
lines = datei.readlines()
|
||||
examples = []
|
||||
for i in range(num):
|
||||
@@ -46,7 +47,7 @@ def get_examples(l_i: List) -> List:
|
||||
:param l_i: Liste von Indizes
|
||||
:return: Liste mit Beispielen
|
||||
"""
|
||||
with open("Karney_2024_Testset.txt") as datei:
|
||||
with open(file_path) as datei:
|
||||
lines = datei.readlines()
|
||||
examples = []
|
||||
for i in l_i:
|
||||
@@ -54,53 +55,21 @@ def get_examples(l_i: List) -> List:
|
||||
examples.append(example)
|
||||
return examples
|
||||
|
||||
# beta0, lamb0, alpha0_ell, beta1, lamb1, alpha1_ell, s
|
||||
|
||||
def get_random_examples_simple_short(num: int, seed: int = None) -> List:
|
||||
if seed is not None:
|
||||
random.seed(seed)
|
||||
with open(r"C:\Users\moell\OneDrive\Desktop\Vorlesungen\Master-Projekt\Python_Masterprojekt\GHA_triaxial\Karney_2024_Testset.txt") as datei:
|
||||
lines = datei.readlines()
|
||||
examples = []
|
||||
while len(examples) < num:
|
||||
example = line2example(lines[random.randint(0, len(lines) - 1)])
|
||||
beta0, lamb0, alpha0_ell, beta1, lamb1, alpha1_ell, s = example
|
||||
if s < 1 and abs(abs(beta0) - np.pi/2) > 1e-5 and lamb0 != 0 and abs(abs(lamb0) - np.pi) > 1e-5:
|
||||
examples.append(example)
|
||||
return examples
|
||||
|
||||
def get_random_examples_umbilics_start(num: int, seed: int = None) -> List:
|
||||
if seed is not None:
|
||||
random.seed(seed)
|
||||
with open(r"C:\Users\moell\OneDrive\Desktop\Vorlesungen\Master-Projekt\Python_Masterprojekt\GHA_triaxial\Karney_2024_Testset.txt") as datei:
|
||||
lines = datei.readlines()
|
||||
examples = []
|
||||
while len(examples) < num:
|
||||
example = line2example(lines[random.randint(0, len(lines) - 1)])
|
||||
beta0, lamb0, alpha0_ell, beta1, lamb1, alpha1_ell, s = example
|
||||
if abs(abs(beta0) - np.pi/2) < 1e-5 and (lamb0 == 0 or abs(abs(lamb0) - np.pi) < 1e-5):
|
||||
examples.append(example)
|
||||
return examples
|
||||
|
||||
def get_random_examples_umbilics_end(num: int, seed: int = None) -> List:
|
||||
if seed is not None:
|
||||
random.seed(seed)
|
||||
with open(r"C:\Users\moell\OneDrive\Desktop\Vorlesungen\Master-Projekt\Python_Masterprojekt\GHA_triaxial\Karney_2024_Testset.txt") as datei:
|
||||
lines = datei.readlines()
|
||||
examples = []
|
||||
while len(examples) < num:
|
||||
example = line2example(lines[random.randint(0, len(lines) - 1)])
|
||||
beta0, lamb0, alpha0_ell, beta1, lamb1, alpha1_ell, s = example
|
||||
if abs(abs(beta1) - np.pi/2) < 1e-5 and (lamb1 == 0 or abs(abs(lamb1) - np.pi) < 1e-5):
|
||||
examples.append(example)
|
||||
return examples
|
||||
|
||||
def get_random_examples_gamma(group: str, num: int, seed: int = None, length: str = None) -> List:
|
||||
"""
|
||||
Zufällige Beispiele aus Karney in Gruppen nach Einteilung anhand der Jacobi-Konstanten
|
||||
:param group: Gruppe
|
||||
:param num: Anzahl
|
||||
:param seed: Random-Seed
|
||||
:param length: long oder short, sond egal
|
||||
:return: Liste mit Beispielen
|
||||
"""
|
||||
eps = 1e-20
|
||||
long_short = 2
|
||||
if seed is not None:
|
||||
random.seed(seed)
|
||||
with open(r"C:\Users\moell\OneDrive\Desktop\Vorlesungen\Master-Projekt\Python_Masterprojekt\GHA_triaxial\Karney_2024_Testset.txt") as datei:
|
||||
with open(file_path) as datei:
|
||||
lines = datei.readlines()
|
||||
examples = []
|
||||
i = 0
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Tuple
|
||||
|
||||
import numpy as np
|
||||
from numpy import arctan2, sin, cos, sqrt
|
||||
from numpy import arctan2, cos, sin, sqrt
|
||||
from numpy.typing import NDArray
|
||||
from utils_angle import wrap_mpi_pi, wrap_0_2pi, wrap_mhalfpi_halfpi
|
||||
|
||||
from ellipsoide import EllipsoidTriaxial
|
||||
from ellipsoid_triaxial import EllipsoidTriaxial
|
||||
from utils_angle import wrap_0_2pi
|
||||
|
||||
|
||||
def sigma2alpha(ell: EllipsoidTriaxial, sigma: NDArray, point: NDArray) -> float:
|
||||
@@ -178,9 +180,22 @@ def pq_para(ell: EllipsoidTriaxial, point: NDArray) -> Tuple[NDArray, NDArray]:
|
||||
return p, q
|
||||
|
||||
|
||||
def jacobi_konstante(beta: float, omega: float, alpha: float, ell: EllipsoidTriaxial) -> float:
|
||||
"""
|
||||
Jacobi-Konstante nach Karney (2025), Gl. (14)
|
||||
:param beta: Beta Koordinate
|
||||
:param omega: Omega Koordinate
|
||||
:param alpha: Azimut alpha
|
||||
:param ell: Ellipsoid
|
||||
:return: Jacobi-Konstante
|
||||
"""
|
||||
gamma_jacobi = float((ell.k ** 2) * (np.cos(beta) ** 2) * (np.sin(alpha) ** 2) - (ell.k_ ** 2) * (np.sin(omega) ** 2) * (np.cos(alpha) ** 2))
|
||||
return gamma_jacobi
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
ell = EllipsoidTriaxial.init_name("KarneyTest2024")
|
||||
alpha_para = 0
|
||||
u, v = ell.ell2para(np.pi/2, 0)
|
||||
alpha_ell = alpha_para2ell(ell, u, v, alpha_para)
|
||||
pass
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user