mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-19 05:40:38 +01:00
[poincare] Move 'complexToExpression' to Evaluation class
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#define POINCARE_APPROXIMATION_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/evaluation.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef POINCARE_BINOMIAL_COEFFICIENT_H
|
||||
#define POINCARE_BINOMIAL_COEFFICIENT_H
|
||||
|
||||
#include <poincare/evaluation.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ namespace Poincare {
|
||||
*/
|
||||
|
||||
class Decimal : public StaticHierarchy<0> {
|
||||
friend class Expression;
|
||||
public:
|
||||
static int exponent(const char * integralPart, int integralPartLength, const char * fractionalPart, int fractionalPartLength, const char * exponent, int exponentLength, bool exponentNegative);
|
||||
static Integer mantissa(const char * integralPart, int integralPartLength, const char * fractionalPart, int fractionalPartLength, bool negative);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
extern "C" {
|
||||
#include <stdint.h>
|
||||
}
|
||||
#include <poincare/expression.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -29,6 +30,7 @@ public:
|
||||
virtual ~Evaluation() {}
|
||||
virtual bool isUndefined() const = 0;
|
||||
virtual T toScalar() const { return NAN; }
|
||||
virtual Expression * complexToExpression(Expression::ComplexFormat complexFormat) const = 0;
|
||||
virtual std::complex<T> createTrace() const = 0;
|
||||
virtual std::complex<T> createDeterminant() const = 0;
|
||||
virtual Evaluation * createInverse() const = 0;
|
||||
@@ -59,6 +61,7 @@ public:
|
||||
return (std::isnan(this->real()) && std::isnan(this->imag()));
|
||||
}
|
||||
T toScalar() const override;
|
||||
Expression * complexToExpression(Expression::ComplexFormat complexFormat) const override;
|
||||
std::complex<T> createTrace() const override { return *this; }
|
||||
std::complex<T> createDeterminant() const override { return *this; }
|
||||
Complex<T> * createInverse() const override;
|
||||
@@ -97,6 +100,7 @@ public:
|
||||
bool isUndefined() const override {
|
||||
return (numberOfRows() == 1 && numberOfColumns() == 1 && std::isnan(complexOperand(0).real()) && std::isnan(complexOperand(0).imag()));
|
||||
}
|
||||
Expression * complexToExpression(Expression::ComplexFormat complexFormat) const override;
|
||||
std::complex<T> createTrace() const override;
|
||||
std::complex<T> createDeterminant() const override;
|
||||
MatrixComplex<T> * createInverse() const override;
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#include <poincare/expression_layout.h>
|
||||
#include <poincare/print_float.h>
|
||||
#include <poincare/evaluation.h>
|
||||
#include <complex>
|
||||
extern "C" {
|
||||
#include <assert.h>
|
||||
@@ -13,6 +12,7 @@ namespace Poincare {
|
||||
|
||||
class Context;
|
||||
class Rational;
|
||||
template<class T> class Evaluation;
|
||||
|
||||
class Expression {
|
||||
template<typename T> friend class Complex;
|
||||
@@ -326,8 +326,6 @@ private:
|
||||
return nullptr;
|
||||
}
|
||||
/* Evaluation Engine */
|
||||
template<typename T> static Expression * CreateDecimal(T f);
|
||||
template<typename T> static Expression * complexToExpression(std::complex<T> c, ComplexFormat complexFormat);
|
||||
virtual Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const = 0;
|
||||
virtual Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const = 0;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define POINCARE_GREAT_COMMON_DIVISOR_H
|
||||
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/evaluation.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define POINCARE_RANDOM_H
|
||||
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <poincare/symbol.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/evaluation.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
|
||||
@@ -7,6 +7,16 @@ extern "C" {
|
||||
#include <poincare/division.h>
|
||||
#include <poincare/matrix.h>
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/undefined.h>
|
||||
#include <poincare/decimal.h>
|
||||
#include <poincare/multiplication.h>
|
||||
#include <poincare/opposite.h>
|
||||
#include <poincare/addition.h>
|
||||
#include <poincare/subtraction.h>
|
||||
#include <poincare/matrix.h>
|
||||
#include <poincare/power.h>
|
||||
#include <poincare/symbol.h>
|
||||
#include <ion.h>
|
||||
#include <cmath>
|
||||
|
||||
namespace Poincare {
|
||||
@@ -19,6 +29,87 @@ T Complex<T>::toScalar() const {
|
||||
return NAN;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static Expression * CreateDecimal(T f) {
|
||||
if (std::isnan(f) || std::isinf(f)) {
|
||||
return new Undefined();
|
||||
}
|
||||
return new Decimal(f);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Expression * Complex<T>::complexToExpression(Expression::ComplexFormat complexFormat) const {
|
||||
if (std::isnan(this->real()) || std::isnan(this->imag()) || std::isinf(this->real()) || std::isinf(this->imag())) {
|
||||
return new Poincare::Undefined();
|
||||
}
|
||||
|
||||
switch (complexFormat) {
|
||||
case Expression::ComplexFormat::Cartesian:
|
||||
{
|
||||
Expression * real = nullptr;
|
||||
Expression * imag = nullptr;
|
||||
if (this->real() != 0 || this->imag() == 0) {
|
||||
real = CreateDecimal(this->real());
|
||||
}
|
||||
if (this->imag() != 0) {
|
||||
if (this->imag() == 1.0 || this->imag() == -1) {
|
||||
imag = new Symbol(Ion::Charset::IComplex);
|
||||
} else if (this->imag() > 0) {
|
||||
imag = new Multiplication(CreateDecimal(this->imag()), new Symbol(Ion::Charset::IComplex), false);
|
||||
} else {
|
||||
imag = new Multiplication(CreateDecimal(-this->imag()), new Symbol(Ion::Charset::IComplex), false);
|
||||
}
|
||||
}
|
||||
if (imag == nullptr) {
|
||||
return real;
|
||||
} else if (real == nullptr) {
|
||||
if (this->imag() > 0) {
|
||||
return imag;
|
||||
} else {
|
||||
return new Opposite(imag, false);
|
||||
}
|
||||
return imag;
|
||||
} else if (this->imag() > 0) {
|
||||
return new Addition(real, imag, false);
|
||||
} else {
|
||||
return new Subtraction(real, imag, false);
|
||||
}
|
||||
}
|
||||
default:
|
||||
{
|
||||
assert(complexFormat == Expression::ComplexFormat::Polar);
|
||||
Expression * norm = nullptr;
|
||||
Expression * exp = nullptr;
|
||||
T r = std::abs(*this);
|
||||
T th = std::arg(*this);
|
||||
if (r != 1 || th == 0) {
|
||||
norm = CreateDecimal(r);
|
||||
}
|
||||
if (r != 0 && th != 0) {
|
||||
Expression * arg = nullptr;
|
||||
if (th == 1.0) {
|
||||
arg = new Symbol(Ion::Charset::IComplex);
|
||||
} else if (th == -1.0) {
|
||||
arg = new Opposite(new Symbol(Ion::Charset::IComplex), false);
|
||||
} else 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
Complex<T> * Complex<T>::createInverse() const {
|
||||
return new Complex<T>(Division::compute(std::complex<T>(1.0), *this));
|
||||
@@ -81,6 +172,17 @@ MatrixComplex<T>::MatrixComplex(std::complex<T> * operands, int numberOfRows, in
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Expression * MatrixComplex<T>::complexToExpression(Expression::ComplexFormat complexFormat) const {
|
||||
Expression ** operands = new Expression * [numberOfComplexOperands()];
|
||||
for (int i = 0; i < numberOfComplexOperands(); i++) {
|
||||
operands[i] = Complex<T>(complexOperand(i)).complexToExpression(complexFormat);
|
||||
}
|
||||
Expression * result = new Matrix(operands, numberOfRows(), numberOfColumns(), false);
|
||||
delete[] operands;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::complex<T> MatrixComplex<T>::createTrace() const {
|
||||
if (numberOfRows() != numberOfColumns()) {
|
||||
|
||||
@@ -7,17 +7,10 @@
|
||||
#include <poincare/matrix_data.h>
|
||||
#include <poincare/undefined.h>
|
||||
#include <poincare/simplification_root.h>
|
||||
#include <poincare/rational.h>
|
||||
#include <poincare/matrix.h>
|
||||
#include <poincare/evaluation.h>
|
||||
#include <poincare/opposite.h>
|
||||
#include <poincare/variable_context.h>
|
||||
#include <poincare/decimal.h>
|
||||
#include <poincare/ieee754.h>
|
||||
#include <poincare/addition.h>
|
||||
#include <poincare/multiplication.h>
|
||||
#include <poincare/subtraction.h>
|
||||
#include <poincare/power.h>
|
||||
#include <poincare/opposite.h>
|
||||
#include <ion.h>
|
||||
#include <cmath>
|
||||
#include <float.h>
|
||||
@@ -420,19 +413,8 @@ Expression * Expression::deepBeautify(Context & context, AngleUnit angleUnit) {
|
||||
/* Evaluation */
|
||||
|
||||
template<typename T> Expression * Expression::approximate(Context& context, AngleUnit angleUnit, ComplexFormat complexFormat) const {
|
||||
Expression * result = nullptr;
|
||||
Evaluation<T> * e = privateApproximate(T(), context, angleUnit);
|
||||
if (e->type() == Evaluation<T>::Type::Complex) {
|
||||
result = complexToExpression(*(static_cast<Complex<T> *>(e)), complexFormat);
|
||||
} else {
|
||||
MatrixComplex<T> * matrix = static_cast<MatrixComplex<T> *>(e);
|
||||
Expression ** operands = new Expression * [matrix->numberOfComplexOperands()];
|
||||
for (int i = 0; i < matrix->numberOfComplexOperands(); i++) {
|
||||
operands[i] = complexToExpression(matrix->complexOperand(i), complexFormat);
|
||||
}
|
||||
result = new Matrix(operands, matrix->numberOfRows(), matrix->numberOfColumns(), false);
|
||||
delete[] operands;
|
||||
}
|
||||
Expression * result = e->complexToExpression(complexFormat);
|
||||
delete e;
|
||||
return result;
|
||||
}
|
||||
@@ -790,85 +772,6 @@ T Expression::approximateWithValueForSymbol(char symbol, T x, Context & context,
|
||||
return value;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Expression * Expression::CreateDecimal(T f) {
|
||||
if (std::isnan(f) || std::isinf(f)) {
|
||||
return new Undefined();
|
||||
}
|
||||
return new Decimal(f);
|
||||
}
|
||||
|
||||
template<typename T> Expression * Expression::complexToExpression(std::complex<T> c, ComplexFormat complexFormat) {
|
||||
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:
|
||||
{
|
||||
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);
|
||||
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 == 1.0) {
|
||||
arg = new Symbol(Ion::Charset::IComplex);
|
||||
} else if (th == -1.0) {
|
||||
arg = new Opposite(new Symbol(Ion::Charset::IComplex), false);
|
||||
} else 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template Poincare::Expression * Poincare::Expression::approximate<double>(Context& context, AngleUnit angleUnit, ComplexFormat complexFormat) const;
|
||||
|
||||
Reference in New Issue
Block a user