diff --git a/Ausgleichungsprogramm.ipynb b/Ausgleichungsprogramm.ipynb index 337955a..93f04ec 100644 --- a/Ausgleichungsprogramm.ipynb +++ b/Ausgleichungsprogramm.ipynb @@ -5,8 +5,8 @@ "id": "2bc687b1b4adb7bd", "metadata": { "ExecuteTime": { - "end_time": "2026-02-05T12:24:09.512813Z", - "start_time": "2026-02-05T12:24:07.910581Z" + "end_time": "2026-02-05T14:00:31.786023Z", + "start_time": "2026-02-05T14:00:29.848681Z" } }, "source": [ @@ -39,8 +39,8 @@ "id": "4f7efd7ba6ec18f9", "metadata": { "ExecuteTime": { - "end_time": "2026-02-05T12:24:09.522346Z", - "start_time": "2026-02-05T12:24:09.520187Z" + "end_time": "2026-02-05T14:00:31.793259Z", + "start_time": "2026-02-05T14:00:31.788027Z" } }, "source": [ @@ -70,8 +70,8 @@ "id": "57fcd841405b7866", "metadata": { "ExecuteTime": { - "end_time": "2026-02-05T12:24:09.763148Z", - "start_time": "2026-02-05T12:24:09.708149Z" + "end_time": "2026-02-05T14:00:31.938578Z", + "start_time": "2026-02-05T14:00:31.798396Z" } }, "source": [ @@ -94,8 +94,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2026-02-05T12:24:10.248982Z", - "start_time": "2026-02-05T12:24:10.242901Z" + "end_time": "2026-02-05T14:00:32.562111Z", + "start_time": "2026-02-05T14:00:32.496934Z" } }, "cell_type": "code", @@ -107,11 +107,51 @@ "id": "2cf681b8ca7f268", "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Es wurden noch keine Instrumente angelegt. Bitte in der folgenden Zelle nachholen und diese Zelle erneut ausführen!\n" - ] + "data": { + "text/plain": [ + "" + ], + "text/html": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
InstrumenteIDTypBezeichnung
1TachymeterTrimble S9
2AnschlusspunktelA
3NivellierTrimble DiNi 0.3
4GNSSGNSS-Rover
\n" + ] + }, + "metadata": {}, + "output_type": "display_data", + "jetTransient": { + "display_id": null + } } ], "execution_count": 4 @@ -119,8 +159,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2026-02-05T12:24:10.710361Z", - "start_time": "2026-02-05T12:24:10.684088Z" + "end_time": "2026-02-05T14:00:39.124168Z", + "start_time": "2026-02-05T14:00:39.112708Z" } }, "cell_type": "code", @@ -148,9 +188,9 @@ "name": "stdout", "output_type": "stream", "text": [ - "Das Instrument Trimble S9 wurde erfolgreich hinzugefügt.\n", - "Das Instrument Trimble DiNi 0.3 wurde erfolgreich hinzugefügt.\n", - "Das Instrument GNSS-Rover wurde erfolgreich hinzugefügt.\n" + "Das Instrument Trimble S9 ist bereits in der Datenbank vorhanden.\n", + "Das Instrument Trimble DiNi 0.3 ist bereits in der Datenbank vorhanden.\n", + "Das Instrument GNSS-Rover ist bereits in der Datenbank vorhanden.\n" ] } ], @@ -159,8 +199,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2026-02-05T12:24:11.161918Z", - "start_time": "2026-02-05T12:24:11.156510Z" + "end_time": "2026-02-05T14:00:39.720324Z", + "start_time": "2026-02-05T14:00:39.713477Z" } }, "cell_type": "code", @@ -172,11 +212,56 @@ "id": "3a90f746c44a1ebb", "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Es wurden noch keine apriori Genauigkeiten zu den Beobachtungsgruppen erfasst. Bitte in der folgenden Zelle nachholen und diese Zelle erneut ausführen.\n" - ] + "data": { + "text/plain": [ + "" + ], + "text/html": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
instrumenteIDbeobachtungsartstabw_apriori_konstantstabw_apriori_streckenprop
1Tachymeter_Richtung0.000002nan
1Tachymeter_Strecke0.0008001.000000
1Tachymeter_Zenitwinkel0.000002nan
3Geometrisches_Nivellement0.0001000.300000
\n" + ] + }, + "metadata": {}, + "output_type": "display_data", + "jetTransient": { + "display_id": null + } } ], "execution_count": 6 @@ -184,8 +269,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2026-02-05T12:24:11.784546Z", - "start_time": "2026-02-05T12:24:11.763928Z" + "end_time": "2026-02-05T14:00:40.399822Z", + "start_time": "2026-02-05T14:00:40.386179Z" } }, "cell_type": "code", @@ -215,10 +300,10 @@ "name": "stdout", "output_type": "stream", "text": [ - "Die Genauigkeitsangabe für Tachymeter_Richtung (Instrument: Trimble S9) wurde erfolgreich hinzugefügt.\n", - "Die Genauigkeitsangabe für Tachymeter_Strecke (Instrument: Trimble S9) wurde erfolgreich hinzugefügt.\n", - "Die Genauigkeitsangabe für Tachymeter_Zenitwinkel (Instrument: Trimble S9) wurde erfolgreich hinzugefügt.\n", - "Die Genauigkeitsangabe für Geometrisches_Nivellement (Instrument: Trimble DiNi 0.3) wurde erfolgreich hinzugefügt.\n" + "Die Genauigkeitsangabe für Tachymeter_Richtung (Instrument: Trimble S9) wurde aktualisiert.\n", + "Die Genauigkeitsangabe für Tachymeter_Strecke (Instrument: Trimble S9) wurde aktualisiert.\n", + "Die Genauigkeitsangabe für Tachymeter_Zenitwinkel (Instrument: Trimble S9) wurde aktualisiert.\n", + "Die Genauigkeitsangabe für Geometrisches_Nivellement (Instrument: Trimble DiNi 0.3) wurde aktualisiert.\n" ] } ], @@ -229,8 +314,8 @@ "id": "b28afe0c64aa59d6", "metadata": { "ExecuteTime": { - "end_time": "2026-02-05T12:24:12.490480Z", - "start_time": "2026-02-05T12:24:12.356523Z" + "end_time": "2026-02-05T14:00:41.093891Z", + "start_time": "2026-02-05T14:00:40.992896Z" } }, "source": [ @@ -262,10 +347,10 @@ "name": "stdout", "output_type": "stream", "text": [ - "Der Import der Näherungskoordinaten wurde erfolgreich abgeschlossen\n", + "Der Import wurde abgebrochen, weil mindestens ein Teil der Punktnummern aus der Datei Daten\\campsnetz_koordinaten_plus_nachmessungen.csv bereits in der Datenbank vorhanden ist. Bitte in der Datei ändern und Import wiederholen.\n", "Korrektur erfolgreich abgeschlossen. Ausgabe: Daten\\campsnetz_beobachtungen_plus_nachmessungen_korrigiert.csv\n", "Ersetzungen in der CSV-Datei (Rundung -> JXL volle Nachkommastellen): {'Hz': 1639, 'Z': 1838, 'SD': 747}\n", - "Der Import der Datei Daten\\campsnetz_beobachtungen_plus_nachmessungen_korrigiert.csv wurde erfolgreich abgeschlossen.\n" + "Der Import wurde abgebrochen, weil die Beobachtungen aus der Datei Daten\\campsnetz_beobachtungen_plus_nachmessungen_korrigiert.csv bereits in der Datenbank vorhanden sind.\n" ] } ], @@ -274,8 +359,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2026-02-05T12:24:12.916365Z", - "start_time": "2026-02-05T12:24:12.899749Z" + "end_time": "2026-02-05T14:00:41.667677Z", + "start_time": "2026-02-05T14:00:41.657349Z" } }, "cell_type": "code", @@ -305,7 +390,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Der Import der Datei Daten\\Basislinien_ohne0648und10002.asc.txt wurde erfolgreich abgeschlossen.\n" + "Der Import wurde abgebrochen, weil die Beobachtungen aus der Datei Daten\\Basislinien_ohne0648und10002.asc.txt bereits in der Datenbank vorhanden sind.\n" ] } ], @@ -316,8 +401,8 @@ "id": "2d8a0533726304a8", "metadata": { "ExecuteTime": { - "end_time": "2026-02-05T12:24:14.974452Z", - "start_time": "2026-02-05T12:24:13.540713Z" + "end_time": "2026-02-05T14:00:51.315237Z", + "start_time": "2026-02-05T14:00:42.322654Z" } }, "source": [ @@ -337,28 +422,86 @@ "name": "stdout", "output_type": "stream", "text": [ - "Anzahl verwendete Punkte für die Helmerttransformation: 9\n", + "Anzahl verwendete Punkte für die Helmerttransformation: 68\n", "Iteration Nr.1 abgeschlossen\n", "Iteration Nr.2 abgeschlossen\n", "Iteration Nr.3 abgeschlossen\n", "Iteration Nr.4 abgeschlossen\n", "Iteration Nr.5 abgeschlossen\n", - "Iteration Nr.6 abgeschlossen\n", "Koordinaten berechnet aus Helmerttransformation:\n", "10001: 3794901.521, 546745.584, 5080065.755\n", + "10002: 3794867.011, 546729.617, 5080092.695\n", + "10003: 3794841.061, 546735.120, 5080111.557\n", + "10004: 3794803.469, 546714.145, 5080141.394\n", + "10005: 3794793.850, 546722.325, 5080147.942\n", + "10006: 3794766.364, 546707.643, 5080169.743\n", + "10007: 3794831.055, 546758.730, 5080116.675\n", "10008: 3794783.870, 546746.646, 5080152.758\n", + "10009: 3794767.479, 546740.091, 5080165.961\n", + "10010: 3794758.643, 546767.670, 5080169.471\n", + "10011: 3794894.930, 546833.119, 5080061.164\n", + "10012: 3794853.608, 546805.240, 5080094.900\n", + "10013: 3794849.615, 546826.872, 5080095.440\n", "10014: 3794838.746, 546812.367, 5080105.181\n", + "10015: 3794839.472, 546793.520, 5080106.782\n", + "10016: 3794826.666, 546788.731, 5080116.878\n", + "10017: 3794825.022, 546831.703, 5080113.383\n", + "10018: 3794762.253, 546797.694, 5080163.986\n", + "10019: 3794800.100, 546833.327, 5080131.731\n", + "10020: 3794782.615, 546834.473, 5080145.041\n", + "10021: 3794776.034, 546833.743, 5080150.018\n", + "10022: 3794778.341, 546841.753, 5080147.280\n", + "10023: 3794780.799, 546848.104, 5080144.929\n", + "10024: 3794772.819, 546857.098, 5080149.838\n", + "10025: 3794774.211, 546871.813, 5080147.362\n", "10026: 3794753.858, 546827.445, 5080167.092\n", + "10027: 3794757.593, 546874.333, 5080159.319\n", "10028: 3794889.671, 546908.764, 5080056.920\n", + "10029: 3794845.029, 546914.918, 5080089.105\n", + "10030: 3794845.357, 546901.029, 5080090.362\n", + "10031: 3794821.763, 546877.550, 5080110.752\n", + "10032: 3794807.851, 546888.488, 5080119.750\n", + "10033: 3794800.019, 546874.654, 5080127.209\n", + "10034: 3794886.107, 546965.700, 5080053.411\n", + "10035: 3794845.950, 546961.514, 5080084.091\n", + "10036: 3794815.055, 546969.597, 5080106.065\n", "10037: 3794800.626, 546960.749, 5080117.709\n", + "10038: 3794806.325, 546929.732, 5080116.901\n", + "10039: 3794804.164, 546914.733, 5080120.142\n", + "10040: 3794780.721, 546956.425, 5080133.161\n", + "10041: 3794778.154, 546925.879, 5080138.723\n", + "10042: 3794758.957, 546937.061, 5080151.609\n", + "10043: 3794747.274, 546919.151, 5080162.149\n", "10044: 3794752.686, 546958.324, 5080154.237\n", + "10045: 3794881.901, 547019.784, 5080050.718\n", + "10046: 3794846.580, 547012.997, 5080077.441\n", + "10047: 3794831.534, 547018.239, 5080088.124\n", + "10048: 3794809.105, 547017.302, 5080105.013\n", + "10049: 3794786.888, 547021.076, 5080121.441\n", + "10050: 3794766.769, 547012.526, 5080137.481\n", + "10051: 3794767.056, 546988.699, 5080139.995\n", + "10052: 3794743.624, 546984.416, 5080157.827\n", + "10053: 3794748.143, 547017.574, 5080150.924\n", "10054: 3794889.163, 547086.949, 5080038.116\n", + "10055: 3794838.849, 547081.903, 5080075.695\n", + "10056: 3794825.037, 547094.810, 5080084.484\n", + "10057: 3794800.815, 547078.670, 5080104.567\n", + "10058: 3794766.103, 547091.752, 5080129.113\n", "10059: 3794736.830, 547079.447, 5080152.362\n", + "666: 3794868.128, 547082.279, 5080054.295\n", + "812: 3794850.535, 547010.934, 5080075.089\n", + "816: 3794817.790, 547004.825, 5080100.040\n", + "FH11: 3794853.321, 546973.225, 5080077.224\n", + "FH13: 3794832.559, 546754.704, 5080116.651\n", + "FH14: 3794853.863, 546972.809, 5080076.935\n", + "FH15: 3794794.213, 546870.696, 5080132.914\n", + "FH3: 3794810.977, 547013.441, 5080105.068\n", + "FH4: 3794773.597, 546985.341, 5080135.930\n", "Streckendifferenzen zwischen Näherungskoordinate aus statischer GNSS-Messung und ergebnis der Helmerttransformation:\n", - "[0.027793, 0.025879, 0.016527, 0.01604, 0.066139, 0.07164, 0.025138, 0.125881, 0.142477]\n", + "[0.027793, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.025879, 0.0, 0.0, 0.0, 0.0, 0.0, 0.016527, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.01604, 0.0, 0.066139, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.07164, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.025138, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.125881, 0.0, 0.0, 0.0, 0.0, 0.142477, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]\n", "\n", "Differenz Schwerpunkt zwischen Näherungskoordinate aus statischer GNSS-Messung und ergebnis der Helmerttransformation::\n", - "Matrix([[3.10e-10], [1.16e-10], [1.03e-10]])\n", + "Matrix([[-2.59e-10], [6.85e-12], [-2.32e-10]])\n", "Betrag der Schwerpunkt-Differenz zwischen Näherungskoordinate aus statischer GNSS-Messung und ergebnis der Helmerttransformation::\n", "0.000m\n" ] @@ -371,8 +514,8 @@ "id": "ed9be38e35cfc619", "metadata": { "ExecuteTime": { - "end_time": "2026-02-05T12:24:15.067892Z", - "start_time": "2026-02-05T12:24:15.058891Z" + "end_time": "2026-02-05T14:00:51.354852Z", + "start_time": "2026-02-05T14:00:51.347388Z" } }, "source": [ @@ -402,8 +545,8 @@ "id": "2d2156381d974d94", "metadata": { "ExecuteTime": { - "end_time": "2026-02-05T12:24:15.151220Z", - "start_time": "2026-02-05T12:24:15.146192Z" + "end_time": "2026-02-05T14:00:51.361580Z", + "start_time": "2026-02-05T14:00:51.354852Z" } }, "source": [ @@ -433,8 +576,8 @@ "id": "c2db29680c53f8c4", "metadata": { "ExecuteTime": { - "end_time": "2026-02-05T12:24:15.928494Z", - "start_time": "2026-02-05T12:24:15.908077Z" + "end_time": "2026-02-05T14:00:51.372347Z", + "start_time": "2026-02-05T14:00:51.364107Z" } }, "source": [ @@ -456,19 +599,9 @@ "name": "stdout", "output_type": "stream", "text": [ - "Folgende Stand- und Zielpunkte des geometrischen Nivellements werden für die Beobachtungsgruppe ausgeglichen: ['812', '10047', '10046', '10045', '10034', 'FH14', 'FH11', '10035', '10029', '10030', '10031', '10017', '10013', '10012', '10014', '10015', '10016', '10007', 'FH13', '666', '10054', '10056', '10058', '10052', '10043', '10026', '10010', '10006', '816', '10048', 'FH3', '10049', '10053', '10050', '10051', 'FH4', '10040', '10037', '10038', '10039', '10032', 'FH15', '10033', '10025', '10024', '10023', '10022', '10021', '10020', '10019', '10036', '10028', '10011', '10001', '10003', '10008', '10005', '10004', '10002', '10055', '10057', '10059', '10044', '10041', '10042', '10027', '10018', '10009']\n", - "Für folgende Punkte wird aktuell keine Höhe in der Ausgleichung berechnet: ['80001', '80002', '90001', '90002', '90003', '90004', '90005', '90006', '90007', '90008', '90009', '90010', '90011', '90012', '90013', '90014', '70001', '70002', '60001', 'FH5', '60002', '60003', '60004', '60005', '60006', '60007', '60008', '60009', '60010', '30001', '30002', '30003', '30004', '30005', '30006', '30007', '30008']. Bei Bedarf im folgenden Schritt ändern!\n" + "Der Import wurde abgebrochen, weil die Beobachtungen aus der Datei Daten\\Niv_bereinigt.DAT.csv bereits in der Datenbank vorhanden sind.\n", + "Der Import wurde abgebrochen, weil die Beobachtungen aus der Datei Daten\\Niv_bereinigt.DAT.csv bereits in der Datenbank vorhanden sind.\n" ] - }, - { - "data": { - "text/plain": [ - "'Die Beobachtungen aus der Datei Daten\\\\Niv_bereinigt.DAT.csv wurden erfolgreich importiert.'" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" } ], "execution_count": 13 @@ -479,7 +612,7 @@ "is_executing": true }, "ExecuteTime": { - "start_time": "2026-02-05T12:24:17.017690Z" + "start_time": "2026-02-05T14:00:51.377686Z" } }, "cell_type": "code", @@ -827,6 +960,14 @@ "id": "23aa13721f563c90", "outputs": [], "execution_count": null + }, + { + "metadata": {}, + "cell_type": "code", + "outputs": [], + "execution_count": null, + "source": "", + "id": "8525da086619229b" } ], "metadata": { diff --git a/Parameterschaetzung.py b/Parameterschaetzung.py index 6d55495..957f498 100644 --- a/Parameterschaetzung.py +++ b/Parameterschaetzung.py @@ -8,123 +8,9 @@ import Datumsfestlegung import numpy as np -def ausgleichung_global(A, dl, Q_ext, P): - """ - Führt eine Ausgleichung nach kleinsten Quadraten durch. - - Aus der Designmatrix A, dem Verbesserungsvektor dl und der Gewichtsmatrix P wird das Normalgleichungssystem - aufgestellt und gelöst. Anschließend werden Residuen sowie Kofaktor-Matrizen der Unbekannten und Beobachtungen berechnet. - - Es werden folgende Berechnungsschitte durchgeführt: - - 1) Normalgleichungsmatrix N = Aᵀ · P · A und Absolutglied n = Aᵀ · P · dl - 2) Lösung dx = N⁻¹ · n - 3) Residuen v = A · dx − dl - 4) Kofaktormatrix der Unbekannten Q_xx - 5) Kofaktormatrix der ausgeglichenen Beobachtungen Q_ll_dach - 6) Kofaktormatrix der Verbesserungen Q_vv - - :param A: Jacobi-Matrix (A-Matrix). - :type A: array_like - :param dl: Verbesserungsvektor bzw. Beobachtungsabweichungen. - :type dl: array_like - :param Q_ext: a-priori Kofaktormatrix der Beobachtungen. - :type Q_ext: array_like - :param P: Gewichtsmatrix der Beobachtungen. - :type P: array_like - :return: Dictionary mit Ausgleichungsergebnissen, Zuschlagsvektor dx. - :rtype: tuple[dict[str, Any], numpy.ndarray] - :raises numpy.linalg.LinAlgError: Wenn das Normalgleichungssystem singulär ist und nicht gelöst werden kann. - """ - 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_lokal(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 - class Iterationen: """Iterative Ausgleichung auf Basis des funktionalen und stochastischen Modells. @@ -167,6 +53,75 @@ class Iterationen: self.fm = Funktionales_Modell.FunktionalesModell(self.pfad_datenbank, self.a, self.b, self.pfad_tif_quasigeoidundolation) + def ausgleichung_global(self, A, dl, Q_ext, P): + """ + Führt eine Ausgleichung nach kleinsten Quadraten durch. + + Aus der Designmatrix A, dem Verbesserungsvektor dl und der Gewichtsmatrix P wird das Normalgleichungssystem + aufgestellt und gelöst. Anschließend werden Residuen sowie Kofaktor-Matrizen der Unbekannten und Beobachtungen berechnet. + + Es werden folgende Berechnungsschitte durchgeführt: + + 1) Normalgleichungsmatrix N = Aᵀ · P · A und Absolutglied n = Aᵀ · P · dl + 2) Lösung dx = N⁻¹ · n + 3) Residuen v = A · dx − dl + 4) Kofaktormatrix der Unbekannten Q_xx + 5) Kofaktormatrix der ausgeglichenen Beobachtungen Q_ll_dach + 6) Kofaktormatrix der Verbesserungen Q_vv + + :param A: Jacobi-Matrix (A-Matrix). + :type A: array_like + :param dl: Verbesserungsvektor bzw. Beobachtungsabweichungen. + :type dl: array_like + :param Q_ext: a-priori Kofaktormatrix der Beobachtungen. + :type Q_ext: array_like + :param P: Gewichtsmatrix der Beobachtungen. + :type P: array_like + :return: Dictionary mit Ausgleichungsergebnissen, Zuschlagsvektor dx. + :rtype: tuple[dict[str, Any], numpy.ndarray] + :raises numpy.linalg.LinAlgError: Wenn das Normalgleichungssystem singulär ist und nicht gelöst werden kann. + """ + 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 iterationen(self, datumfestlegung: str, speichern_in_csv: bool) -> tuple[np.ndarray, list, list, np.ndarray, np.ndarray, np.ndarray, dict]: """Führt die iterative Ausgleichung (Parameterschätzung) aus und gibt die Ergebnisse zurück. @@ -365,7 +320,7 @@ class Iterationen: dl_k = np.asarray(dl_k, float) # Parameterschätzung für die aktuelle Iteration berechnen - ausgabe_parameterschaetzung, dx = Parameterschaetzung.ausgleichung_global(A_matrix_numerisch, dl_k, Q_k, P) + ausgabe_parameterschaetzung, dx = self.ausgleichung_global(A_matrix_numerisch, dl_k, Q_k, P) dx = np.asarray(dx, float).reshape(-1, 1) # Matrizen je Iteration als CSV-Datei speichern