[poincare] Implement shallowReduce of ComplexArgument, AbsoluteValue,

RealPart and ImaginaryPart
This commit is contained in:
Émilie Feral
2018-12-07 16:51:15 +01:00
committed by Léa Saviot
parent 2f8ede54f2
commit 64aebcf16d
11 changed files with 44 additions and 28 deletions

View File

@@ -55,7 +55,7 @@ public:
static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); }
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("abs", 1, &UntypedBuilder);
Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit);
Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target);
private:
explicit AbsoluteValue(Expression child) : Expression(TreePool::sharedPool()->createTreeNode<AbsoluteValueNode>()) {
replaceChildAtIndexInPlace(0, child);

View File

@@ -47,7 +47,7 @@ public:
static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); }
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("arg", 1, &UntypedBuilder);
Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit);
Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target);
private:
explicit ComplexArgument(Expression child) : Expression(TreePool::sharedPool()->createTreeNode<ComplexArgumentNode>()) {
replaceChildAtIndexInPlace(0, child);

View File

@@ -50,7 +50,7 @@ public:
static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); }
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("im", 1, &UntypedBuilder);
Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit);
Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target);
private:
explicit ImaginaryPart(Expression child) : Expression(TreePool::sharedPool()->createTreeNode<ImaginaryPartNode>()) {
replaceChildAtIndexInPlace(0, child);

View File

@@ -50,7 +50,7 @@ public:
static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); }
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("re", 1, &UntypedBuilder);
Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit);
Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target);
private:
explicit RealPart(Expression child) : Expression(TreePool::sharedPool()->createTreeNode<RealPartNode>()) {
replaceChildAtIndexInPlace(0, child);

View File

@@ -3,6 +3,7 @@
#include <poincare/serialization_helper.h>
#include <poincare/simplification_helper.h>
#include <poincare/absolute_value_layout.h>
#include <poincare/multiplication.h>
#include <assert.h>
#include <cmath>
@@ -25,7 +26,7 @@ int AbsoluteValueNode::serialize(char * buffer, int bufferSize, Preferences::Pri
}
Expression AbsoluteValueNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, ReductionTarget target) {
return AbsoluteValue(this).shallowReduce(context, angleUnit);
return AbsoluteValue(this).shallowReduce(context, angleUnit, target);
}
Expression AbsoluteValue::setSign(ExpressionNode::Sign s, Context * context, Preferences::AngleUnit angleUnit) {
@@ -33,12 +34,11 @@ Expression AbsoluteValue::setSign(ExpressionNode::Sign s, Context * context, Pre
return *this;
}
Expression AbsoluteValue::shallowReduce(Context & context, Preferences::AngleUnit angleUnit) {
Expression AbsoluteValue::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) {
Expression e = Expression::defaultShallowReduce(context, angleUnit);
if (e.isUndefined()) {
return e;
}
Expression c = childAtIndex(0);
#if MATRIX_EXACT_REDUCING
#if 0
if (c->type() == Type::Matrix) {
@@ -46,14 +46,11 @@ Expression AbsoluteValue::shallowReduce(Context & context, Preferences::AngleUni
}
#endif
#endif
if (c.sign(&context, angleUnit) == ExpressionNode::Sign::Positive) {
replaceWithInPlace(c);
return c;
}
if (c.sign(&context, angleUnit) == ExpressionNode::Sign::Negative) {
Expression result = c.setSign(ExpressionNode::Sign::Positive, &context, angleUnit);
replaceWithInPlace(result);
return result;
Expression c = childAtIndex(0);
Expression norm = c.complexNorm(context, angleUnit);
if (!norm.isUninitialized()) {
replaceWithInPlace(norm);
return norm.deepReduce(context, angleUnit, target);
}
return *this;
}

View File

@@ -22,7 +22,7 @@ int ComplexArgumentNode::serialize(char * buffer, int bufferSize, Preferences::P
}
Expression ComplexArgumentNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, ReductionTarget target) {
return ComplexArgument(this).shallowReduce(context, angleUnit);
return ComplexArgument(this).shallowReduce(context, angleUnit, target);
}
template<typename T>
@@ -30,19 +30,24 @@ Complex<T> ComplexArgumentNode::computeOnComplex(const std::complex<T> c, Prefer
return Complex<T>(std::arg(c));
}
Expression ComplexArgument::shallowReduce(Context & context, Preferences::AngleUnit angleUnit) {
Expression ComplexArgument::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) {
{
Expression e = Expression::defaultShallowReduce(context, angleUnit);
if (e.isUndefined()) {
return e;
}
}
#if MATRIX_EXACT_REDUCING
Expression c = childAtIndex(0);
#if MATRIX_EXACT_REDUCING
if (c.type() == ExpressionNode::Type::Matrix) {
return SimplificationHelper::Map(*this, context, angleUnit);
}
#endif
Expression arg = c.complexArgument(context, angleUnit);
if (!arg.isUninitialized()) {
replaceWithInPlace(arg);
return arg.deepReduce(context, angleUnit, target);
}
return *this;
}

View File

@@ -109,7 +109,7 @@ Expression ExpressionNode::complexArgument(Context & context, Preferences::Angle
Multiplication(
SignFunction::Builder(b).shallowReduce(context, angleUnit),
Division(Constant(Ion::Charset::SmallPi), Rational(2)).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation)
),
).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation),
arcTangent
).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation);
} else {

View File

@@ -20,10 +20,10 @@ int ImaginaryPartNode::serialize(char * buffer, int bufferSize, Preferences::Pri
}
Expression ImaginaryPartNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, ReductionTarget target) {
return ImaginaryPart(this).shallowReduce(context, angleUnit);
return ImaginaryPart(this).shallowReduce(context, angleUnit, target);
}
Expression ImaginaryPart::shallowReduce(Context & context, Preferences::AngleUnit angleUnit) {
Expression ImaginaryPart::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) {
{
Expression e = Expression::defaultShallowReduce(context, angleUnit);
if (e.isUndefined()) {
@@ -41,6 +41,11 @@ Expression ImaginaryPart::shallowReduce(Context & context, Preferences::AngleUni
replaceWithInPlace(result);
return result;
}
Expression im = c.imaginaryPart(context, angleUnit);
if (!im.isUninitialized()) {
replaceWithInPlace(im);
return im.deepReduce(context, angleUnit, target);
}
return *this;
}

View File

@@ -20,10 +20,10 @@ int RealPartNode::serialize(char * buffer, int bufferSize, Preferences::PrintFlo
}
Expression RealPartNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, ReductionTarget target) {
return RealPart(this).shallowReduce(context, angleUnit);
return RealPart(this).shallowReduce(context, angleUnit, target);
}
Expression RealPart::shallowReduce(Context & context, Preferences::AngleUnit angleUnit) {
Expression RealPart::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) {
{
Expression e = Expression::defaultShallowReduce(context, angleUnit);
if (e.isUndefined()) {
@@ -40,6 +40,11 @@ Expression RealPart::shallowReduce(Context & context, Preferences::AngleUnit ang
replaceWithInPlace(c);
return c;
}
Expression re = c.realPart(context, angleUnit);
if (!re.isUninitialized()) {
replaceWithInPlace(re);
return re.deepReduce(context, angleUnit, target);
}
return *this;
}

View File

@@ -69,12 +69,12 @@ QUIZ_CASE(poincare_complex_parts) {
assert_expression_has_complex_cartesian_parts("I", "0", "1");
assert_expression_has_complex_cartesian_parts("abs(-3)", "3", "0");
assert_expression_has_complex_cartesian_parts("abs(-3+I)", "abs(-3+I)", "0");
assert_expression_has_complex_cartesian_parts("abs(-3+I)", "R(10)", "0");
assert_expression_has_complex_cartesian_parts("atan(2)", "atan(2)", "0");
assert_expression_has_complex_cartesian_parts("atan(2+I)", nullptr, nullptr);
assert_expression_has_complex_cartesian_parts("binomial(10, 4)", "210", "0");
assert_expression_has_complex_cartesian_parts("ceil(-1.3)", "-1", "0");
assert_expression_has_complex_cartesian_parts("arg(-2)", "arg(-2)", "0");
assert_expression_has_complex_cartesian_parts("arg(-2)", "P", "0");
// TODO: confidence is not simplified yet
//assert_expression_has_complex_cartesian_parts("confidence(-2,-3)", "confidence(-2)", "0");
assert_expression_has_complex_cartesian_parts("conj(-2)", "-2", "0");
@@ -87,7 +87,7 @@ QUIZ_CASE(poincare_complex_parts) {
assert_expression_has_complex_cartesian_parts("floor(x)", "floor(x)", "0");
assert_expression_has_complex_cartesian_parts("frac(x)", "frac(x)", "0");
assert_expression_has_complex_cartesian_parts("gcd(x,y)", "gcd(x,y)", "0");
assert_expression_has_complex_cartesian_parts("im(x)", "im(x)", "0");
assert_expression_has_complex_cartesian_parts("im(1+I)", "1", "0");
assert_expression_has_complex_cartesian_parts("int(x^2, x, 1, 2)", "int(x^2,x,1,2)", "0");
assert_expression_has_complex_cartesian_parts("lcm(x,y)", "lcm(x,y)", "0");
// TODO: dim is not simplified yet
@@ -101,7 +101,7 @@ QUIZ_CASE(poincare_complex_parts) {
//assert_expression_has_complex_cartesian_parts("prediction(-2,-3)", "prediction(-2)", "0");
assert_expression_has_complex_cartesian_parts("randint(2,4)", "randint(2,4)", "0");
assert_expression_has_complex_cartesian_parts("random()", "random()", "0");
assert_expression_has_complex_cartesian_parts("re(x)", "re(x)", "0");
assert_expression_has_complex_cartesian_parts("re(x)", "x", "0");
assert_expression_has_complex_cartesian_parts("round(x,y)", "round(x,y)", "0");
assert_expression_has_complex_cartesian_parts("sign(x)", "sign(x)", "0");
assert_expression_has_complex_cartesian_parts("sin(23)", "sin(23)", "0");
@@ -148,5 +148,5 @@ QUIZ_CASE(poincare_complex_parts) {
assert_expression_has_complex_polar_parts("P", "P", "0");
assert_expression_has_complex_polar_parts("I", "1", "P/2");
assert_expression_has_complex_polar_parts("abs(-3)", "3", "0");
assert_expression_has_complex_polar_parts("abs(-3+I)", "abs(-3+I)", "0");
assert_expression_has_complex_polar_parts("abs(-3+I)", "R(10)", "0");
}

View File

@@ -238,6 +238,8 @@ QUIZ_CASE(poincare_function_evaluate) {
QUIZ_CASE(poincare_function_simplify) {
assert_parsed_expression_simplify_to("abs(P)", "P");
assert_parsed_expression_simplify_to("abs(-P)", "P");
assert_parsed_expression_simplify_to("abs(1+I)", "R(2)");
assert_parsed_expression_simplify_to("arg(1+I)", "P/4");
assert_parsed_expression_simplify_to("binomial(20,3)", "1140");
assert_parsed_expression_simplify_to("binomial(20,10)", "184756");
assert_parsed_expression_simplify_to("ceil(-1.3)", "-1");
@@ -257,9 +259,11 @@ QUIZ_CASE(poincare_function_simplify) {
assert_parsed_expression_simplify_to("frac(-1.3)", "7/10");
assert_parsed_expression_simplify_to("gcd(123,278)", "1");
assert_parsed_expression_simplify_to("gcd(11,121)", "11");
assert_parsed_expression_simplify_to("im(1+5*I)", "5");
assert_parsed_expression_simplify_to("lcm(123,278)", "34194");
assert_parsed_expression_simplify_to("lcm(11,121)", "121");
assert_parsed_expression_simplify_to("R(4)", "2");
assert_parsed_expression_simplify_to("re(1+5*I)", "1");
assert_parsed_expression_simplify_to("root(4,3)", "root(4,3)");
assert_parsed_expression_simplify_to("root(4,P)", "4^(1/P)");
assert_parsed_expression_simplify_to("root(27,3)", "3");