mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-20 01:08:15 +01:00
[poincare] Implement shallowReduce of ComplexArgument, AbsoluteValue,
RealPart and ImaginaryPart
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user