forked from lamont-granquist/distlink-cpp
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtests.cpp
More file actions
118 lines (103 loc) · 4.89 KB
/
Copy pathtests.cpp
File metadata and controls
118 lines (103 loc) · 4.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include "distlink.h"
#include <cmath>
#include <iostream>
#include <limits>
#include <string_view>
namespace {
int failures = 0;
void check(bool condition, std::string_view message)
{
if (!condition) {
std::cerr << "FAILED: " << message << '\n';
++failures;
}
}
template<typename Function>
void check_invalid_argument(Function&& function, std::string_view message)
{
try {
function();
check(false, message);
} catch (const std::invalid_argument&) {
check(true, message);
}
}
bool same_result(const SMOIDResult<double>& first, const SMOIDResult<double>& second)
{
return first.good == second.good &&
first.distance == second.distance &&
first.distance_error == second.distance_error &&
first.u1 == second.u1 && first.u1_error == second.u1_error &&
first.u2 == second.u2 && first.u2_error == second.u2_error &&
first.root_count == second.root_count &&
first.min_delta == second.min_delta &&
first.iter_count == second.iter_count &&
first.iter_count_2D == second.iter_count_2D;
}
} // namespace
int main()
{
const SMOIDResult<double> default_moid;
const SLCResult<double> default_linking;
check(std::isnan(default_moid.u1), "default u1 is initialized to NaN");
check(std::isnan(default_moid.u2), "default u2 is initialized to NaN");
check(default_moid.u2_error == 0.0, "default u2 error is initialized");
check(default_linking.lmod == 0.0, "default modified linking coefficient is initialized");
const COrbitData<double> ellipse(-2.0, 0.2, 0.3, 0.4, 0.5);
const COrbitData<double> hyperbola(2.0, 1.2, 0.3, 0.4, 0.5);
check(ellipse.get_a() == 2.0, "elliptic semimajor axis is canonicalized positive");
check(hyperbola.get_a() == -2.0, "hyperbolic semimajor axis is canonicalized negative");
const COrbitData<long double> converted(ellipse);
check(converted.get_a() == static_cast<long double>(ellipse.get_a()) &&
converted.get_e() == static_cast<long double>(ellipse.get_e()),
"cross-precision orbit constructor links and preserves elements");
check_invalid_argument(
[] { (void)COrbitData<double>(1.0, -0.1, 0.2, 0.3, 0.4); },
"negative eccentricity is rejected");
check_invalid_argument(
[] { (void)COrbitData<double>(1.0, 1.0, 0.2, 0.3, 0.4); },
"parabolic eccentricity is rejected");
check_invalid_argument(
[] { (void)COrbitData<double>(0.0, 0.1, 0.2, 0.3, 0.4); },
"zero semimajor axis is rejected");
check_invalid_argument(
[] { (void)COrbitData<double>(1.0, 0.1, std::numeric_limits<double>::infinity(), 0.3, 0.4); },
"nonfinite elements are rejected");
const COrbitData<double> coplanar1(1.0, 0.1, 0.2, 0.3, 0.4);
const COrbitData<double> coplanar2(1.1, 0.15, 0.2, 0.31, 0.4);
const auto linking = LC(coplanar1, coplanar2, 0.0);
check(std::isfinite(linking.l), "coplanar linking coefficient is finite");
check(linking.lmod == 0.0, "coplanar third-coefficient branch marks lmod not computed");
double max_root_error, min_root_error;
double max_anom_error;
detect_suitable_options(max_root_error, min_root_error, max_anom_error);
const COrbitData<double> circle1(1.0, 0.0, 0.0, 0.0, 0.0);
const COrbitData<double> circle2(1.5, 0.0, 0.7, 0.4, 1.2);
const auto circular = MOID_fast(circle1, circle2, max_root_error, min_root_error);
check(circular.good, "two-circle fast result is reliable");
check(std::fabs(circular.distance - 0.5) < 1.0e-15,
"two-circle exact distance is the radius difference");
const COrbitData<double> asteroid(1.4583, 0.2226, 0.058, 2.2, 3.56);
const auto repeat1 = MOID_fast(circle1, asteroid, max_root_error, min_root_error);
const auto repeat2 = MOID_fast(circle1, asteroid, max_root_error, min_root_error);
check(same_result(repeat1, repeat2), "fast MOID is exactly repeatable within one process");
check_invalid_argument(
[&] { (void)LC(coplanar1, coplanar2, -1.0); },
"negative linking threshold is rejected");
check_invalid_argument(
[&] { (void)MOID_fast(coplanar1, coplanar2, 0.0, min_root_error); },
"nonpositive maximum root error is rejected");
check_invalid_argument(
[&] { (void)MOID_direct_search(coplanar1, coplanar2, nullptr, 1.0e-10, 0.0); },
"nonpositive direct-search anomaly error is rejected");
const COrbitData<double> coplanar_hyperbola1(-2.0, 1.4, 0.4, 0.2, 0.8);
const COrbitData<double> coplanar_hyperbola2(-3.0, 1.8, 0.4, 1.1, 0.8);
check_invalid_argument(
[&] {
(void)MOID_direct_search(
coplanar_hyperbola1, coplanar_hyperbola2, nullptr, 1.0e-10, max_anom_error);
},
"unbounded coplanar hyperbolic direct search is rejected");
if (failures == 0) std::cout << "All distlink C++ tests passed\n";
return failures == 0 ? 0 : 1;
}