Merged upsilon-dev

This commit is contained in:
Laury
2022-04-26 12:48:52 +02:00
2 changed files with 39 additions and 4 deletions

View File

@@ -44,11 +44,46 @@ Expression SquareRoot::shallowReduce(ExpressionNode::ReductionContext reductionC
return e;
}
}
Expression c = childAtIndex(0);
if (c.deepIsMatrix(reductionContext.context())) {
Expression child = childAtIndex(0);
if (child.deepIsMatrix(reductionContext.context())) {
return replaceWithUndefinedInPlace();
}
Power p = Power::Builder(c, Rational::Builder(1, 2));
// Test if we are in a case like sqrt(a +- sqrt(b)) where a and b are rational
if (child.type() == ExpressionNode::Type::Addition && child.numberOfChildren() == 2) {
bool subtraction = child.numberOfChildren() == 2 && child.childAtIndex(1).type() == ExpressionNode::Type::Multiplication && child.childAtIndex(1).numberOfChildren() == 2 && child.childAtIndex(1).childAtIndex(0).type() == ExpressionNode::Type::Rational && child.childAtIndex(1).childAtIndex(0).sign(reductionContext.context()) == ExpressionNode::Sign::Negative;
Expression a = child.childAtIndex(0);
Expression b = subtraction && child.childAtIndex(1).childAtIndex(0).convert<Rational>().isMinusOne() ? child.childAtIndex(1).childAtIndex(1) : child.childAtIndex(1);
// If root have been simplified in x * sqrt(y), we say that b is sqrt(x^2 * y)
if (b.type() == ExpressionNode::Type::Multiplication && b.numberOfChildren() == 2 && b.childAtIndex(0).type() == ExpressionNode::Type::Rational && b.childAtIndex(0).type() == ExpressionNode::Type::Rational && b.childAtIndex(1).type() == ExpressionNode::Type::Power && b.childAtIndex(1).childAtIndex(0).type() == ExpressionNode::Type::Rational && b.childAtIndex(1).childAtIndex(1).type() == ExpressionNode::Type::Rational && b.childAtIndex(1).childAtIndex(1).convert<Rational>().isHalf()) {
b = Power::Builder(Multiplication::Builder(Power::Builder(b.childAtIndex(0).clone(), Rational::Builder(2, 1)).shallowReduce(reductionContext), b.childAtIndex(1).childAtIndex(0).clone()).shallowReduce(reductionContext), Rational::Builder(1, 2));
}
if (a.type() == ExpressionNode::Type::Rational && b.type() == ExpressionNode::Type::Power && b.childAtIndex(0).type() == ExpressionNode::Type::Rational && b.childAtIndex(1).type() == ExpressionNode::Type::Rational && b.childAtIndex(1).convert<Rational>().isHalf()) {
Expression a0 = a.clone();
Expression a1 = b.childAtIndex(0).clone();
// There is a simplification (wikipedia)
Expression rr = Subtraction::Builder(Power::Builder(a0, Rational::Builder(2, 1)).shallowReduce(reductionContext), a1).shallowReduce(reductionContext);
if (a0.sign(reductionContext.context()) != ExpressionNode::Sign::Negative && rr.sign(reductionContext.context()) != ExpressionNode::Sign::Negative) {
Expression r = Power::Builder(rr, Rational::Builder(1, 2)).shallowReduce(reductionContext);
if (r.type() == ExpressionNode::Type::Rational) {
Expression c = Division::Builder(Addition::Builder(a0.clone(), r.clone()).shallowReduce(reductionContext), Rational::Builder(2, 1)).shallowReduce(reductionContext);
Expression d = Division::Builder(Subtraction::Builder(a0.clone(), r.clone()).shallowReduce(reductionContext), Rational::Builder(2, 1)).shallowReduce(reductionContext);
Expression result;
if (subtraction) {
result = Subtraction::Builder(Power::Builder(c, Rational::Builder(1, 2)).shallowReduce(reductionContext), Power::Builder(d, Rational::Builder(1, 2)).shallowReduce(reductionContext));
} else {
result = Addition::Builder(Power::Builder(c, Rational::Builder(1, 2)).shallowReduce(reductionContext), Power::Builder(d, Rational::Builder(1, 2)).shallowReduce(reductionContext));
}
replaceWithInPlace(result);
return result.shallowReduce(reductionContext);
}
}
}
}
Power p = Power::Builder(child, Rational::Builder(1, 2));
replaceWithInPlace(p);
return p.shallowReduce(reductionContext);
}