mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
[poincare/zoom] Ignore imprecise float value
When looking for extrema in a function, we need to discard results where the function growth rate is smaller than the precision of the float type itself : these results are likely to be too noisy, and can cause false positives. e.g. : The sqrt(x^2+1)-x function Change-Id: I6e2c002d7308b41a4c226d274cbb5d9efe4ea7db
This commit is contained in:
committed by
EmilieNumworks
parent
adf28345b1
commit
291b400595
@@ -22,6 +22,16 @@ constexpr float
|
||||
Zoom::k_largeUnitMantissa,
|
||||
Zoom::k_minimalRangeLength;
|
||||
|
||||
static bool DoesNotOverestimatePrecision(float dx, float y1, float y2, float y3) {
|
||||
/* The float type looses precision surprisingly fast, and cannot confidently
|
||||
* hold more than 6.6 digits of precision. Results more precise than that are
|
||||
* too noisy to be be of any value. */
|
||||
float yMin = std::min(y1, std::min(y2, y3));
|
||||
float yMax = std::max(y1, std::max(y2, y3));
|
||||
constexpr float maxPrecision = 2.4e-7f; // 2^-22 ~ 10^-6.6
|
||||
return (yMax - yMin) / std::fabs(dx) > maxPrecision;
|
||||
}
|
||||
|
||||
bool Zoom::InterestingRangesForDisplay(ValueAtAbscissa evaluation, float * xMin, float * xMax, float * yMin, float * yMax, float tMin, float tMax, Context * context, const void * auxiliary) {
|
||||
assert(xMin && xMax && yMin && yMax);
|
||||
|
||||
@@ -84,7 +94,7 @@ bool Zoom::InterestingRangesForDisplay(ValueAtAbscissa evaluation, float * xMin,
|
||||
/* Check for a change in the profile. */
|
||||
const PointOfInterest variation = BoundOfIntervalOfDefinitionIsReached(yPrev, yNext) ? PointOfInterest::Bound :
|
||||
RootExistsOnInterval(yPrev, yNext) ? PointOfInterest::Root :
|
||||
ExtremumExistsOnInterval(yOld, yPrev, yNext) ? PointOfInterest::Extremum :
|
||||
(ExtremumExistsOnInterval(yOld, yPrev, yNext) && DoesNotOverestimatePrecision(dXNext, yOld, yPrev, yNext)) ? PointOfInterest::Extremum :
|
||||
PointOfInterest::None;
|
||||
switch (static_cast<uint8_t>(variation)) {
|
||||
/* The fallthrough is intentional, as we only want to update the Y
|
||||
|
||||
Reference in New Issue
Block a user