From 376d9ef9a227519dec4fb3aed51c96edde8b5e1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Fri, 20 Apr 2018 11:46:31 +0200 Subject: [PATCH] [poincare] Improve the transformation from complex to expression to avoid complex(1, 0) -> Addition(Decimal(1), Multiplcation(Decimal(0), Symbol(I))) --- poincare/src/expression.cpp | 63 +++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/poincare/src/expression.cpp b/poincare/src/expression.cpp index 8c8363134..60f90babb 100644 --- a/poincare/src/expression.cpp +++ b/poincare/src/expression.cpp @@ -15,7 +15,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -836,12 +838,69 @@ template Expression * Expression::complexToExpression(std::complexcomplexFormat(); } + if (std::isnan(c.real()) || std::isnan(c.imag()) || std::isinf(c.real()) || std::isinf(c.imag())) { + return new Undefined(); + } + switch (complexFormat) { case ComplexFormat::Cartesian: - return new Addition(CreateDecimal(c.real()), new Multiplication(new Symbol(Ion::Charset::IComplex), CreateDecimal(c.imag()), false), false); + { + Expression * real = nullptr; + Expression * imag = nullptr; + if (c.real() != 0 || c.imag() == 0) { + real = CreateDecimal(c.real()); + } + if (c.imag() != 0) { + if (c.imag() == 1.0 || c.imag() == -1) { + imag = new Symbol(Ion::Charset::IComplex); + } else if (c.imag() > 0) { + imag = new Multiplication(CreateDecimal(c.imag()), new Symbol(Ion::Charset::IComplex), false); + } else { + imag = new Multiplication(CreateDecimal(-c.imag()), new Symbol(Ion::Charset::IComplex), false); + } + } + if (imag == nullptr) { + return real; + } else if (real == nullptr) { + if (c.imag() > 0) { + return imag; + } else { + return new Opposite(imag, false); + } + return imag; + } else if (c.imag() > 0) { + return new Addition(real, imag, false); + } else { + return new Subtraction(real, imag, false); + } + } default: + { assert(complexFormat == ComplexFormat::Polar); - return new Multiplication(CreateDecimal(std::abs(c)), new Power(new Symbol(Ion::Charset::Exponential), new Multiplication(new Symbol(Ion::Charset::IComplex), CreateDecimal(std::arg(c)), false), false), false); + Expression * norm = nullptr; + Expression * exp = nullptr; + T r = std::abs(c); + T th = std::arg(c); + if (r != 1 || th == 0) { + norm = CreateDecimal(r); + } + if (r != 0 && th != 0) { + Expression * arg = nullptr; + if (th > 0) { + arg = new Multiplication(CreateDecimal(th), new Symbol(Ion::Charset::IComplex), false); + } else { + arg = new Opposite(new Multiplication(CreateDecimal(-th), new Symbol(Ion::Charset::IComplex), false), false); + } + exp = new Power(new Symbol(Ion::Charset::Exponential), arg, false); + } + if (exp == nullptr) { + return norm; + } else if (norm == nullptr) { + return exp; + } else { + return new Multiplication(norm, exp, false); + } + } } }