Line | Branch | Exec | Source |
---|---|---|---|
1 | // This file is part of INSTINCT, the INS Toolkit for Integrated | ||
2 | // Navigation Concepts and Training by the Institute of Navigation of | ||
3 | // the University of Stuttgart, Germany. | ||
4 | // | ||
5 | // This Source Code Form is subject to the terms of the Mozilla Public | ||
6 | // License, v. 2.0. If a copy of the MPL was not distributed with this | ||
7 | // file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
8 | |||
9 | #include "AssociatedLegendre.hpp" | ||
10 | #include "util/Logger.hpp" | ||
11 | |||
12 | #include "Navigation/Constants.hpp" | ||
13 | #include <cmath> | ||
14 | #include <array> | ||
15 | #include <numbers> | ||
16 | |||
17 | 181318 | std::pair<Eigen::MatrixXd, Eigen::MatrixXd> NAV::internal::associatedLegendre(double theta, size_t ndegree) | |
18 | { | ||
19 | // Index needed for the calculation of all necessary 'Pd' entries up to 'ndegree' (--> Pd(n = ndegree, m = ndegree) is dependent on P(n = ndegree, m = ndegree + 1)) | ||
20 | 181318 | int N = static_cast<int>(ndegree + 2); | |
21 | |||
22 |
2/4✓ Branch 1 taken 181317 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 181319 times.
✗ Branch 5 not taken.
|
181318 | Eigen::MatrixXd P = Eigen::MatrixXd::Zero(N, N); |
23 |
2/4✓ Branch 1 taken 181322 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 181323 times.
✗ Branch 5 not taken.
|
181319 | Eigen::MatrixXd Pd = Eigen::MatrixXd::Zero(N, N); |
24 | |||
25 | #if defined(__GNUC__) || defined(__clang__) | ||
26 | #pragma GCC diagnostic push | ||
27 | #pragma GCC diagnostic ignored "-Wnull-dereference" | ||
28 | #endif | ||
29 | // Recurrence relations for the normalized associated Legendre functions (see 'GUT User Guide' eq. 4.2.2 and eq. 4.2.3) | ||
30 |
1/2✓ Branch 1 taken 181320 times.
✗ Branch 2 not taken.
|
181323 | P(0, 0) = 1.0; |
31 |
1/2✓ Branch 1 taken 181323 times.
✗ Branch 2 not taken.
|
181320 | P(1, 0) = std::numbers::sqrt3 * std::cos(theta); |
32 |
1/2✓ Branch 1 taken 181323 times.
✗ Branch 2 not taken.
|
181323 | P(1, 1) = std::numbers::sqrt3 * std::sin(theta); |
33 | #if defined(__GNUC__) || defined(__clang__) | ||
34 | #pragma GCC diagnostic pop | ||
35 | #endif | ||
36 | |||
37 |
2/2✓ Branch 0 taken 1813185 times.
✓ Branch 1 taken 181196 times.
|
1994381 | for (int n = 2; n <= N - 1; n++) |
38 | { | ||
39 | 1813185 | auto nd = static_cast<double>(n); | |
40 |
2/4✓ Branch 1 taken 1813185 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1813176 times.
✗ Branch 5 not taken.
|
1813185 | P(n, n) = std::sqrt((2.0 * nd + 1.0) / (2.0 * nd)) * std::sin(theta) * P(n - 1, n - 1); |
41 | |||
42 |
2/2✓ Branch 0 taken 13596909 times.
✓ Branch 1 taken 1813058 times.
|
15409967 | for (int m = 0; m <= n; m++) |
43 | { | ||
44 | 13596909 | auto md = static_cast<double>(m); | |
45 | |||
46 |
2/2✓ Branch 0 taken 1813177 times.
✓ Branch 1 taken 11783732 times.
|
13596909 | if (n == m + 1) |
47 | { | ||
48 |
2/4✓ Branch 1 taken 1813183 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1813179 times.
✗ Branch 5 not taken.
|
1813177 | P(n, m) = std::sqrt(((2.0 * nd + 1.0) * (2.0 * nd - 1.0)) / ((nd + md) * (nd - md))) * std::cos(theta) * P(n - 1, m); |
49 | } | ||
50 |
2/2✓ Branch 0 taken 9971144 times.
✓ Branch 1 taken 1812588 times.
|
11783732 | else if (n > m + 1) |
51 | { | ||
52 |
1/2✓ Branch 1 taken 9970968 times.
✗ Branch 2 not taken.
|
19942168 | P(n, m) = std::sqrt(((2.0 * nd + 1.0) * (2.0 * nd - 1.0)) / ((nd + md) * (nd - md))) * std::cos(theta) * P(n - 1, m) |
53 |
2/4✓ Branch 1 taken 9971193 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9971024 times.
✗ Branch 5 not taken.
|
9970968 | - std::sqrt(((2.0 * nd + 1.0) * (nd + md - 1.0) * (nd - md - 1.0)) / ((2.0 * nd - 3.0) * (nd + md) * (nd - md))) * std::cos(theta) * P(n - 2, m); |
54 | } | ||
55 | } | ||
56 | } | ||
57 | |||
58 | // Recurrence relations for the derivative of the normalized associated Legendre functions (see 'GUT User Guide' eq. 4.2.6) | ||
59 |
1/2✓ Branch 1 taken 181323 times.
✗ Branch 2 not taken.
|
181196 | Pd(0, 0) = 0.0; |
60 |
1/2✓ Branch 1 taken 181323 times.
✗ Branch 2 not taken.
|
181323 | Pd(1, 0) = -std::numbers::sqrt3 * std::sin(theta); |
61 |
1/2✓ Branch 1 taken 181323 times.
✗ Branch 2 not taken.
|
181323 | Pd(1, 1) = std::numbers::sqrt3 * std::cos(theta); |
62 | |||
63 |
2/2✓ Branch 0 taken 1813177 times.
✓ Branch 1 taken 181253 times.
|
1994430 | for (int n = 2; n <= N - 1; n++) // 2nd for-loop is necessary, because for the calculation of 'Pd', all coefficients of 'P' must be available |
64 | { | ||
65 | 1813177 | auto nd = static_cast<double>(n); | |
66 | |||
67 |
2/4✓ Branch 1 taken 1813174 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1813187 times.
✗ Branch 5 not taken.
|
1813177 | Pd(n, 0) = -0.5 * std::sqrt(2.0 * nd * (nd + 1.0)) * P(n, 1); |
68 |
3/6✓ Branch 1 taken 1813179 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1813170 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1813180 times.
✗ Branch 8 not taken.
|
1813187 | Pd(n, 1) = 0.5 * (std::sqrt(2.0 * nd * (nd + 1.0)) * P(n, 0) - std::sqrt((nd - 1.0) * (nd + 2.0)) * std::pow(P(n, 2), 2.0)); |
69 | |||
70 |
2/2✓ Branch 0 taken 8158598 times.
✓ Branch 1 taken 1813107 times.
|
9971705 | for (int m = 2; m <= n - 1; m++) |
71 | { | ||
72 | 8158598 | auto md = static_cast<double>(m); | |
73 | |||
74 | // else if ((m > 1) && (m < N - 1)) | ||
75 |
3/6✓ Branch 1 taken 8158545 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8158620 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 8158525 times.
✗ Branch 8 not taken.
|
8158598 | Pd(n, m) = 0.5 * (std::sqrt((nd + md) * (nd - md + 1.0)) * P(n, m - 1) - std::sqrt((nd - md) * (nd + md + 1.0)) * P(n, m + 1)); |
76 | } | ||
77 | } | ||
78 | |||
79 |
1/2✓ Branch 1 taken 181322 times.
✗ Branch 2 not taken.
|
362575 | return std::make_pair(P, Pd); |
80 | 181322 | } | |
81 |