[poincare] Remove characteristicXHalfRange

Method characteristicXHalfRange was used to compute the range on which
to display cartesian function in Graph. With the new zoom algorithm,
this method is deprecated.

Change-Id: Ic681fab8d58d0f5628a94302a7b49dacaaa1a6a3
This commit is contained in:
Gabriel Ozouf
2020-08-05 11:08:57 +02:00
committed by Émilie Feral
parent 8104caea50
commit 0ed0cc56e9
16 changed files with 0 additions and 122 deletions

View File

@@ -21,7 +21,6 @@ public:
// Properties
Type type() const override { return Type::Cosine; }
float characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const override;
template<typename T> static Complex<T> computeOnComplex(const std::complex<T> c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit = Preferences::AngleUnit::Radian);

View File

@@ -170,15 +170,6 @@ public:
static bool IsRandom(const Expression e, Context * context);
static bool IsMatrix(const Expression e, Context * context);
static bool IsInfinity(const Expression e, Context * context);
/* 'characteristicXRange' tries to assess the range on x where the expression
* (considered as a function on x) has an interesting evolution. For example,
* the period of the function on 'x' if it is periodic. If
* the function is x-independent, the return value is 0.0f (because any
* x-range is equivalent). If the function does not have an interesting range,
* the return value is NAN.
* NB: so far, we consider that the only way of building a periodic function
* is to use sin/tan/cos(f(x)) with f a linear function. */
float characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const { return node()->characteristicXRange(context, angleUnit); }
/* polynomialDegree returns:
* - (-1) if the expression is not a polynome
* - the degree of the polynome otherwise */

View File

@@ -200,7 +200,6 @@ public:
/*!*/ virtual Expression deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly, int parameteredAncestorsCount);
typedef bool (*isVariableTest)(const char * c, Poincare::Context * context);
virtual int getVariables(Context * context, isVariableTest isVariable, char * variables, int maxSizeVariable, int nextVariableIndex) const;
virtual float characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const;
bool isOfType(Type * types, int length) const;
virtual Expression removeUnit(Expression * unit); // Only reduced nodes should answer

View File

@@ -27,7 +27,6 @@ public:
int polynomialDegree(Context * context, const char * symbolName) const override;
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const override;
int getVariables(Context * context, isVariableTest isVariable, char * variables, int maxSizeVariable, int nextVariableIndex) const override;
float characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const override;
private:
char m_name[0]; // MUST be the last member variable

View File

@@ -21,7 +21,6 @@ public:
// Properties
Type type() const override { return Type::Sine; }
float characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const override;
template<typename T> static Complex<T> computeOnComplex(const std::complex<T> c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit = Preferences::AngleUnit::Radian);

View File

@@ -25,7 +25,6 @@ public:
int polynomialDegree(Context * context, const char * symbolName) const override;
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const override;
int getVariables(Context * context, isVariableTest isVariable, char * variables, int maxSizeVariable, int nextVariableIndex) const override;
float characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const override;
/* getUnit returns Undefined, because the symbol would have
* already been replaced if it should have been.*/

View File

@@ -20,7 +20,6 @@ public:
// Properties
Type type() const override { return Type::Tangent; }
float characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const override;
private:
// Layout

View File

@@ -13,7 +13,6 @@ public:
Sine = 1,
};
static double PiInAngleUnit(Preferences::AngleUnit angleUnit);
static float characteristicXRange(const Expression & e, Context * context, Preferences::AngleUnit angleUnit);
static bool isDirectTrigonometryFunction(const Expression & e);
static bool isInverseTrigonometryFunction(const Expression & e);
static bool AreInverseFunctions(const Expression & directFunction, const Expression & inverseFunction);

View File

