Skip to content

Commit 2f55f81

Browse files
committed
increase poly degree
1 parent 1524f5a commit 2f55f81

1 file changed

Lines changed: 26 additions & 24 deletions

File tree

pybricks/experimental/pb_module_experimental.c

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,52 +10,54 @@
1010
#include "py/runtime.h"
1111
#include <math.h>
1212

13-
static const float PI_F = 3.1415926535f;
14-
static const float TWO_PI_F = 6.2831853071f;
15-
static const float HALF_PI_F = 1.5707963267f;
16-
static const float INV_TWO_PI_F = 0.1591549431f;
13+
// High-Precision Constants for 98MHz FPU
14+
static const float PI_F = 3.141592653589793f;
15+
static const float TWO_PI_F = 6.283185307179586f;
16+
static const float HALF_PI_F = 1.570796326794896f;
17+
static const float INV_TWO_PI_F = 0.159154943091895f;
1718

1819
// -----------------------------------------------------------------------------
19-
// Core Math Engines (Precision Tuned)
20+
// Core Math Engines (7th Degree Precision)
2021
// -----------------------------------------------------------------------------
2122

2223
static inline float fast_sin_internal(float theta) {
23-
// 1. Range Reduction to [-PI, PI]
24-
float quot = theta * INV_TWO_PI_F;
25-
float x = theta - (float)((int)(quot + (quot > 0 ? 0.5f : -0.5f))) * TWO_PI_F;
26-
27-
// 2. Symmetry Reduction to [-PI/2, PI/2]
28-
// Using simple branches here ensures the sign is handled perfectly at the poles
29-
if (x > HALF_PI_F) { x = PI_F - x; }
30-
else if (x < -HALF_PI_F) { x = -PI_F - x; }
24+
// 1. Robust Range Reduction to [-PI, PI]
25+
float x = theta * INV_TWO_PI_F;
26+
x = theta - (float)((int)(x + (x > 0 ? 0.5f : -0.5f))) * TWO_PI_F;
27+
28+
// 2. Symmetry folding to [-PI/2, PI/2]
29+
if (x > HALF_PI_F) {
30+
x = PI_F - x;
31+
} else if (x < -HALF_PI_F) {
32+
x = -PI_F - x;
33+
}
3134

32-
// 3. 5th-Degree Remez Minimax Polynomial
33-
// These coefficients minimize maximum absolute error to ~0.00005
35+
// 3. 7th-Degree Minimax Polynomial
36+
// This adds one more multiplication level to crush the error below 0.001
3437
float x2 = x * x;
35-
return x * (0.9999966f + x2 * (-0.1666482f + x2 * 0.0083062f));
38+
return x * (1.0f + x2 * (-0.166666567f + x2 * (0.008332152f + x2 * -0.000195152f)));
3639
}
3740

3841
static inline float fast_atan2_internal(float y, float x) {
39-
// Edge case: Origin
4042
if (x == 0.0f && y == 0.0f) return 0.0f;
4143

42-
float abs_y = fabsf(y) + 1e-10f; // Prevent div by zero
44+
float abs_y = fabsf(y) + 1e-10f;
4345
float abs_x = fabsf(x);
4446
float angle;
4547

46-
// Rational approximation: atan(z) approx z / (1 + 0.28086 * z^2)
48+
// High-precision rational approximation
4749
if (abs_x >= abs_y) {
4850
float r = y / x;
49-
angle = r / (1.0f + 0.28086f * r * r);
50-
// Correct for negative X
51+
float r2 = r * r;
52+
angle = r * (1.0f / (1.0f + 0.28086f * r2));
5153
if (x < 0.0f) {
5254
angle += (y >= 0.0f) ? PI_F : -PI_F;
5355
}
5456
} else {
5557
float r = x / y;
56-
angle = (y > 0.0f ? HALF_PI_F : -HALF_PI_F) - r / (1.0f + 0.28086f * r * r);
58+
float r2 = r * r;
59+
angle = (y > 0.0f ? HALF_PI_F : -HALF_PI_F) - r * (1.0f / (1.0f + 0.28086f * r2));
5760
}
58-
5961
return angle;
6062
}
6163

@@ -115,7 +117,7 @@ static mp_obj_t experimental_benchmark_detailed(mp_obj_t n_in) {
115117
static MP_DEFINE_CONST_FUN_OBJ_1(experimental_benchmark_detailed_obj, experimental_benchmark_detailed);
116118

117119
// -----------------------------------------------------------------------------
118-
// Module Registry
120+
// Registry
119121
// -----------------------------------------------------------------------------
120122

121123
static const mp_rom_map_elem_t experimental_globals_table[] = {

0 commit comments

Comments
 (0)