[poincare] Do not simplify power when it is the children of a logarithm

that can simplify

Change-Id: Ibec5a97b4eda0cf25efcbe5ee4f9a99673c0eb8a
This commit is contained in:
Émilie Feral
2017-11-17 18:07:05 +01:00
parent 6a71fc9cbf
commit fe3fa9bf7c
3 changed files with 31 additions and 4 deletions

View File

@@ -40,6 +40,7 @@ private:
Expression * simplifyPowerMultiplication(Multiplication * m, Expression * r, Context & context, AngleUnit angleUnit);
Expression * simplifyRationalRationalPower(Expression * result, Rational * a, Rational * b, Context & context, AngleUnit angleUnit);
Expression * removeSquareRootsFromDenominator(Context & context, AngleUnit angleUnit);
bool parentIsALogarithmOfSameBase() const;
bool isNthRootOfUnity() const;
static Expression * CreateSimplifiedIntegerRationalPower(Integer i, Rational * r, bool isDenominator, Context & context, AngleUnit angleUnit);
static Expression * CreateNthRootOfUnity(const Rational r);

View File

@@ -201,6 +201,7 @@ Expression * Power::shallowReduce(Context& context, AngleUnit angleUnit) {
return replaceWith(CreateNthRootOfUnity(r))->shallowReduce(context, angleUnit);
}
}
bool letPowerAtRoot = parentIsALogarithmOfSameBase();
if (operand(0)->type() == Type::Rational) {
Rational * a = static_cast<Rational *>(editableOperand(0));
// 0^x
@@ -217,12 +218,12 @@ Expression * Power::shallowReduce(Context& context, AngleUnit angleUnit) {
return replaceWith(new Rational(1), true);
}
// p^q with p, q rationals
if (operand(1)->type() == Type::Rational) {
if (!letPowerAtRoot && operand(1)->type() == Type::Rational) {
return simplifyRationalRationalPower(this, a, static_cast<Rational *>(editableOperand(1)), context, angleUnit);
}
}
// e^(i*Pi*r) with r rational
if (isNthRootOfUnity()) {
if (!letPowerAtRoot && isNthRootOfUnity()) {
Expression * m = editableOperand(1);
detachOperand(m);
Expression * i = m->editableOperand(m->numberOfOperands()-1);
@@ -264,7 +265,7 @@ Expression * Power::shallowReduce(Context& context, AngleUnit angleUnit) {
}
}
// (a*b*c*...)^r ?
if (operand(0)->type() == Type::Multiplication) {
if (!letPowerAtRoot && operand(0)->type() == Type::Multiplication) {
Multiplication * m = static_cast<Multiplication *>(editableOperand(0));
// (a*b*c*...)^n = a^n*b^n*c^n*... if n integer
if (operand(1)->type() == Type::Rational && static_cast<Rational *>(editableOperand(1))->denominator().isOne()) {
@@ -295,7 +296,7 @@ Expression * Power::shallowReduce(Context& context, AngleUnit angleUnit) {
}
}
// a^(b+c) -> Rational(a^b)*a^c with a and b rational
if (operand(0)->type() == Type::Rational && operand(1)->type() == Type::Addition) {
if (!letPowerAtRoot && operand(0)->type() == Type::Rational && operand(1)->type() == Type::Addition) {
Addition * a = static_cast<Addition *>(editableOperand(1));
// Check is b is rational
if (a->operand(0)->type() == Type::Rational) {
@@ -311,6 +312,27 @@ Expression * Power::shallowReduce(Context& context, AngleUnit angleUnit) {
return this;
}
bool Power::parentIsALogarithmOfSameBase() const {
if (parent()->type() == Type::Logarithm && parent()->operand(0) == this) {
// parent = log(10^x)
if (parent()->numberOfOperands() == 1) {
if (operand(0)->type() == Type::Rational && static_cast<const Rational *>(operand(0))->isTen()) {
return true;
}
return false;
}
// parent = log(x^y,x)
if (operand(0)->isIdenticalTo(parent()->operand(1))) {
return true;
}
}
// parent = ln(e^x)
if (parent()->type() == Type::NaperianLogarithm && parent()->operand(0) == this && operand(0)->type() == Type::Symbol && static_cast<const Symbol *>(operand(0))->name() == Ion::Charset::Exponential) {
return true;
}
return false;
}
Expression * Power::simplifyPowerPower(Power * p, Expression * e, Context& context, AngleUnit angleUnit) {
Expression * p0 = p->editableOperand(0);
Expression * p1 = p->editableOperand(1);

View File

@@ -483,6 +483,10 @@ QUIZ_CASE(poincare_simplify_easy) {
assert_parsed_expression_simplify_to("X^ln(PX)", "PX");
assert_parsed_expression_simplify_to("X^log(PX)", "X^(log(P)+log(X))");
assert_parsed_expression_simplify_to("R(X^2)", "X");
assert_parsed_expression_simplify_to("ln(X^(IP/7))", "IP/7");
assert_parsed_expression_simplify_to("log(10^24)", "24");
assert_parsed_expression_simplify_to("log((23P)^4,23P)", "4");
assert_parsed_expression_simplify_to("log(10^(2+P))", "2+P");
/* This does not work but should not as it is above k_primorial32 = 1*3*5*7*11*... (product of first 32 primes. */
//assert_parsed_expression_simplify_to("1881676377434183981909562699940347954480361860897069^(1/3)", "123456789123456789");