mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-25 00:30:46 +01:00
[poincare] Power
This commit is contained in:
@@ -6,6 +6,7 @@ objs += $(addprefix poincare/src/,\
|
||||
addition.o\
|
||||
matrix_complex.o\
|
||||
multiplication.o\
|
||||
power.o\
|
||||
tree_node.o\
|
||||
tree_pool.o\
|
||||
tree_by_reference.o\
|
||||
|
||||
@@ -17,8 +17,6 @@ public:
|
||||
Expression complexToExpression(Preferences::Preferences::ComplexFormat complexFormat) const override { return Undefined(); }
|
||||
std::complex<U> trace() const override { return std::complex<U>(NAN); }
|
||||
std::complex<U> determinant() const override { return std::complex<U>(NAN); }
|
||||
Evaluation<U> inverse() const override { return Complex<U>::Undefined(); }
|
||||
virtual Evaluation<U> transpose() const override { return Complex<U>::Undefined(); }
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(AllocationFailureEvaluationNode<T, U>); }
|
||||
#if TREE_LOG
|
||||
|
||||
@@ -27,8 +27,6 @@ public:
|
||||
Expression complexToExpression(Preferences::Preferences::ComplexFormat complexFormat) const override;
|
||||
std::complex<T> trace() const override { return *this; }
|
||||
std::complex<T> determinant() const override { return *this; }
|
||||
Evaluation<T> inverse() const override;
|
||||
Evaluation<T> transpose() const override { return Complex<T>(*this); }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
||||
@@ -31,8 +31,6 @@ public:
|
||||
virtual Expression complexToExpression(Preferences::ComplexFormat complexFormat) const = 0;
|
||||
virtual std::complex<T> trace() const = 0;
|
||||
virtual std::complex<T> determinant() const = 0;
|
||||
virtual Evaluation<T> inverse() const = 0;
|
||||
virtual Evaluation<T> transpose() const = 0;
|
||||
|
||||
// TreeNode
|
||||
static TreeNode * FailedAllocationStaticNode();
|
||||
@@ -56,8 +54,6 @@ public:
|
||||
Expression complexToExpression(Preferences::ComplexFormat complexFormat) const;
|
||||
std::complex<T> trace() const { return node()->trace(); }
|
||||
std::complex<T> determinant() const { return node()->determinant(); }
|
||||
Evaluation inverse() const { return node()->inverse(); }
|
||||
Evaluation transpose() const { return node()->transpose(); }
|
||||
protected:
|
||||
Evaluation(EvaluationNode<T> * n) : TreeByValue(n) {}
|
||||
//Evaluation() : TreeByValue() {}
|
||||
|
||||
@@ -23,6 +23,7 @@ class Expression : public TreeByValue {
|
||||
friend class Division;
|
||||
friend class NAryExpressionNode;
|
||||
friend class Parenthesis;
|
||||
friend class Power;
|
||||
public:
|
||||
/* Constructor & Destructor */
|
||||
Expression() : Expression(nullptr) {}
|
||||
@@ -133,7 +134,7 @@ protected:
|
||||
|
||||
private:
|
||||
/* Properties */
|
||||
int getPolynomialCoefficients(char symbolName, Expression coefficients[], Context & context, Preferences::AngleUnit angleUnit) const;
|
||||
int getPolynomialCoefficients(char symbolName, Expression coefficients[]) const;
|
||||
|
||||
/* Simplification */
|
||||
Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit) const;
|
||||
|
||||
@@ -14,9 +14,10 @@ namespace Poincare {
|
||||
* 'this' outdated. They should only be called in a wrapper on Expression. */
|
||||
|
||||
class ExpressionNode : public TreeNode, public SerializationHelperInterface {
|
||||
friend class SymbolNode;
|
||||
friend class DivisionNode;
|
||||
friend class NAryExpressionNode;
|
||||
friend class PowerNode;
|
||||
friend class SymbolNode;
|
||||
public:
|
||||
enum class Type : uint8_t {
|
||||
AllocationFailure = 0,
|
||||
|
||||
@@ -41,8 +41,8 @@ public:
|
||||
Expression complexToExpression(Preferences::Preferences::ComplexFormat complexFormat) const override;
|
||||
std::complex<T> trace() const override;
|
||||
std::complex<T> determinant() const override;
|
||||
Evaluation<T> inverse() const override;
|
||||
Evaluation<T> transpose() const override;
|
||||
MatrixComplex<T> inverse() const;
|
||||
MatrixComplex<T> transpose() const;
|
||||
private:
|
||||
int m_numberOfRows;
|
||||
int m_numberOfColumns;
|
||||
@@ -65,6 +65,7 @@ public:
|
||||
return MatrixComplex<T>((std::complex<T> *)&undef, 1, 1);
|
||||
}
|
||||
static MatrixComplex<T> createIdentity(int dim);
|
||||
MatrixComplex<T> inverse() const { return node()->inverse(); }
|
||||
Complex<T> complexAtIndex(int index) {
|
||||
return Complex<T>(node()->complexAtIndex(index));
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
#define POINCARE_POWER_H
|
||||
|
||||
#include <poincare/approximation_helper.h>
|
||||
#include <poincare/rational.h>
|
||||
#include <poincare/multiplication.h>
|
||||
#include <poincare/char_layout_node.h>
|
||||
#include <poincare/rational.h>
|
||||
#include <poincare/serialization_helper.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -19,14 +19,14 @@ public:
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(PowerNode); }
|
||||
#if TREE_LOG
|
||||
const char * description() const override { return "Division"; }
|
||||
const char * description() const override { return "Power"; }
|
||||
#endif
|
||||
int numberOfChildren() const override { return 2; }
|
||||
|
||||
// Properties
|
||||
virtual Type type() const override { return Type::Power; }
|
||||
virtual Sign sign() const override;
|
||||
virtual Expression setSign(Sign s, Context & context, Preferences::AngleUnit angleUnit) const override;
|
||||
Type type() const override { return Type::Power; }
|
||||
Sign sign() const override;
|
||||
Expression setSign(Sign s, Context & context, Preferences::AngleUnit angleUnit) const override;
|
||||
|
||||
int polynomialDegree(char symbolName) const override;
|
||||
int getPolynomialCoefficients(char symbolName, Expression coefficients[]) const override;
|
||||
@@ -36,23 +36,25 @@ private:
|
||||
constexpr static int k_maxNumberOfTermsInExpandedMultinome = 25;
|
||||
constexpr static int k_maxExactPowerMatrix = 100;
|
||||
|
||||
/* Layout */
|
||||
// Layout
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
|
||||
/* Serialize */
|
||||
// Serialize
|
||||
bool needsParenthesesWithParent(const SerializationHelperInterface * parent) const override;
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
return SerializationHelper::Infix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, name());
|
||||
}
|
||||
static const char * name() { return "^"; }
|
||||
|
||||
/* Simplify */
|
||||
Expression shallowReduce(Context& context, Preferences::AngleUnit angleUnit) const override;
|
||||
Expression * shallowBeautify(Context & context, Preferences::AngleUnit angleUnit) const override;
|
||||
int simplificationOrderGreaterType(const Expression * e, bool canBeInterrupted) const override;
|
||||
Expression shallowBeautify(Context & context, Preferences::AngleUnit angleUnit) const override;
|
||||
int simplificationOrderGreaterType(const ExpressionNode * e, bool canBeInterrupted) const override;
|
||||
int simplificationOrderSameType(const ExpressionNode * e, bool canBeInterrupted) const override;
|
||||
Expression * simplifyPowerPower(Power * p, Expression * r, Context & context, Preferences::AngleUnit angleUnit);
|
||||
Expression * denominator(Context & context, Preferences::AngleUnit angleUnit) const override;
|
||||
Expression * simplifyPowerMultiplication(Multiplication * m, Expression * r, Context & context, Preferences::AngleUnit angleUnit);
|
||||
Expression denominator(Context & context, Preferences::AngleUnit angleUnit) const override;
|
||||
#if 0
|
||||
Expression * simplifyPowerPower(Power * p, Expression * r, Context & context, Preferences::AngleUnit angleUnit);
|
||||
Expression * simplifyPowerMultiplication(Multiplication * m, Expression * r, Context & context, Preferences::AngleUnit angleUnit);
|
||||
Expression * simplifyRationalRationalPower(Expression * result, Rational * a, Rational * b, Context & context, Preferences::AngleUnit angleUnit);
|
||||
Expression * removeSquareRootsFromDenominator(Context & context, Preferences::AngleUnit angleUnit);
|
||||
bool parentIsALogarithmOfSameBase() const;
|
||||
@@ -63,6 +65,7 @@ private:
|
||||
static const Rational * RadicandInExpression(const Expression * e);
|
||||
static const Rational * RationalFactorInExpression(const Expression * e);
|
||||
static bool RationalExponentShouldNotBeReduced(const Rational * b, const Rational * r);
|
||||
#endif
|
||||
/* Evaluation */
|
||||
constexpr static int k_maxApproximatePowerMatrix = 1000;
|
||||
template<typename T> static MatrixComplex<T> computeOnComplexAndMatrix(const std::complex<T> c, const MatrixComplex<T> n);
|
||||
@@ -80,10 +83,10 @@ class Power : public Expression {
|
||||
public:
|
||||
Power(Expression base, Expression exponent);
|
||||
Power(const PowerNode * n) : Expression(n) {}
|
||||
Expression setSign(Sign s, Context & context, Preferences::AngleUnit angleUnit) const;
|
||||
Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit) const;
|
||||
Expression * shallowBeautify(Context & context, Preferences::AngleUnit angleUnit) const;
|
||||
Expression setSign(ExpressionNode::Sign s, Context & context, Preferences::AngleUnit angleUnit) const;
|
||||
int getPolynomialCoefficients(char symbolName, Expression coefficients[]) const;
|
||||
Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit) const;
|
||||
Expression shallowBeautify(Context & context, Preferences::AngleUnit angleUnit) const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -47,12 +47,8 @@ template<typename T> Complex<T> DivisionNode::compute(const std::complex<T> c, c
|
||||
}
|
||||
|
||||
template<typename T> MatrixComplex<T> DivisionNode::computeOnComplexAndMatrix(const std::complex<T> c, const MatrixComplex<T> n) {
|
||||
Evaluation<T> inverse = n.inverse();
|
||||
if (inverse.isUndefined()) {
|
||||
return MatrixComplex<T>::Undefined();
|
||||
}
|
||||
assert(inverse.node()->type() == EvaluationNode<T>::Type::MatrixComplex || inverse.node()->type() == EvaluationNode<T>::Type::AllocationFailure);
|
||||
MatrixComplex<T> result = MultiplicationNode::computeOnComplexAndMatrix<T>(c, MatrixComplex<T>(static_cast<MatrixComplexNode<T> *>(inverse.node())));
|
||||
MatrixComplex<T> inverse = n.inverse();
|
||||
MatrixComplex<T> result = MultiplicationNode::computeOnComplexAndMatrix<T>(c, inverse);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -60,12 +56,8 @@ template<typename T> MatrixComplex<T> DivisionNode::computeOnMatrices(const Matr
|
||||
if (m.numberOfColumns() != n.numberOfColumns()) {
|
||||
return MatrixComplex<T>::Undefined();
|
||||
}
|
||||
Evaluation<T> inverse = n.inverse();
|
||||
if (inverse.isUndefined()) {
|
||||
return MatrixComplex<T>::Undefined();
|
||||
}
|
||||
assert(inverse.node()->type() == EvaluationNode<T>::Type::MatrixComplex || inverse.node()->type() == EvaluationNode<T>::Type::AllocationFailure);
|
||||
MatrixComplex<T> result = MultiplicationNode::computeOnMatrices<T>(m, MatrixComplex<T>(static_cast<MatrixComplexNode<T> *>(inverse.node())));
|
||||
MatrixComplex<T> inverse = n.inverse();
|
||||
MatrixComplex<T> result = MultiplicationNode::computeOnMatrices<T>(m, inverse);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ std::complex<T> MatrixComplexNode<T>::determinant() const {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Evaluation<T> MatrixComplexNode<T>::inverse() const {
|
||||
MatrixComplex<T> MatrixComplexNode<T>::inverse() const {
|
||||
/* TODO if (numberOfRows() != numberOfColumns() || numberOfChildren() == 0 || numberOfChildren() > Matrix::k_maxNumberOfCoefficients) {
|
||||
return MatrixComplex<T>::Undefined();
|
||||
}
|
||||
@@ -110,7 +110,7 @@ Evaluation<T> MatrixComplexNode<T>::inverse() const {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Evaluation<T> MatrixComplexNode<T>::transpose() const {
|
||||
MatrixComplex<T> MatrixComplexNode<T>::transpose() const {
|
||||
// Intentionally swapping dimensions for transpose
|
||||
MatrixComplex<T> result;
|
||||
for (int i = 0; i < numberOfRows(); i++) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user