满足给定MSE约束的离散点连续近似函数与控制点最小化问询
Great question—balancing accuracy and resource usage on MCUs is always a tricky but rewarding problem. Looking at your dataset, one key detail jumps out: your y-values are perfectly uniform (step of 0.005), while x grows non-linearly with distinct slow/fast/slow phases. We can leverage this to cut control points down to single digits, no need for 82+ spline points.
Option 1: Piecewise Polynomial Fitting (Top Recommendation)
Your curve has three clear behavioral segments, so we can fit low-order polynomials to each—each segment only needs 2-3 control points total:
- Segment 1 (y: 0.05 → 0.135, x: 3.387 → 5.148): x grows faster as y increases. A quadratic polynomial (
x = a*y² + b*y + c) will fit this with tiny MSE, using just the start, middle, and end points of the segment as controls. - Segment 2 (y: 0.135 → 0.14, x: 5.148 → 5.267): This is a sharp jump, so we can either use a linear transition between the two points or treat it as a direct mapping (no interpolation needed here).
- Segment 3 (y: 0.14 → 0.255, x: 5.267 → 8.09): x grows linearly with y here! The fit is nearly perfect:
x = 24.547*y + 1.880. Calculate the slope/offset once in Python, then hardcode the coefficients in your MCU code.
On the MCU, this is super cheap: check which segment your target y falls into, plug into the corresponding polynomial, and compute. All operations are basic add/multiply—no fancy math required. You can even convert coefficients to fixed-point (Q-format) if you want to avoid floating-point entirely.
Option 2: Sparse Lookup Table + Linear Interpolation
Since y is uniform, we can build a tiny lookup table of key turning points, then use linear interpolation for values in between. For example, these 5 control points capture all the non-linear behavior:
- (0.05, 3.387)
- (0.115, 4.974)
- (0.135, 5.148)
- (0.14, 5.267)
- (0.255, 8.09)
To compute x for any y:
- Find which pair of adjacent control points contains your y value
- Use the linear interpolation formula (easy to implement in C/MCU code):
x = x0 + (y - y0) * (x1 - x0) / (y1 - y0);
Linear interpolation is trivial for MCUs, and you can tweak the number of control points to hit your exact MSE limit—add a point if a segment's error is too high, remove one if you can get away with it.
Option 3: Single Global Polynomial (No Branching)
If you want to avoid conditional logic (segment checks), a single quadratic polynomial can fit the entire dataset with acceptable MSE. For example, a quick fit gives:x = 142.3*y² - 16.5*y + 4.3
Calculate the MSE against your dataset—if it's within your allowed limit, this is the cheapest option: just two multiplies and two adds, no branches at all.
Quick Validation & Optimization Tips
- Use Python's
numpy.polyfitorscipy.interpolate.interp1dto test MSE for each option before porting to MCU code. - If your MCU doesn't have a floating-point unit, convert all coefficients to fixed-point (e.g., Q15) to speed up calculations and save memory.
- Start with the piecewise option—it gives the best balance of low control points and tight MSE, and the branching is minimal (only 2 checks total).
内容的提问来源于stack exchange,提问作者fearless_fool

