mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
[poincare/zoom] Clean up and comment API
Change-Id: I58347d7188551471817fb334bcb54d5c5b398f72
This commit is contained in:
committed by
Émilie Feral
parent
91e1154bb8
commit
c647bfe566
@@ -16,14 +16,22 @@ public:
|
||||
|
||||
typedef float (*ValueAtAbscissa)(float abscissa, Context * context, const void * auxiliary);
|
||||
|
||||
/* Return false if the X range was given a default value because there were
|
||||
* no points of interest. */
|
||||
/* Find the most suitable window to display the function's points of
|
||||
* interest. Return false if the X range was given a default value because
|
||||
* there were no points of interest. */
|
||||
static bool InterestingRangesForDisplay(ValueAtAbscissa evaluation, float * xMin, float * xMax, float * yMin, float * yMax, float tMin, float tMax, Context * context, const void * auxiliary);
|
||||
/* Find the best Y range to display the function on [xMin, xMax], but crop
|
||||
* the values that are outside of the function's order of magnitude. */
|
||||
static void RefinedYRangeForDisplay(ValueAtAbscissa evaluation, float xMin, float xMax, float * yMin, float * yMax, Context * context, const void * auxiliary);
|
||||
/* Find the best window to display functions, with a specified ratio
|
||||
* between X and Y. Usually used to find the most fitting orthonormal range. */
|
||||
static void RangeWithRatioForDisplay(ValueAtAbscissa evaluation, float yxRatio, float * xMin, float * xMax, float * yMin, float * yMax, Context * context, const void * auxiliary);
|
||||
static void FullRange(ValueAtAbscissa evaluation, float tMin, float tMax, float tStep, float * fMin, float * fMax, Context * context, const void * auxiliary);
|
||||
|
||||
/* Find the bounding box of the given ranges. */
|
||||
static void CombineRanges(int length, const float * mins, const float * maxs, float * minRes, float * maxRes);
|
||||
/* Ensures that the window is fit for display, with all bounds being proper
|
||||
* numbers, with min < max. */
|
||||
static void SanitizeRange(float * xMin, float * xMax, float * yMin, float * yMax, float normalRatio);
|
||||
|
||||
/* If shrink is false, the range will be set to ratio by increasing the size
|
||||
|
||||
@@ -215,6 +215,63 @@ void Zoom::RefinedYRangeForDisplay(ValueAtAbscissa evaluation, float xMin, float
|
||||
}
|
||||
}
|
||||
|
||||
void Zoom::RangeWithRatioForDisplay(ValueAtAbscissa evaluation, float yxRatio, float * xMin, float * xMax, float * yMin, float * yMax, Context * context, const void * auxiliary) {
|
||||
constexpr float units[] = {k_smallUnitMantissa, k_mediumUnitMantissa, k_largeUnitMantissa};
|
||||
constexpr float rangeMagnitudeWeight = 0.2f;
|
||||
constexpr float maxMagnitudeDifference = 2.f;
|
||||
|
||||
float bestGrade = FLT_MAX;
|
||||
float xMagnitude = k_minimalDistance;
|
||||
float yMinRange = FLT_MAX, yMaxRange = -FLT_MAX;
|
||||
while (xMagnitude < k_maximalDistance) {
|
||||
for(const float unit : units) {
|
||||
const float xRange = unit * xMagnitude;
|
||||
RefinedYRangeForDisplay(evaluation, -xRange, xRange, &yMinRange, &yMaxRange, context, auxiliary);
|
||||
float currentRatio = (yMaxRange - yMinRange) / (2 * xRange);
|
||||
float grade = std::fabs(std::log(currentRatio / yxRatio));
|
||||
/* When in doubt, favor ranges between [-1, 1] and [-10, 10] */
|
||||
grade += std::fabs(std::log(xRange / 10.f) * std::log(xRange)) * rangeMagnitudeWeight;
|
||||
if (std::fabs(std::log(currentRatio / yxRatio)) < maxMagnitudeDifference && grade < bestGrade) {
|
||||
bestGrade = grade;
|
||||
*xMin = -xRange;
|
||||
*xMax = xRange;
|
||||
*yMin = yMinRange;
|
||||
*yMax = yMaxRange;
|
||||
}
|
||||
}
|
||||
xMagnitude *= 10.f;
|
||||
}
|
||||
if (bestGrade == FLT_MAX) {
|
||||
*xMin = NAN;
|
||||
*xMax = NAN;
|
||||
*yMin = NAN;
|
||||
*yMax = NAN;
|
||||
return;
|
||||
}
|
||||
|
||||
SetToRatio(yxRatio, xMin, xMax, yMin, yMax);
|
||||
}
|
||||
|
||||
void Zoom::FullRange(ValueAtAbscissa evaluation, float tMin, float tMax, float tStep, float * fMin, float * fMax, Context * context, const void * auxiliary) {
|
||||
float t = tMin;
|
||||
*fMin = FLT_MAX;
|
||||
*fMax = -FLT_MAX;
|
||||
while (t <= tMax) {
|
||||
float value = evaluation(t, context, auxiliary);
|
||||
if (value < *fMin) {
|
||||
*fMin = value;
|
||||
}
|
||||
if (value > *fMax) {
|
||||
*fMax = value;
|
||||
}
|
||||
t += tStep;
|
||||
}
|
||||
if (*fMin > *fMax) {
|
||||
*fMin = NAN;
|
||||
*fMax = NAN;
|
||||
}
|
||||
}
|
||||
|
||||
void Zoom::CombineRanges(int length, const float * mins, const float * maxs, float * minRes, float * maxRes) {
|
||||
ValueAtAbscissa evaluation = [](float x, Context * context, const void * auxiliary) {
|
||||
int index = std::round(x);
|
||||
@@ -288,63 +345,6 @@ void Zoom::SetToRatio(float yxRatio, float * xMin, float * xMax, float * yMin, f
|
||||
*tMin = center - newRange / 2.f;
|
||||
}
|
||||
|
||||
void Zoom::RangeWithRatioForDisplay(ValueAtAbscissa evaluation, float yxRatio, float * xMin, float * xMax, float * yMin, float * yMax, Context * context, const void * auxiliary) {
|
||||
constexpr float units[] = {k_smallUnitMantissa, k_mediumUnitMantissa, k_largeUnitMantissa};
|
||||
constexpr float rangeMagnitudeWeight = 0.2f;
|
||||
constexpr float maxMagnitudeDifference = 2.f;
|
||||
|
||||
float bestGrade = FLT_MAX;
|
||||
float xMagnitude = k_minimalDistance;
|
||||
float yMinRange = FLT_MAX, yMaxRange = -FLT_MAX;
|
||||
while (xMagnitude < k_maximalDistance) {
|
||||
for(const float unit : units) {
|
||||
const float xRange = unit * xMagnitude;
|
||||
RefinedYRangeForDisplay(evaluation, -xRange, xRange, &yMinRange, &yMaxRange, context, auxiliary);
|
||||
float currentRatio = (yMaxRange - yMinRange) / (2 * xRange);
|
||||
float grade = std::fabs(std::log(currentRatio / yxRatio));
|
||||
/* When in doubt, favor ranges between [-1, 1] and [-10, 10] */
|
||||
grade += std::fabs(std::log(xRange / 10.f) * std::log(xRange)) * rangeMagnitudeWeight;
|
||||
if (std::fabs(std::log(currentRatio / yxRatio)) < maxMagnitudeDifference && grade < bestGrade) {
|
||||
bestGrade = grade;
|
||||
*xMin = -xRange;
|
||||
*xMax = xRange;
|
||||
*yMin = yMinRange;
|
||||
*yMax = yMaxRange;
|
||||
}
|
||||
}
|
||||
xMagnitude *= 10.f;
|
||||
}
|
||||
if (bestGrade == FLT_MAX) {
|
||||
*xMin = NAN;
|
||||
*xMax = NAN;
|
||||
*yMin = NAN;
|
||||
*yMax = NAN;
|
||||
return;
|
||||
}
|
||||
|
||||
SetToRatio(yxRatio, xMin, xMax, yMin, yMax);
|
||||
}
|
||||
|
||||
void Zoom::FullRange(ValueAtAbscissa evaluation, float tMin, float tMax, float tStep, float * fMin, float * fMax, Context * context, const void * auxiliary) {
|
||||
float t = tMin;
|
||||
*fMin = FLT_MAX;
|
||||
*fMax = -FLT_MAX;
|
||||
while (t <= tMax) {
|
||||
float value = evaluation(t, context, auxiliary);
|
||||
if (value < *fMin) {
|
||||
*fMin = value;
|
||||
}
|
||||
if (value > *fMax) {
|
||||
*fMax = value;
|
||||
}
|
||||
t += tStep;
|
||||
}
|
||||
if (*fMin > *fMax) {
|
||||
*fMin = NAN;
|
||||
*fMax = NAN;
|
||||
}
|
||||
}
|
||||
|
||||
bool Zoom::IsConvexAroundExtremum(ValueAtAbscissa evaluation, float x1, float x2, float x3, float y1, float y2, float y3, Context * context, const void * auxiliary, int iterations) {
|
||||
if (iterations <= 0) {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user