mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
[apps/graph] Remove tests on ranges
As zooming has moved to Poincare, so will the tests. Change-Id: I6c1fe581edc903369779e46a295447273a89e517
This commit is contained in:
committed by
Émilie Feral
parent
1bfeeb5842
commit
0a6ac0b40b
@@ -42,7 +42,6 @@ i18n_files += $(call i18n_without_universal_for,graph/base)
|
||||
tests_src += $(addprefix apps/graph/test/,\
|
||||
caching.cpp \
|
||||
helper.cpp \
|
||||
range.cpp \
|
||||
)
|
||||
|
||||
$(eval $(call depends_on_image,apps/graph/app.cpp,apps/graph/graph_icon.png))
|
||||
|
||||
@@ -1,182 +0,0 @@
|
||||
#include <quiz.h>
|
||||
#include "helper.h"
|
||||
#include <cmath>
|
||||
|
||||
using namespace Poincare;
|
||||
using namespace Shared;
|
||||
|
||||
namespace Graph {
|
||||
|
||||
void assert_range_inclusion_predicate(const char * definition, ContinuousFunction::PlotType type, const float * xList, size_t length, bool testInclusion) {
|
||||
/* Test that all points (x, f(x)) for x in xList are either included in the
|
||||
* range if testIncluded is true, or exculded from the range if testInclusion
|
||||
* is false.
|
||||
* If f(x) is not finite, only the presence of x in the horizontal range is
|
||||
* tested. */
|
||||
GlobalContext globalContext;
|
||||
ContinuousFunctionStore functionStore;
|
||||
ContinuousFunction * f = addFunction(definition, type, &functionStore, &globalContext);
|
||||
|
||||
float xMin = FLT_MAX, xMax = - FLT_MAX, yMin = FLT_MAX, yMax = - FLT_MAX;
|
||||
f->rangeForDisplay(&xMin, &xMax, &yMin, &yMax, &globalContext);
|
||||
assert(xMin <= xMax && yMin <= yMax);
|
||||
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
float x = xList[i];
|
||||
float y = f->evaluateXYAtParameter(x, &globalContext).x2();
|
||||
assert(std::isfinite(x));
|
||||
if (!testInclusion) {
|
||||
quiz_assert(xMin > x || x > xMax || (std::isfinite(y) && (yMin > y || y > yMax)));
|
||||
} else {
|
||||
/* The program can miss the exact abscissa of an extremum, resulting in
|
||||
* bounds that are close from its value but that do not encompass it. We
|
||||
* thus test the inclusion of (x, f(x)) along with two neighbouring
|
||||
* points. */
|
||||
float dx = (xMax - xMin) / (Ion::Display::Width / 2);
|
||||
float y1 = f->evaluateXYAtParameter(x - dx, &globalContext).x2(), y2 = f->evaluateXYAtParameter(x + dx, &globalContext).x2();
|
||||
quiz_assert(xMin <= x
|
||||
&& x <= xMax
|
||||
&& (!std::isfinite(y)
|
||||
|| (yMin <= y && y <= yMax)
|
||||
|| (yMin <= y1 && y1 <= yMax)
|
||||
|| (yMin <= y2 && y2 <= yMax)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void assert_range_includes_points(const char * definition, ContinuousFunction::PlotType type, const float * xList, size_t length) { assert_range_inclusion_predicate(definition, type, xList, length, true); }
|
||||
void assert_range_excludes_points(const char * definition, ContinuousFunction::PlotType type, const float * xList, size_t length) { assert_range_inclusion_predicate(definition, type, xList, length, false); }
|
||||
|
||||
void assert_range_includes_single_point(const char * definition, ContinuousFunction::PlotType type, float x) { assert_range_includes_points(definition, type, &x, 1); }
|
||||
void assert_range_excludes_single_point(const char * definition, ContinuousFunction::PlotType type, float x) { assert_range_excludes_points(definition, type, &x, 1); }
|
||||
|
||||
void assert_range_includes_and_bounds_asymptotes(const char * definition, const float * asymptotesXList, size_t length) {
|
||||
/* The value for delta is the step the old algorithm used to sample a
|
||||
* cartesian function, causing functions such as 1/x to be evaluated too
|
||||
* close to 0. */
|
||||
constexpr float delta = 1.f / 32.f;
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
float x = asymptotesXList[i];
|
||||
assert_range_includes_single_point(definition, Cartesian, x);
|
||||
assert_range_excludes_single_point(definition, Cartesian, x - delta);
|
||||
assert_range_excludes_single_point(definition, Cartesian, x + delta);
|
||||
}
|
||||
}
|
||||
|
||||
void assert_range_shows_enough_periods(const char * definition, float period, Preferences::AngleUnit angleUnit = Preferences::AngleUnit::Degree) {
|
||||
/* The graph should display at least 3 periods, but no more than 7. */
|
||||
constexpr int lowNumberOfPeriods = 3, highNumberOfPeriods = 8;
|
||||
|
||||
GlobalContext globalContext;
|
||||
ContinuousFunctionStore functionStore;
|
||||
ContinuousFunction * f = addFunction(definition, Cartesian, &functionStore, &globalContext);
|
||||
|
||||
Preferences::sharedPreferences()->setAngleUnit(angleUnit);
|
||||
if (angleUnit != Preferences::AngleUnit::Degree) {
|
||||
f->setPlotType(Cartesian, angleUnit, &globalContext);
|
||||
}
|
||||
|
||||
float xMin = FLT_MAX, xMax = - FLT_MAX, yMin = FLT_MAX, yMax = - FLT_MAX;
|
||||
f->rangeForDisplay(&xMin, &xMax, &yMin, &yMax, &globalContext);
|
||||
assert(xMin <= xMax && yMin <= yMax);
|
||||
float numberOfPeriods = (xMax - xMin) / period;
|
||||
|
||||
quiz_assert(lowNumberOfPeriods <= numberOfPeriods && numberOfPeriods <= highNumberOfPeriods);
|
||||
}
|
||||
|
||||
void assert_range_displays_entire_polar_function(const char * definition) {
|
||||
GlobalContext globalContext;
|
||||
ContinuousFunctionStore functionStore;
|
||||
ContinuousFunction * f = addFunction(definition, Polar, &functionStore, &globalContext);
|
||||
|
||||
float xMin = FLT_MAX, xMax = - FLT_MAX, yMin = FLT_MAX, yMax = - FLT_MAX;
|
||||
f->rangeForDisplay(&xMin, &xMax, &yMin, &yMax, &globalContext);
|
||||
assert(xMin <= xMax && yMin <= yMax);
|
||||
|
||||
for (float t = f->tMin(); t < f->tMax(); t += f->rangeStep()) {
|
||||
const Coordinate2D<float> xy = f->evaluateXYAtParameter(t, &globalContext);
|
||||
if (!std::isfinite(xy.x1()) || !std::isfinite(xy.x2())) {
|
||||
continue;
|
||||
}
|
||||
quiz_assert(xMin <= xy.x1() && xy.x1() <= xMax && yMin <= xy.x2() && xy.x2() <= yMax);
|
||||
}
|
||||
}
|
||||
|
||||
QUIZ_CASE(graph_range_polynomes) {
|
||||
assert_range_includes_single_point("37", Cartesian, 0.f);
|
||||
assert_range_includes_single_point("x-1", Cartesian, 1.f);
|
||||
assert_range_includes_single_point("100+x", Cartesian, -100.f);
|
||||
assert_range_includes_single_point("x^2-20*x+101", Cartesian, 10.f);
|
||||
|
||||
constexpr float array1[2] = {-2.f, 3.f};
|
||||
assert_range_includes_points("(x+2)*(x-3)", Cartesian, array1, 2);
|
||||
|
||||
constexpr float array2[2] = {-1.f, 0.5f};
|
||||
assert_range_includes_points("2*x^2+x-1", Cartesian, array2, 2);
|
||||
|
||||
constexpr float array3[6] = {-3.f, 3.f, -2.f, 2.f, -1.f, 1.f};
|
||||
assert_range_includes_points("(x+3)(x+2)(x+1)(x-1)(x-2)(x-3)", Cartesian, array3, 6);
|
||||
|
||||
constexpr float array4[3] = {0.f, 4.f, 5.f};
|
||||
assert_range_includes_points("x^5-5*x^4", Cartesian, array4, 3);
|
||||
}
|
||||
|
||||
QUIZ_CASE(graph_range_exponential) {
|
||||
assert_range_includes_single_point("ℯ^x", Cartesian, 0.f);
|
||||
assert_range_excludes_single_point("ℯ^x", Cartesian, 4.f);
|
||||
|
||||
assert_range_includes_single_point("ℯ^(-x)", Cartesian, 0.f);
|
||||
assert_range_excludes_single_point("ℯ^(-x)", Cartesian, -4.f);
|
||||
|
||||
constexpr float array1[3] = {1.f, 5.f, 1e-1f};
|
||||
assert_range_includes_points("ln(x)", Cartesian, array1, 3);
|
||||
assert_range_excludes_single_point("ln(x)", Cartesian, 1e-3f);
|
||||
|
||||
constexpr float array2[2] = {-1.f, 3.f};
|
||||
assert_range_includes_points("2-ℯ^(-x)", Cartesian, array2, 2);
|
||||
assert_range_excludes_single_point("2-ℯ^(-x)", Cartesian, 50.f);
|
||||
assert_range_excludes_single_point("2-ℯ^(-x)", Cartesian, -10.f);
|
||||
|
||||
assert_range_includes_single_point("x^x", Cartesian, 0.5f);
|
||||
assert_range_excludes_single_point("x^x", Cartesian, -5.f);
|
||||
assert_range_includes_single_point("x^(1/x)", Cartesian, 1e-3f);
|
||||
}
|
||||
|
||||
QUIZ_CASE(graph_range_fractions) {
|
||||
constexpr float array1[1] = {0.f};
|
||||
assert_range_includes_and_bounds_asymptotes("1/x", array1, 1);
|
||||
assert_range_includes_and_bounds_asymptotes("1/x^2", array1, 1);
|
||||
|
||||
constexpr float array2[2] = {-2.f, 2.f};
|
||||
assert_range_includes_and_bounds_asymptotes("1/(x^2-4)", array2, 2);
|
||||
|
||||
constexpr float array3[1] = {-100.f};
|
||||
assert_range_includes_and_bounds_asymptotes("1/(x+100)", array3, 1);
|
||||
}
|
||||
|
||||
QUIZ_CASE(graph_range_periodic) {
|
||||
assert_range_shows_enough_periods("sin(x)", 2*M_PI, Preferences::AngleUnit::Radian);
|
||||
assert_range_shows_enough_periods("sin(x)", 360.f);
|
||||
assert_range_shows_enough_periods("sin(x)+10", 2*M_PI, Preferences::AngleUnit::Radian);
|
||||
assert_range_shows_enough_periods("sin(x)+10", 360.f);
|
||||
assert_range_shows_enough_periods("cos(x)", 2*M_PI, Preferences::AngleUnit::Radian);
|
||||
assert_range_shows_enough_periods("cos(x)", 360.f);
|
||||
assert_range_shows_enough_periods("sin(x)/x", 2*M_PI, Preferences::AngleUnit::Radian);
|
||||
assert_range_shows_enough_periods("sin(x)/x", 360.f);
|
||||
assert_range_shows_enough_periods("x*sin(x)", 2*M_PI, Preferences::AngleUnit::Radian);
|
||||
assert_range_shows_enough_periods("x*sin(x)", 360.f);
|
||||
assert_range_shows_enough_periods("ln(sin(x))", 2*M_PI, Preferences::AngleUnit::Radian);
|
||||
assert_range_shows_enough_periods("ln(sin(x))", 360.f);
|
||||
constexpr float array1[2] = {-1.f, 1.f};
|
||||
assert_range_includes_points("x*sin(1/x)", Cartesian, array1, 2);
|
||||
}
|
||||
|
||||
QUIZ_CASE(graph_range_polar) {
|
||||
assert_range_displays_entire_polar_function("1");
|
||||
assert_range_displays_entire_polar_function("θ");
|
||||
assert_range_displays_entire_polar_function("sin(θ)");
|
||||
assert_range_displays_entire_polar_function("sin(10θ)");
|
||||
assert_range_displays_entire_polar_function("ln(θ)");
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user