mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[poincare] Implementation of shallowReduce for Complex: when replacing
the ans symbol, we might introduce a Complex expression in the input
This commit is contained in:
committed by
EmilieNumworks
parent
785c6a7329
commit
02b15035fa
@@ -14,6 +14,8 @@ class Addition : public DynamicHierarchy {
|
||||
friend class Multiplication;
|
||||
friend class Subtraction;
|
||||
friend class Power;
|
||||
friend class Complex<float>;
|
||||
friend class Complex<double>;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
|
||||
@@ -64,8 +64,8 @@ public:
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override;
|
||||
|
||||
/* Simplification: complex does not implement simplificationOrderSameType
|
||||
* because Complex expressions do not appear before evaluation. The sorting
|
||||
* step is part of simplificaiton process which thus handles no complex. */
|
||||
* because Complex expressions are always transformed into an addition of
|
||||
* Decimal and I symbol before compared with another Expression. */
|
||||
|
||||
/* The parameter 'DisplayMode' refers to the way to display float 'scientific'
|
||||
* or 'auto'. The scientific mode returns float with style -1.2E2 whereas
|
||||
@@ -81,7 +81,12 @@ public:
|
||||
static int convertFloatToText(T d, char * buffer, int bufferSize, int numberOfSignificantDigits, Expression::FloatDisplayMode mode = Expression::FloatDisplayMode::Default);
|
||||
private:
|
||||
Complex(T a, T b);
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(Expression::FloatDisplayMode floatDisplayMode, Expression::ComplexFormat complexFormat) const override;
|
||||
/* Simplification */
|
||||
static Expression * CreateDecimal(T f);
|
||||
Expression * shallowReduce(Context & context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Expression * privateApproximate(Expression::SinglePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Expression * privateApproximate(Expression::DoublePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename U> Complex<U> * templatedApproximate(Context& context, Expression::AngleUnit angleUnit) const;
|
||||
|
||||
@@ -75,6 +75,8 @@ class Expression {
|
||||
friend class ApproximationEngine;
|
||||
friend class SimplificationEngine;
|
||||
friend class LayoutEngine;
|
||||
friend class Complex<float>;
|
||||
friend class Complex<double>;
|
||||
|
||||
public:
|
||||
enum class Type : uint8_t {
|
||||
|
||||
@@ -16,6 +16,8 @@ class Multiplication : public DynamicHierarchy {
|
||||
friend class Power;
|
||||
friend class Subtraction;
|
||||
friend class Symbol;
|
||||
friend class Complex<float>;
|
||||
friend class Complex<double>;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
#include <poincare/complex.h>
|
||||
#include <poincare/undefined.h>
|
||||
#include <poincare/decimal.h>
|
||||
#include <poincare/addition.h>
|
||||
#include <poincare/multiplication.h>
|
||||
#include <poincare/symbol.h>
|
||||
extern "C" {
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
@@ -12,6 +17,17 @@ extern "C" {
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
template<typename T>
|
||||
int exponent(T f) {
|
||||
T logBase10 = f != 0 ? std::log10(std::fabs(f)) : 0;
|
||||
int exponentInBase10 = std::floor(logBase10);
|
||||
/* Correct the exponent in base 10: sometines the exact log10 of f is 6.999999
|
||||
* but is stored as 7 in hardware. We catch these cases here. */
|
||||
if (f != 0 && logBase10 == (int)logBase10 && std::fabs(f) < std::pow(10, logBase10)) {
|
||||
exponentInBase10--;
|
||||
}
|
||||
return exponentInBase10;
|
||||
}
|
||||
|
||||
void PrintFloat::printBase10IntegerWithDecimalMarker(char * buffer, int bufferLength, Integer i, int decimalMarkerPosition) {
|
||||
/* The decimal marker position is always preceded by a char, thus, it is never
|
||||
@@ -243,6 +259,28 @@ ExpressionLayout * Complex<T>::privateCreateLayout(Expression::FloatDisplayMode
|
||||
return createCartesianLayout(floatDisplayMode);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
Expression * Complex<T>::CreateDecimal(T f) {
|
||||
if (std::isnan(f) || std::isinf(f)) {
|
||||
return new Undefined();
|
||||
}
|
||||
int e = exponent(f);
|
||||
int64_t mantissaf = f * std::pow((T)10, -e+PrintFloat::k_numberOfStoredSignificantDigits+1);
|
||||
return new Decimal(Integer(mantissaf), e);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
Expression * Complex<T>::shallowReduce(Context & context, AngleUnit angleUnit) {
|
||||
Expression * a = CreateDecimal(m_a);
|
||||
Expression * b = CreateDecimal(m_b);
|
||||
Multiplication * m = new Multiplication(new Symbol(Ion::Charset::IComplex), b, false);
|
||||
Addition * add = new Addition(a, m, false);
|
||||
a->shallowReduce(context, angleUnit);
|
||||
b->shallowReduce(context, angleUnit);
|
||||
m->shallowReduce(context, angleUnit);
|
||||
return replaceWith(add, true)->shallowReduce(context, angleUnit);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
Complex<U> * Complex<T>::templatedApproximate(Context& context, Expression::AngleUnit angleUnit) const {
|
||||
@@ -333,13 +371,7 @@ int Complex<T>::convertFloatToTextPrivate(T f, char * buffer, int numberOfSignif
|
||||
return currentChar;
|
||||
}
|
||||
|
||||
T logBase10 = f != 0 ? std::log10(std::fabs(f)) : 0;
|
||||
int exponentInBase10 = std::floor(logBase10);
|
||||
/* Correct the exponent in base 10: sometines the exact log10 of f is 6.999999
|
||||
* but is stored as 7 in hardware. We catch these cases here. */
|
||||
if (f != 0 && logBase10 == (int)logBase10 && std::fabs(f) < std::pow(10, logBase10)) {
|
||||
exponentInBase10--;
|
||||
}
|
||||
int exponentInBase10 = exponent(f);
|
||||
|
||||
Expression::FloatDisplayMode displayMode = mode;
|
||||
if ((exponentInBase10 >= numberOfSignificantDigits || exponentInBase10 <= -numberOfSignificantDigits) && mode == Expression::FloatDisplayMode::Decimal) {
|
||||
|
||||
Reference in New Issue
Block a user