Merge changes I54fed14f,I8de07359,Ic95a0400

* changes:
  [poincare] Parse approximation functions (floor, ceil, frac, round)
  [poincare] Parse trace(matrix) and dim(matrix)
  [poincare] fix typo
This commit is contained in:
Émilie Feral
2017-03-16 16:38:24 +01:00
committed by Gerrit
19 changed files with 416 additions and 3 deletions

View File

@@ -7,6 +7,7 @@ objs += $(addprefix poincare/src/,\
addition.o\
binary_operation.o\
binomial_coefficient.o\
ceiling.o\
complex.o\
complex_argument.o\
conjugate.o\
@@ -18,6 +19,8 @@ objs += $(addprefix poincare/src/,\
expression.o\
expression_lexer.o\
expression_parser.o\
floor.o\
frac_part.o\
fraction.o\
function.o\
global_context.o\
@@ -34,7 +37,9 @@ objs += $(addprefix poincare/src/,\
logarithm.o\
matrix.o\
matrix_data.o\
matrix_dimension.o\
matrix_inverse.o\
matrix_trace.o\
matrix_transpose.o\
multiplication.o\
naperian_logarithm.o\
@@ -46,6 +51,7 @@ objs += $(addprefix poincare/src/,\
preferences.o\
product.o\
reel_part.o\
round.o\
sine.o\
square_root.o\
subtraction.o\

View File

@@ -4,6 +4,7 @@
#include <poincare/absolute_value.h>
#include <poincare/addition.h>
#include <poincare/binomial_coefficient.h>
#include <poincare/ceiling.h>
#include <poincare/complex.h>
#include <poincare/complex_argument.h>
#include <poincare/conjugate.h>
@@ -14,6 +15,8 @@
#include <poincare/division_quotient.h>
#include <poincare/division_remainder.h>
#include <poincare/expression.h>
#include <poincare/floor.h>
#include <poincare/frac_part.h>
#include <poincare/fraction.h>
#include <poincare/function.h>
#include <poincare/global_context.h>
@@ -24,12 +27,12 @@
#include <poincare/integer.h>
#include <poincare/imaginary_part.h>
#include <poincare/integral.h>
#include <poincare/list_data.h>
#include <poincare/least_common_multiple.h>
#include <poincare/logarithm.h>
#include <poincare/matrix.h>
#include <poincare/matrix_data.h>
#include <poincare/matrix_dimension.h>
#include <poincare/matrix_inverse.h>
#include <poincare/matrix_trace.h>
#include <poincare/matrix_transpose.h>
#include <poincare/multiplication.h>
#include <poincare/naperian_logarithm.h>
@@ -41,6 +44,7 @@
#include <poincare/preferences.h>
#include <poincare/product.h>
#include <poincare/reel_part.h>
#include <poincare/round.h>
#include <poincare/sine.h>
#include <poincare/square_root.h>
#include <poincare/subtraction.h>

View File

@@ -0,0 +1,22 @@
#ifndef POINCARE_CEILING_H
#define POINCARE_CEILING_H
#include <poincare/function.h>
namespace Poincare {
class Ceiling : public Function {
public:
Ceiling();
Type type() const override;
Expression * cloneWithDifferentOperands(Expression ** newOperands,
int numberOfOperands, bool cloneOperands = true) const override;
private:
float privateApproximate(Context & context, AngleUnit angleUnit) const override;
};
}
#endif

View File

@@ -14,6 +14,7 @@ public:
AbsoluteValue,
Addition,
BinomialCoefficient,
Ceiling,
Complex,
ComplexArgument,
Conjugate,
@@ -23,6 +24,8 @@ public:
DivisionQuotient,
DivisionRemainder,
Float,
Floor,
FracPart,
GreatCommonDivisor,
HyperbolicCosine,
HyperbolicSine,
@@ -33,7 +36,9 @@ public:
Logarithm,
LeastCommonMultiple,
Matrix,
MatrixDimension,
MatrixInverse,
MatrixTrace,
MatrixTranspose,
Multiplication,
NaperianLogarithm,
@@ -45,6 +50,7 @@ public:
Power,
Product,
ReelPart,
Round,
Sine,
SquareRoot,
Sum,

View File

@@ -0,0 +1,22 @@
#ifndef POINCARE_FLOOR_H
#define POINCARE_FLOOR_H
#include <poincare/function.h>
namespace Poincare {
class Floor : public Function {
public:
Floor();
Type type() const override;
Expression * cloneWithDifferentOperands(Expression ** newOperands,
int numberOfOperands, bool cloneOperands = true) const override;
private:
float privateApproximate(Context & context, AngleUnit angleUnit) const override;
};
}
#endif

View File

@@ -0,0 +1,22 @@
#ifndef POINCARE_FRAC_PART_H
#define POINCARE_FRAC_PART_H
#include <poincare/function.h>
namespace Poincare {
class FracPart : public Function {
public:
FracPart();
Type type() const override;
Expression * cloneWithDifferentOperands(Expression ** newOperands,
int numberOfOperands, bool cloneOperands = true) const override;
private:
float privateApproximate(Context & context, AngleUnit angleUnit) const override;
};
}
#endif

View File

@@ -23,6 +23,8 @@ public:
/* If the buffer is too small, the function fills the buffer until reaching
* buffer size */
int writeTextInBuffer(char * buffer, int bufferSize) override;
Expression * createDimensionMatrix(Context& context, AngleUnit angleUnit) const;
float trace(Context& context, AngleUnit angleUnit) const;
float determinant(Context& context, AngleUnit angleUnit) const;
Expression * createInverse(Context& context, AngleUnit angleUnit) const;
Expression * createTranspose(Context& context, AngleUnit angleUnit) const;

View File

@@ -0,0 +1,22 @@
#ifndef POINCARE_MATRIX_DIMENSION_H
#define POINCARE_MATRIX_DIMENSION_H
#include <poincare/function.h>
namespace Poincare {
class MatrixDimension : public Function {
public:
MatrixDimension();
Type type() const override;
Expression * cloneWithDifferentOperands(Expression ** newOperands,
int numberOfOperands, bool cloneOperands = true) const override;
private:
float privateApproximate(Context & context, AngleUnit angleUnit) const override;
Expression * privateEvaluate(Context& context, AngleUnit angleUnit) const override;
};
}
#endif

View File

@@ -0,0 +1,21 @@
#ifndef POINCARE_MATRIX_TRACE_H
#define POINCARE_MATRIX_TRACE_H
#include <poincare/function.h>
namespace Poincare {
class MatrixTrace : public Function {
public:
MatrixTrace();
Type type() const override;
Expression * cloneWithDifferentOperands(Expression ** newOperands,
int numberOfOperands, bool cloneOperands = true) const override;
private:
float privateApproximate(Context & context, AngleUnit angleUnit) const override;
};
}
#endif

View File

@@ -0,0 +1,22 @@
#ifndef POINCARE_ROUND_H
#define POINCARE_ROUND_H
#include <poincare/function.h>
namespace Poincare {
class Round : public Function {
public:
Round();
Type type() const override;
Expression * cloneWithDifferentOperands(Expression ** newOperands,
int numberOfOperands, bool cloneOperands = true) const override;
private:
float privateApproximate(Context & context, AngleUnit angleUnit) const override;
};
}
#endif

36
poincare/src/ceiling.cpp Normal file
View File

@@ -0,0 +1,36 @@
#include <poincare/ceiling.h>
extern "C" {
#include <assert.h>
#include <math.h>
}
namespace Poincare {
Ceiling::Ceiling() :
Function("ceil")
{
}
Expression::Type Ceiling::type() const {
return Type::Ceiling;
}
Expression * Ceiling::cloneWithDifferentOperands(Expression** newOperands,
int numberOfOperands, bool cloneOperands) const {
assert(numberOfOperands == 1);
assert(newOperands != nullptr);
Ceiling * c = new Ceiling();
c->setArgument(newOperands, numberOfOperands, cloneOperands);
return c;
}
float Ceiling::privateApproximate(Context& context, AngleUnit angleUnit) const {
assert(angleUnit != AngleUnit::Default);
float f = m_args[0]->approximate(context, angleUnit);
return ceilf(f);
}
}

View File

@@ -93,11 +93,15 @@ abs { poincare_expression_yylval.expression = new AbsoluteValue(); return FUNCTI
ans { poincare_expression_yylval.character = Symbol::SpecialSymbols::Ans; return SYMBOL; }
arg { poincare_expression_yylval.expression = new ComplexArgument(); return FUNCTION; }
binomial { poincare_expression_yylval.expression = new BinomialCoefficient(); return FUNCTION; }
ceil { poincare_expression_yylval.expression = new Ceiling(); return FUNCTION; }
diff { poincare_expression_yylval.expression = new Derivative(); return FUNCTION; }
dim { poincare_expression_yylval.expression = new MatrixDimension(); return FUNCTION; }
det { poincare_expression_yylval.expression = new Determinant(); return FUNCTION; }
conj { poincare_expression_yylval.expression = new Conjugate(); return FUNCTION; }
cos { poincare_expression_yylval.expression = new Cosine(); return FUNCTION; }
cosh { poincare_expression_yylval.expression = new HyperbolicCosine(); return FUNCTION; }
floor { poincare_expression_yylval.expression = new Floor(); return FUNCTION; }
frac { poincare_expression_yylval.expression = new FracPart(); return FUNCTION; }
gcd { poincare_expression_yylval.expression = new GreatCommonDivisor(); return FUNCTION; }
im { poincare_expression_yylval.expression = new ImaginaryPart(); return FUNCTION; }
int { poincare_expression_yylval.expression = new Integral(); return FUNCTION; }
@@ -111,11 +115,13 @@ quo { poincare_expression_yylval.expression = new DivisionQuotient(); return FUN
re { poincare_expression_yylval.expression = new ReelPart(); return FUNCTION; }
rem { poincare_expression_yylval.expression = new DivisionRemainder(); return FUNCTION; }
root { poincare_expression_yylval.expression = new NthRoot(); return FUNCTION; }
round { poincare_expression_yylval.expression = new Round(); return FUNCTION; }
sin { poincare_expression_yylval.expression = new Sine(); return FUNCTION; }
sinh { poincare_expression_yylval.expression = new HyperbolicSine(); return FUNCTION; }
sum { poincare_expression_yylval.expression = new Sum(); return FUNCTION; }
tan { poincare_expression_yylval.expression = new Tangent(); return FUNCTION; }
tanh { poincare_expression_yylval.expression = new HyperbolicTangent(); return FUNCTION; }
trace { poincare_expression_yylval.expression = new MatrixTrace(); return FUNCTION; }
transpose { poincare_expression_yylval.expression = new MatrixTranspose(); return FUNCTION; }
\x89 { poincare_expression_yylval.character = yytext[0]; return SYMBOL; }
\x8c { return EE; }

36
poincare/src/floor.cpp Normal file
View File

@@ -0,0 +1,36 @@
#include <poincare/floor.h>
extern "C" {
#include <assert.h>
#include <math.h>
}
namespace Poincare {
Floor::Floor() :
Function("floor")
{
}
Expression::Type Floor::type() const {
return Type::Floor;
}
Expression * Floor::cloneWithDifferentOperands(Expression** newOperands,
int numberOfOperands, bool cloneOperands) const {
assert(numberOfOperands == 1);
assert(newOperands != nullptr);
Floor * f = new Floor();
f->setArgument(newOperands, numberOfOperands, cloneOperands);
return f;
}
float Floor::privateApproximate(Context& context, AngleUnit angleUnit) const {
assert(angleUnit != AngleUnit::Default);
float f = m_args[0]->approximate(context, angleUnit);
return floorf(f);
}
}

View File

@@ -0,0 +1,36 @@
#include <poincare/frac_part.h>
extern "C" {
#include <assert.h>
#include <math.h>
}
namespace Poincare {
FracPart::FracPart() :
Function("frac")
{
}
Expression::Type FracPart::type() const {
return Type::FracPart;
}
Expression * FracPart::cloneWithDifferentOperands(Expression** newOperands,
int numberOfOperands, bool cloneOperands) const {
assert(numberOfOperands == 1);
assert(newOperands != nullptr);
FracPart * fp = new FracPart();
fp->setArgument(newOperands, numberOfOperands, cloneOperands);
return fp;
}
float FracPart::privateApproximate(Context& context, AngleUnit angleUnit) const {
assert(angleUnit != AngleUnit::Default);
float f = m_args[0]->approximate(context, angleUnit);
return f-floorf(f);
}
}

View File

@@ -143,6 +143,25 @@ int Matrix::writeTextInBuffer(char * buffer, int bufferSize) {
return currentChar;
}
Expression * Matrix::createDimensionMatrix(Context& context, AngleUnit angleUnit) const {
Expression * operands[2];
operands[0] = new Complex(Complex::Float(numberOfRows()));
operands[1] = new Complex(Complex::Float(numberOfColumns()));
return new Matrix(new MatrixData(operands, 2, 2, 1, false));
}
float Matrix::trace(Context& context, AngleUnit angleUnit) const {
if (numberOfColumns() != numberOfRows()) {
return NAN;
}
int dim = numberOfRows();
float trace = 0.0f;
for (int i = 0; i < dim; i++) {
trace += m_matrixData->operands()[i*dim+i]->approximate(context, angleUnit);
}
return trace;
}
float Matrix::determinant(Context& context, AngleUnit angleUnit) const {
if (numberOfColumns() != numberOfRows()) {
return NAN;

View File

@@ -0,0 +1,47 @@
#include <poincare/matrix_dimension.h>
#include <poincare/matrix.h>
extern "C" {
#include <assert.h>
#include <math.h>
}
namespace Poincare {
MatrixDimension::MatrixDimension() :
Function("dimension")
{
}
Expression::Type MatrixDimension::type() const {
return Type::MatrixDimension;
}
Expression * MatrixDimension::cloneWithDifferentOperands(Expression** newOperands,
int numberOfOperands, bool cloneOperands) const {
assert(numberOfOperands == 1);
assert(newOperands != nullptr);
MatrixDimension * md = new MatrixDimension();
md->setArgument(newOperands, numberOfOperands, cloneOperands);
return md;
}
float MatrixDimension::privateApproximate(Context& context, AngleUnit angleUnit) const {
assert(angleUnit != AngleUnit::Default);
return NAN;
}
Expression * MatrixDimension::privateEvaluate(Context& context, AngleUnit angleUnit) const {
assert(angleUnit != AngleUnit::Default);
Expression * evaluation = m_args[0]->evaluate(context, angleUnit);
assert(evaluation->type() == Type::Matrix || evaluation->type() == Type::Complex);
if (evaluation->type() == Type::Complex) {
delete evaluation;
return nullptr;
}
Expression * dimension = ((Matrix *)evaluation)->createDimensionMatrix(context, angleUnit);
delete evaluation;
return dimension;
}
}

View File

@@ -38,7 +38,7 @@ Expression * MatrixInverse::privateEvaluate(Context& context, AngleUnit angleUni
assert(evaluation->type() == Type::Matrix || evaluation->type() == Type::Complex);
if (evaluation->type() == Type::Complex) {
Expression * arguments[2];
arguments[0] = new Complex(Complex::Float(2.0f));
arguments[0] = new Complex(Complex::Float(1.0f));
arguments[1] = evaluation;
Expression * result = new Fraction(arguments, true);
delete arguments[0];

View File

@@ -0,0 +1,43 @@
#include <poincare/matrix_trace.h>
#include <poincare/matrix.h>
extern "C" {
#include <assert.h>
#include <math.h>
}
namespace Poincare {
MatrixTrace::MatrixTrace() :
Function("trace")
{
}
Expression::Type MatrixTrace::type() const {
return Type::MatrixTrace;
}
Expression * MatrixTrace::cloneWithDifferentOperands(Expression** newOperands,
int numberOfOperands, bool cloneOperands) const {
assert(numberOfOperands == 1);
assert(newOperands != nullptr);
MatrixTrace * t = new MatrixTrace();
t->setArgument(newOperands, numberOfOperands, cloneOperands);
return t;
}
float MatrixTrace::privateApproximate(Context& context, AngleUnit angleUnit) const {
assert(angleUnit != AngleUnit::Default);
Expression * evaluation = m_args[0]->evaluate(context, angleUnit);
assert(evaluation->type() == Type::Matrix || evaluation->type() == Type::Complex);
if (evaluation->type() == Type::Complex) {
float result = evaluation->approximate(context, angleUnit);
delete evaluation;
return result;
}
float trace = ((Matrix *)evaluation)->trace(context, angleUnit);
delete evaluation;
return trace;
}
}

41
poincare/src/round.cpp Normal file
View File

@@ -0,0 +1,41 @@
#include <poincare/round.h>
extern "C" {
#include <assert.h>
#include <math.h>
}
namespace Poincare {
Round::Round() :
Function("round")
{
}
Expression::Type Round::type() const {
return Type::Round;
}
Expression * Round::cloneWithDifferentOperands(Expression** newOperands,
int numberOfOperands, bool cloneOperands) const {
assert(numberOfOperands == 1);
assert(newOperands != nullptr);
Round * r = new Round();
r->setArgument(newOperands, numberOfOperands, cloneOperands);
return r;
}
float Round::privateApproximate(Context& context, AngleUnit angleUnit) const {
assert(angleUnit != AngleUnit::Default);
float f1 = m_args[0]->approximate(context, angleUnit);
float f2 = m_args[1]->approximate(context, angleUnit);
if (isnan(f2) || f2 != (int)f2) {
return NAN;
}
float err = powf(10.0f, (int)f2);
return roundf(f1*err)/err;
}
}