I am implementing a piecewise linear function to linearize the sqrt operation. I am using breakpoints from 0 to 100,000. I have set higher precision in lower breakpoints (as the sqrt changes more rapidly) and less in the higher values.
I implemented the same code in python:
def piecewise_linear_sqrt(x, coefficients, breakpoints, scale_factor):
"""Approximate square root using piecewise linear functions with integer coefficients."""
if x < 0:
return 0 # Return 0 for negative values
for i, (m, n) in enumerate(coefficients):
if breakpoints[i] <= x < breakpoints[i+1]:
result = (m * x + n) / scale_factor
return result
m, n = coefficients[-1]
return (m * x + n) / scale_factor # Use the last segment for any values at or beyond the last breakpoint
and in C:
float piecewise_linear_sqrt(int x) {
if (x < 0) {
return 0;
}
for (int i = 0; i < num_coefficients - 1; ++i) {
if (x >= breakpoints[i] && x < breakpoints[i + 1]) {
float result = (coefficients[i][0] * x + coefficients[i][1]) / scale_factor;
return result;
}
}
if (x >= breakpoints[num_coefficients - 1]) {
float result = (coefficients[num_coefficients - 1][0] * x + coefficients[num_coefficients - 1][1]) / scale_factor;
return result;
}
return 0;
}
However, when I run the two implements with the same input, I have a different behaviour.

I guess that I have a precision problem from what I see, but I dont know how to get better results. I tried increasing the scaling of the coefficient to be used in the cpp because I want to later us a fixed point implementation.
Any ideas on how to improve the performance of this code or any reference/code that I can follow/borrow?
