@@ -7,9 +7,17 @@ namespace {
7
7
8
8
using OO = ApproximationPrecision::OptimizationObjective;
9
9
10
+ // clang-format off
10
11
// Generate this table with:
11
12
// python3 src/polynomial_optimizer.py atan --order 1 2 3 4 5 6 7 8 --loss mse mae mulpe mulpe_mae --no-gui --format table
12
- std::vector<Approximation> table_atan = {
13
+ //
14
+ // Note that the maximal errors are computed with numpy with double precision.
15
+ // The real errors are a bit larger with single-precision floats (see correctness/fast_arctan.cpp).
16
+ // Also note that ULP distances which are not units are bogus, but this is because this error
17
+ // was again measured with double precision, so the actual reconstruction had more bits of
18
+ // precision than the actual float32 target value. So in practice the MaxULP Error
19
+ // will be close to round(MaxUlpE).
20
+ const std::vector<Approximation> table_atan = {
13
21
{OO::MSE, 9.249650e-04 , 7.078984e-02 , 2.411e+06 , {+8.56188008e-01 }},
14
22
{OO::MSE, 1.026356e-05 , 9.214909e-03 , 3.985e+05 , {+9.76213454e-01 , -2.00030200e-01 }},
15
23
{OO::MSE, 1.577588e-07 , 1.323851e-03 , 6.724e+04 , {+9.95982073e-01 , -2.92278128e-01 , +8.30180680e-02 }},
@@ -46,21 +54,28 @@ std::vector<Approximation> table_atan = {
46
54
{OO::MULPE_MAE, 3.053218e-14 , 3.784868e-07 , 4.181e+01 , {+9.99997480e-01 , -3.33205127e-01 , +1.98309644e-01 , -1.33094430e-01 , +8.08643094e-02 , -3.45859503e-02 , +7.11261604e-03 }},
47
55
{OO::MULPE_MAE, 7.018877e-16 , 5.862915e-08 , 6.942e+00 , {+9.99999581e-01 , -3.33306326e-01 , +1.99542180e-01 , -1.39433369e-01 , +9.72462857e-02 , -5.69734398e-02 , +2.25639390e-02 , -4.24074590e-03 }},
48
56
};
57
+ // clang-format on
49
58
} // namespace
50
59
51
- const Approximation *find_best_approximation (const std::vector<Approximation> &table, ApproximationPrecision precision) {
60
+ const Approximation *find_best_approximation (const std::vector<Approximation> &table,
61
+ ApproximationPrecision precision) {
62
+ #define DEBUG_APPROXIMATION_SEARCH 0
52
63
const Approximation *best = nullptr ;
53
64
constexpr int term_cost = 20 ;
54
65
constexpr int extra_term_cost = 200 ;
55
66
double best_score = 0 ;
56
- // std::printf("Looking for min_terms=%d, max_absolute_error=%f\n", precision.constraint_min_poly_terms, precision.constraint_max_absolute_error);
67
+ #if DEBUG_APPROXIMATION_SEARCH
68
+ std::printf (" Looking for min_terms=%d, max_absolute_error=%f\n " ,
69
+ precision.constraint_min_poly_terms , precision.constraint_max_absolute_error );
70
+ #endif
57
71
for (size_t i = 0 ; i < table.size (); ++i) {
58
72
const Approximation &e = table[i];
59
73
60
74
double penalty = 0.0 ;
61
75
62
76
int obj_score = e.objective == precision.optimized_for ? 100 * term_cost : 0 ;
63
- if (precision.optimized_for == ApproximationPrecision::MULPE_MAE && e.objective == ApproximationPrecision::MULPE) {
77
+ if (precision.optimized_for == ApproximationPrecision::MULPE_MAE &&
78
+ e.objective == ApproximationPrecision::MULPE) {
64
79
obj_score = 50 * term_cost; // When MULPE_MAE is not available, prefer MULPE.
65
80
}
66
81
@@ -87,19 +102,26 @@ const Approximation *find_best_approximation(const std::vector<Approximation> &t
87
102
break ;
88
103
}
89
104
90
- if (precision.constraint_max_absolute_error > 0.0 && precision.constraint_max_absolute_error < e.mae ) {
105
+ if (precision.constraint_max_absolute_error > 0.0 &&
106
+ precision.constraint_max_absolute_error < e.mae ) {
91
107
float error_ratio = e.mae / precision.constraint_max_absolute_error ;
92
108
penalty += 20 * error_ratio * extra_term_cost; // penalty for not getting the required precision.
93
109
}
94
110
95
111
double score = obj_score + term_count_score + precision_score - penalty;
96
- // std::printf("Score for %zu (%zu terms): %f = %d + %d + %f - penalty %f\n", i, e.coefficients.size(), score, obj_score, term_count_score, precision_score, penalty);
112
+ #if DEBUG_APPROXIMATION_SEARCH
113
+ std::printf (" Score for %zu (%zu terms): %f = %d + %d + %f - penalty %f\n " ,
114
+ i, e.coefficients .size (), score, obj_score, term_count_score,
115
+ precision_score, penalty);
116
+ #endif
97
117
if (score > best_score || best == nullptr ) {
98
118
best = &e;
99
119
best_score = score;
100
120
}
101
121
}
102
- // std::printf("Best score: %f\n", best_score);
122
+ #if DEBUG_APPROXIMATION_SEARCH
123
+ std::printf (" Best score: %f\n " , best_score);
124
+ #endif
103
125
return best;
104
126
}
105
127
0 commit comments