@@ -15,10 +15,6 @@ constexpr Expression::FunctionHelper Cosine::s_functionHelper;
int CosineNode::numberOfChildren() const { return Cosine::s_functionHelper.numberOfChildren(); }
float CosineNode::characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const {
return Trigonometry::characteristicXRange(Cosine(this), context, angleUnit);
}
template<typename T>
Complex<T> CosineNode::computeOnComplex(const std::complex<T> c, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) {
std::complex<T> angleInput = Trigonometry::ConvertToRadian(c, angleUnit);

View File

@@ -51,22 +51,6 @@ int ExpressionNode::getVariables(Context * context, isVariableTest isVariable, c
return nextVariableIndex;
}
float ExpressionNode::characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const {
/* A expression has a characteristic range if at least one of its childAtIndex has
* one and the other are x-independant. We keep the biggest interesting range
* among the childAtIndex interesting ranges. */
float range = 0.0f;
for (ExpressionNode * c : children()) {
float opRange = c->characteristicXRange(context, angleUnit);
if (std::isnan(opRange)) {
return NAN;
} else if (range < opRange) {
range = opRange;
}
}
return range;
}
int ExpressionNode::SimplificationOrder(const ExpressionNode * e1, const ExpressionNode * e2, bool ascending, bool canBeInterrupted, bool ignoreParentheses) {
// Depending on ignoreParentheses, check if e1 or e2 are parenthesis
ExpressionNode::Type type1 = e1->type();

View File

@@ -44,15 +44,6 @@ int FunctionNode::getVariables(Context * context, isVariableTest isVariable, cha
return e.node()->getVariables(context, isVariable, variables, maxSizeVariable, nextVariableIndex);
}
float FunctionNode::characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const {
Function f(this);
Expression e = SymbolAbstract::Expand(f,context, true);
if (e.isUninitialized()) {
return 0.0f;
}
return e.characteristicXRange(context, angleUnit);
}
Layout FunctionNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
return LayoutHelper::Prefix(Function(this), floatDisplayMode, numberOfSignificantDigits, name());
}

View File

@@ -13,10 +13,6 @@ constexpr Expression::FunctionHelper Sine::s_functionHelper;
int SineNode::numberOfChildren() const { return Sine::s_functionHelper.numberOfChildren(); }
float SineNode::characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const {
return Trigonometry::characteristicXRange(Sine(this), context, angleUnit);
}
template<typename T>
Complex<T> SineNode::computeOnComplex(const std::complex<T> c, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) {
std::complex<T> angleInput = Trigonometry::ConvertToRadian(c, angleUnit);

View File

@@ -64,10 +64,6 @@ int SymbolNode::getVariables(Context * context, isVariableTest isVariable, char
return nextVariableIndex;
}
float SymbolNode::characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const {
return isUnknown() ? NAN : 0.0f;
}
Layout SymbolNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
assert(!isUnknown());
// TODO return Parse(m_name).createLayout() ?

View File

@@ -17,10 +17,6 @@ constexpr Expression::FunctionHelper Tangent::s_functionHelper;
int TangentNode::numberOfChildren() const { return Tangent::s_functionHelper.numberOfChildren(); }
float TangentNode::characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const {
return Trigonometry::characteristicXRange(Tangent(this), context, angleUnit);
}
Layout TangentNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
return LayoutHelper::Prefix(Tangent(this), floatDisplayMode, numberOfSignificantDigits, Tangent::s_functionHelper.name());
}

View File

@@ -55,32 +55,6 @@ double Trigonometry::PiInAngleUnit(Preferences::AngleUnit angleUnit) {
return 200.0;
}
float Trigonometry::characteristicXRange(const Expression & e, Context * context, Preferences::AngleUnit angleUnit) {
assert(e.numberOfChildren() == 1);
constexpr int bufferSize = CodePoint::MaxCodePointCharLength + 1;
char x[bufferSize];
SerializationHelper::CodePoint(x, bufferSize, UCodePointUnknown);
int d = e.childAtIndex(0).polynomialDegree(context, x);
if (d < 0 || d > 1) {
// child(0) is not linear so we cannot easily find an interesting range
return e.childAtIndex(0).characteristicXRange(context, angleUnit);
}
// The expression e is x-independent
if (d == 0) {
return 0.0f;
}
// e has the form cos/sin/tan(ax+b) so it is periodic of period 2*π/a
assert(d == 1);
/* To compute a, the slope of the expression child(0), we compute the
* derivative of child(0) for any x value. */
Poincare::Derivative derivative = Poincare::Derivative::Builder(e.childAtIndex(0).clone(), Symbol::Builder(x, 1), Float<float>::Builder(1.0f));
double a = derivative.node()->approximate(double(), context, Preferences::ComplexFormat::Real, angleUnit).toScalar();
double pi = PiInAngleUnit(angleUnit);
return std::fabs(a) < Expression::Epsilon<double>() ? NAN : 2.0*pi/std::fabs(a);
}
bool Trigonometry::isDirectTrigonometryFunction(const Expression & e) {
return e.type() == ExpressionNode::Type::Cosine
|| e.type() == ExpressionNode::Type::Sine

View File

@@ -240,45 +240,6 @@ QUIZ_CASE(poincare_properties_polynomial_degree) {
Ion::Storage::sharedStorage()->recordNamed("f.func").destroy();
}
void assert_reduced_expression_has_characteristic_range(Expression e, float range, Preferences::AngleUnit angleUnit = Preferences::AngleUnit::Degree, Preferences::UnitFormat unitFormat = Metric) {
Shared::GlobalContext globalContext;
e = e.reduce(ExpressionNode::ReductionContext(&globalContext, Preferences::ComplexFormat::Cartesian, angleUnit, unitFormat, ExpressionNode::ReductionTarget::SystemForApproximation));
if (std::isnan(range)) {
quiz_assert(std::isnan(e.characteristicXRange(&globalContext, angleUnit)));
} else {
quiz_assert(std::fabs(e.characteristicXRange(&globalContext, angleUnit) - range) < 0.0000001f);
}
}
QUIZ_CASE(poincare_properties_characteristic_range) {
// cos(x), degree
assert_reduced_expression_has_characteristic_range(Cosine::Builder(Symbol::Builder(UCodePointUnknown)), 360.0f);
// cos(-x), degree
assert_reduced_expression_has_characteristic_range(Cosine::Builder(Opposite::Builder(Symbol::Builder(UCodePointUnknown))), 360.0f);
// cos(x), radian
assert_reduced_expression_has_characteristic_range(Cosine::Builder(Symbol::Builder(UCodePointUnknown)), 2.0f*M_PI, Preferences::AngleUnit::Radian);
// cos(-x), radian
assert_reduced_expression_has_characteristic_range(Cosine::Builder(Opposite::Builder(Symbol::Builder(UCodePointUnknown))), 2.0f*M_PI, Preferences::AngleUnit::Radian);
// sin(9x+10), degree
assert_reduced_expression_has_characteristic_range(Sine::Builder(Addition::Builder(Multiplication::Builder(Rational::Builder(9),Symbol::Builder(UCodePointUnknown)),Rational::Builder(10))), 40.0f);
// sin(9x+10)+cos(x/2), degree
assert_reduced_expression_has_characteristic_range(Addition::Builder(Sine::Builder(Addition::Builder(Multiplication::Builder(Rational::Builder(9),Symbol::Builder(UCodePointUnknown)),Rational::Builder(10))),Cosine::Builder(Division::Builder(Symbol::Builder(UCodePointUnknown),Rational::Builder(2)))), 720.0f);
// sin(9x+10)+cos(x/2), radian
assert_reduced_expression_has_characteristic_range(Addition::Builder(Sine::Builder(Addition::Builder(Multiplication::Builder(Rational::Builder(9),Symbol::Builder(UCodePointUnknown)),Rational::Builder(10))),Cosine::Builder(Division::Builder(Symbol::Builder(UCodePointUnknown),Rational::Builder(2)))), 4.0f*M_PI, Preferences::AngleUnit::Radian);
// x, degree
assert_reduced_expression_has_characteristic_range(Symbol::Builder(UCodePointUnknown), NAN);
// cos(3)+2, degree
assert_reduced_expression_has_characteristic_range(Addition::Builder(Cosine::Builder(Rational::Builder(3)),Rational::Builder(2)), 0.0f);
// log(cos(40x), degree
assert_reduced_expression_has_characteristic_range(CommonLogarithm::Builder(Cosine::Builder(Multiplication::Builder(Rational::Builder(40),Symbol::Builder(UCodePointUnknown)))), 9.0f);
// cos(cos(x)), degree
assert_reduced_expression_has_characteristic_range(Cosine::Builder((Expression)Cosine::Builder(Symbol::Builder(UCodePointUnknown))), 360.0f);
// f(x) with f : x --> cos(x), degree
assert_reduce("cos(x)→f(x)");
assert_reduced_expression_has_characteristic_range(Function::Builder("f",1,Symbol::Builder(UCodePointUnknown)), 360.0f);
Ion::Storage::sharedStorage()->recordNamed("f.func").destroy();
}
void assert_expression_has_variables(const char * expression, const char * variables[], int trueNumberOfVariables) {
Shared::GlobalContext globalContext;
Expression e = parse_expression(expression, &globalContext, false);