268 lines
7.5 KiB
Python
268 lines
7.5 KiB
Python
from Stochastisches_Modell import StochastischesModell
|
|
from Netzqualität_Genauigkeit import Genauigkeitsmaße
|
|
from Datumsfestlegung import Datumsfestlegung
|
|
import numpy as np
|
|
import Export
|
|
|
|
|
|
def ausgleichung_global(A, dl, Q_ext, P):
|
|
A=np.asarray(A, float)
|
|
dl = np.asarray(dl, float).reshape(-1, 1)
|
|
Q_ext = np.asarray(Q_ext, float)
|
|
P = np.asarray(P, float)
|
|
|
|
# 1) Gewichtsmatrix P
|
|
#P = Q_ext
|
|
|
|
# 2) Normalgleichungsmatrix N und Absolutgliedvektor n
|
|
N = A.T @ P @ A
|
|
n = A.T @ P @ dl
|
|
|
|
# 3) Zuschlagsvektor dx
|
|
dx = np.linalg.solve(N, n)
|
|
|
|
# 4) Residuenvektor v
|
|
v = A @ dx - dl
|
|
|
|
# 5) Kofaktormatrix der Unbekannten Q_xx
|
|
Q_xx = StochastischesModell.berechne_Q_xx(N)
|
|
|
|
# 6) Kofaktormatrix der Beobachtungen Q_ll_dach
|
|
Q_ll_dach = StochastischesModell.berechne_Q_ll_dach(A, Q_xx)
|
|
|
|
# 7) Kofaktormatrix der Verbesserungen Q_vv
|
|
Q_vv = StochastischesModell.berechne_Qvv(Q_ext, Q_ll_dach)
|
|
|
|
# 8) Ausgabe
|
|
dict_ausgleichung = {
|
|
"dx": dx,
|
|
"v": v,
|
|
"P": P,
|
|
"N": N,
|
|
"Q_xx": Q_xx,
|
|
"Q_ll_dach": Q_ll_dach,
|
|
"Q_vv": Q_vv,
|
|
"Q_ext": Q_ext,
|
|
}
|
|
return dict_ausgleichung, dx
|
|
|
|
|
|
|
|
def ausgleichung_lokal1(A, dl, Q_ll):
|
|
A = np.asarray(A, dtype=float)
|
|
dl = np.asarray(dl, dtype=float).reshape(-1, 1)
|
|
Q_ll = np.asarray(Q_ll, dtype=float)
|
|
|
|
# 1) Gewichtsmatrix
|
|
P = np.linalg.inv(Q_ll)
|
|
|
|
# 2) Normalgleichungen
|
|
N = A.T @ P @ A
|
|
n = A.T @ P @ dl
|
|
|
|
# 3) Datumsfestlegung
|
|
G = Datumsfestlegung.build_G_from_names(x0, Jacobimatrix_symbolisch_liste_unbekannte, liste_punktnummern, mit_massstab=True)
|
|
u = A.shape[1]
|
|
aktive = Datumsfestlegung.aktive_indices_from_selection(auswahl, Jacobimatrix_symbolisch_liste_unbekannte)
|
|
E = Datumsfestlegung.auswahlmatrix_E(u, aktive)
|
|
Gi = E @ G
|
|
|
|
# 3) Zuschlagsvektor dx
|
|
dx, k = Datumsfestlegung.berechne_dx_geraendert(N, n, Gi)
|
|
|
|
# 5) Residuen
|
|
v = dl - A @ dx
|
|
|
|
# 5) Kofaktormatrix der Unbekannten Q_xx
|
|
Q_xx = StochastischesModell.berechne_Q_xx(N)
|
|
|
|
# 6) Kofaktormatrix der Beobachtungen Q_ll_dach
|
|
Q_ll_dach = StochastischesModell.berechne_Q_ll_dach(A, Q_xx)
|
|
|
|
# 7) Kofaktormatrix der Verbesserungen Q_vv
|
|
Q_vv = StochastischesModell.berechne_Qvv(Q_ll, Q_ll_dach)
|
|
|
|
# 8) Ausgabe
|
|
dict_ausgleichung = {
|
|
"dx": dx,
|
|
"v": v,
|
|
"P": P,
|
|
"N": N,
|
|
"Q_xx": Q_xx,
|
|
"Q_ll_dach": Q_ll_dach,
|
|
"Q_vv": Q_vv,
|
|
"Q_ll": Q_ll,
|
|
}
|
|
return dict_ausgleichung, dx
|
|
|
|
|
|
|
|
def ausgleichung_lokal(
|
|
A, dl, Q_ll,
|
|
*,
|
|
datumfestlegung="hart",
|
|
x0=None,
|
|
unbekannten_liste=None,
|
|
liste_punktnummern=None,
|
|
datenbank=None,
|
|
mit_massstab=True
|
|
):
|
|
A = np.asarray(A, float)
|
|
dl = np.asarray(dl, float).reshape(-1, 1)
|
|
Q_ll = np.asarray(Q_ll, float)
|
|
|
|
# 1) Gewichtsmatrix
|
|
P = np.linalg.inv(Q_ll)
|
|
|
|
# 2) Normalgleichungen
|
|
N = A.T @ P @ A
|
|
n = A.T @ P @ dl
|
|
u = N.shape[0]
|
|
|
|
# 3) Datumsfestlegung
|
|
if datumfestlegung == "weiche Lagerung":
|
|
# hier wurde Q_ll bereits extern erweitert → ganz normal lösen
|
|
dx = np.linalg.solve(N, n)
|
|
|
|
elif datumfestlegung == "gesamtspur":
|
|
if x0 is None or unbekannten_liste is None or liste_punktnummern is None:
|
|
raise ValueError("gesamtspur benötigt x0, unbekannten_liste, liste_punktnummern")
|
|
|
|
G = Datumsfestlegung.build_G_from_names(
|
|
x0,
|
|
unbekannten_liste,
|
|
liste_punktnummern,
|
|
mit_massstab=mit_massstab
|
|
)
|
|
dx, k = Datumsfestlegung.berechne_dx_geraendert(N, n, G)
|
|
|
|
elif datumfestlegung == "teilspur":
|
|
if x0 is None or unbekannten_liste is None or liste_punktnummern is None or datenbank is None:
|
|
raise ValueError("teilspur benötigt x0, unbekannten_liste, liste_punktnummern, datenbank")
|
|
|
|
# G über alle Punkte
|
|
G = Datumsfestlegung.build_G_from_names(
|
|
x0,
|
|
unbekannten_liste,
|
|
liste_punktnummern,
|
|
mit_massstab=mit_massstab
|
|
)
|
|
|
|
# Auswahl aus DB
|
|
liste_datumskoordinaten = datenbank.get_datumskoordinate()
|
|
if not liste_datumskoordinaten:
|
|
raise ValueError("Teilspur gewählt, aber keine Datumskoordinaten in der DB gesetzt.")
|
|
|
|
aktive = Datumsfestlegung.aktive_indices_from_selection(
|
|
[(s[1:], s[0]) for s in liste_datumskoordinaten],
|
|
unbekannten_liste
|
|
)
|
|
|
|
E = Datumsfestlegung.auswahlmatrix_E(u, aktive)
|
|
Gi = E @ G
|
|
|
|
dx, k = Datumsfestlegung.berechne_dx_geraendert(N, n, Gi)
|
|
|
|
else:
|
|
raise ValueError(f"Unbekannte Datumsfestlegung: {datumfestlegung}")
|
|
|
|
# 4) Residuen
|
|
v = dl - A @ dx
|
|
|
|
# 5) Kofaktormatrix der Unbekannten
|
|
Q_xx = StochastischesModell.berechne_Q_xx(N)
|
|
|
|
# 6) Kofaktormatrix der Beobachtungen
|
|
Q_ll_dach = StochastischesModell.berechne_Q_ll_dach(A, Q_xx)
|
|
|
|
# 7) Kofaktormatrix der Verbesserungen
|
|
Q_vv = StochastischesModell.berechne_Qvv(Q_ll, Q_ll_dach)
|
|
|
|
dict_ausgleichung = {
|
|
"dx": dx,
|
|
"v": v,
|
|
"P": P,
|
|
"N": N,
|
|
"Q_xx": Q_xx,
|
|
"Q_ll_dach": Q_ll_dach,
|
|
"Q_vv": Q_vv,
|
|
"Q_ll": Q_ll,
|
|
}
|
|
|
|
return dict_ausgleichung, dx
|
|
|
|
|
|
def ausgleichung_spurminimierung(A, dl, Q_ll, *, datumfestlegung, x0, unbekannten_liste, datenbank=None, mit_massstab=True):
|
|
"""
|
|
Freie Ausgleichung mit Gesamtspur- oder Teilspurminimierung.
|
|
Rückgabe-Layout wie ausgleichung_global.
|
|
"""
|
|
A = np.asarray(A, float)
|
|
dl = np.asarray(dl, float).reshape(-1, 1)
|
|
Q_ll = np.asarray(Q_ll, float)
|
|
|
|
# 1) Gewichtsmatrix P
|
|
P = StochastischesModell.berechne_P(Q_ll)
|
|
|
|
# 2) Normalgleichungen
|
|
N = A.T @ P @ A
|
|
n = A.T @ P @ dl
|
|
|
|
# 3) G über ALLE Punkte aus unbekannten_liste (automatisch)
|
|
G = Datumsfestlegung.build_G_from_names(
|
|
x0=x0,
|
|
unbekannten_liste=unbekannten_liste,
|
|
liste_punktnummern=None, # <- wichtig: auto
|
|
mit_massstab=mit_massstab
|
|
)
|
|
|
|
# 4) Gesamtspur / Teilspur
|
|
if datumfestlegung == "gesamtspur":
|
|
Gi = G
|
|
k = None # wird unten überschrieben
|
|
|
|
elif datumfestlegung == "teilspur":
|
|
if datenbank is None:
|
|
raise ValueError("teilspur benötigt datenbank mit get_datumskoordinate()")
|
|
liste_datumskoordinaten = datenbank.get_datumskoordinate()
|
|
if not liste_datumskoordinaten:
|
|
raise ValueError("Teilspur gewählt, aber keine Datumskoordinaten in der DB gesetzt.")
|
|
|
|
# ["X10034","Y10034"] -> [("10034","X"),("10034","Y")]
|
|
auswahl = [(s[1:], s[0]) for s in liste_datumskoordinaten]
|
|
aktive = Datumsfestlegung.aktive_indices_from_selection(auswahl, unbekannten_liste)
|
|
|
|
E = Datumsfestlegung.auswahlmatrix_E(N.shape[0], aktive)
|
|
Gi = E @ G
|
|
|
|
else:
|
|
raise ValueError("datumfestlegung muss 'gesamtspur' oder 'teilspur' sein")
|
|
|
|
# 5) Lösung per Ränderung + korrektes Q_xx
|
|
dx, k, Q_xx = Datumsfestlegung.loese_geraendert_mit_Qxx(N, n, Gi)
|
|
|
|
# 6) Residuen (wie bei dir)
|
|
v = A @ dx - dl
|
|
|
|
# 7) Kofaktormatrix der Beobachtungen
|
|
Q_ll_dach = StochastischesModell.berechne_Q_ll_dach(A, Q_xx)
|
|
|
|
# 8) Kofaktormatrix der Verbesserungen
|
|
Q_vv = StochastischesModell.berechne_Qvv(Q_ll, Q_ll_dach)
|
|
|
|
dict_ausgleichung = {
|
|
"dx": dx,
|
|
"v": v,
|
|
"P": P,
|
|
"N": N,
|
|
"n": n,
|
|
"k": k,
|
|
"Q_xx": Q_xx,
|
|
"Q_ll_dach": Q_ll_dach,
|
|
"Q_vv": Q_vv,
|
|
"Q_ll": Q_ll,
|
|
"datumfestlegung": datumfestlegung,
|
|
}
|
|
return dict_ausgleichung, dx
|
|
|