-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathregression_test.cc
93 lines (73 loc) · 2.66 KB
/
regression_test.cc
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
/**
* Moon Position Algorithm (MPA) Regression Tests
*
* Copyright 2023 Joey Parrish <joey.parrish@gmail.com>
*
* Ensures that this ported, stripped-down version of MPA is compatible with
* the original SAMPA implementation from the DoE and NREL.
*/
#include <cinttypes>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include "gtest/gtest.h"
#include "sampa/sampa.h"
#include "mpa/mpa.h"
namespace {
int64_t roll_int(int64_t min, int64_t max) { // inclusive
// NOTE: This is not uniformly distributed, and that's fine for the
// randomized testing we're doing here.
return min + (random() % (max - min + 1));
}
double roll_double(double min, double max) { // inclusive
// NOTE: This is not uniformly distributed, and that's fine for the
// randomized testing we're doing here.
double zero_to_one =
static_cast<double>(random()) / static_cast<double>(RAND_MAX);
return min + ((max - min) * zero_to_one);
}
void compare_algorithms(time_t now, double latitude, double longitude, double elevation) {
sampa::sampa_data old_data;
mpa::mpa_input new_input;
mpa::mpa_output new_output;
memset(&old_data, 0, sizeof(old_data));
memset(&new_input, 0, sizeof(new_input));
memset(&new_output, 0, sizeof(new_output));
// Break out the unix timestamp into fields.
struct tm utc;
gmtime_r(&now, &utc);
// Fill in the data to drive the old algorithm.
old_data.spa.year = 1900 + utc.tm_year;
old_data.spa.month = utc.tm_mon + 1;
old_data.spa.day = utc.tm_mday;
old_data.spa.hour = utc.tm_hour;
old_data.spa.minute = utc.tm_min;
old_data.spa.second = utc.tm_sec;
old_data.spa.latitude = latitude;
old_data.spa.longitude = longitude;
old_data.spa.elevation = elevation;
// Fill in the data to drive the new algorithm.
set_mpa_time(utc, &new_input);
new_input.latitude = latitude;
new_input.longitude = longitude;
new_input.elevation = elevation;
// If the old one fails, the test data was invalid.
ASSERT_EQ(0, sampa::sampa_calculate(&old_data));
// The new one returns void.
mpa::compute_mpa(new_input, &new_output);
EXPECT_DOUBLE_EQ(old_data.mpa.azimuth, new_output.azimuth) << "Azimuth mismatch";
EXPECT_DOUBLE_EQ(old_data.mpa.zenith, new_output.zenith) << "Zenith mismatch";
}
} // namespace
TEST(PositionAlgorithm, RandomInputs) {
for (int i = 0; i < 1000; ++i) {
// 2023 - 2083.
time_t now = roll_int(1672552800LL, 3597544799LL);
// Anywhere on earth.
double latitude = roll_double(-90.0, 90.0);
double longitude = roll_double(-180.0, 180.0);
// From the Dead Sea to Everest.
double elevation = roll_double(-420.0, 8849.0);
compare_algorithms(now, latitude, longitude, elevation);
}
}