From 576d1dcd6ba4e4284318efad9936041d97e7719f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Thu, 12 Mar 2020 14:10:16 +0100 Subject: [PATCH] [poincare/power] Rename and comment computeRealRootOfRationalPow --- poincare/include/poincare/power.h | 2 +- poincare/src/nth_root.cpp | 2 +- poincare/src/power.cpp | 18 +++++++++++++----- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/poincare/include/poincare/power.h b/poincare/include/poincare/power.h index b2e161b85..1f40e978f 100644 --- a/poincare/include/poincare/power.h +++ b/poincare/include/poincare/power.h @@ -34,7 +34,7 @@ public: int polynomialDegree(Context * context, const char * symbolName) const override; int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const override; - template static Complex computeRealRootOfRationalPow(const std::complex c, T p, T q); + template static Complex tryComputeRealRootOfRationalPow(const std::complex c, T p, T q); template static Complex compute(const std::complex c, const std::complex d, Preferences::ComplexFormat complexFormat); private: diff --git a/poincare/src/nth_root.cpp b/poincare/src/nth_root.cpp index b5081c1c0..3af471605 100644 --- a/poincare/src/nth_root.cpp +++ b/poincare/src/nth_root.cpp @@ -48,7 +48,7 @@ Evaluation NthRootNode::templatedApproximate(Context * context, Preferences:: * correspond to the principale angle. */ if (complexFormat == Preferences::ComplexFormat::Real && indexc.imag() == 0.0 && std::round(indexc.real()) == indexc.real()) { // root(x, q) with q integer and x real - Complex result = PowerNode::computeRealRootOfRationalPow(basec, (T)1.0, indexc.real()); + Complex result = PowerNode::tryComputeRealRootOfRationalPow(basec, (T)1.0, indexc.real()); if (!result.isUndefined()) { return result; } diff --git a/poincare/src/power.cpp b/poincare/src/power.cpp index 460437e3f..712c5ab79 100644 --- a/poincare/src/power.cpp +++ b/poincare/src/power.cpp @@ -128,16 +128,24 @@ bool PowerNode::childAtIndexNeedsUserParentheses(const Expression & child, int c // Private template -Complex PowerNode::computeRealRootOfRationalPow(const std::complex c, T p, T q) { - // Compute real root of c^(p/q) with p, q integers if it has a real root +Complex PowerNode::tryComputeRealRootOfRationalPow(const std::complex c, T p, T q) { + // Assert p and q are in fact integers + assert(std::round(p) == p); + assert(std::round(q) == q); + /* Try to find a real root of c^(p/q) with p, q integers. If none is found + * easily, return undefined -> this does not mean there is no real root. */ if (c.imag() == 0 && std::pow((T)-1.0, q) < 0.0) { /* If c real and q odd integer (q odd if (-1)^q = -1), a real root does - * exist (which is not necessarily the principal root)! */ + * exist (which is not necessarily the principal root)! + * For q even integer, a real root does not necessarily exist (example: + * -2 ^(1/2)). */ std::complex absc = c; absc.real(std::fabs(absc.real())); // compute |c|^(p/q) which is a real Complex absCPowD = PowerNode::compute(absc, std::complex(p/q), Preferences::ComplexFormat::Real); - // c^(p/q) = (sign(c)^p)*|c|^(p/q) = -|c|^(p/q) iff c < 0 and p odd + /* As q is odd, c^(p/q) = (sign(c)^(1/q))^p * |c|^(p/q) + * = sign(c)^p * |c|^(p/q) + * = -|c|^(p/q) iff c < 0 and p odd */ return c.real() < 0 && std::pow((T)-1.0, p) < 0.0 ? Complex::Builder(-absCPowD.stdComplex()) : absCPowD; } return Complex::Undefined(); @@ -313,7 +321,7 @@ template Evaluation PowerNode::templatedApproximate(Context * con if (std::isnan(p) || std::isnan(q)) { goto defaultApproximation; } - Complex result = computeRealRootOfRationalPow(c, p, q); + Complex result = tryComputeRealRootOfRationalPow(c, p, q); if (!result.isUndefined()) { return result; }