Optimize cuberoot using Newton-Raphson approximation

Change-Id: I23a2515b42ef6592df0a18f04420670dc2b4ac1a
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
Allan Sandfeld Jensen 2024-02-28 17:00:14 +01:00
parent 111c08d0ea
commit 5f516b2442
1 changed files with 16 additions and 3 deletions

View File

@ -80,15 +80,15 @@ public:
float fx, fy, fz;
if (xr > eps)
fx = std::cbrt(xr);
fx = fastCbrt(xr);
else
fx = (kap * xr + 16.f) / 116.f;
if (yr > eps)
fy = std::cbrt(yr);
fy = fastCbrt(yr);
else
fy = (kap * yr + 16.f) / 116.f;
if (zr > eps)
fz = std::cbrt(zr);
fz = fastCbrt(zr);
else
fz = (kap * zr + 16.f) / 116.f;
@ -135,6 +135,19 @@ public:
}
friend inline bool comparesEqual(const QColorVector &lhs, const QColorVector &rhs);
Q_DECLARE_EQUALITY_COMPARABLE(QColorVector);
private:
static float fastCbrt(float x)
{
// This gives us cube root within the precision we need.
float est = 0.25f + (x * 0.75f); // guessing a cube-root of numbers between 0.01 and 1.
est -= ((est * est * est) - x) / (3.f * (est * est));
est -= ((est * est * est) - x) / (3.f * (est * est));
est -= ((est * est * est) - x) / (3.f * (est * est));
est -= ((est * est * est) - x) / (3.f * (est * est));
// Q_ASSERT(qAbs(est - std::cbrt(x)) < 0.0001f);
return est;
}
};
inline bool comparesEqual(const QColorVector &v1, const QColorVector &v2)