mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-29 03:29:58 +02:00
Merge changes I10f860ee,Ia557927c
* changes: [poincare] Fix memory leak [poincare] Parse arithmetic functions (gcd, lcm, rem, quo)
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
const ToolboxNode calculChildren[4] = {ToolboxNode("diff(,)", "Nombre derive"), ToolboxNode("int(,,)", "Integrale"), ToolboxNode("sum(,,)", "Somme"), ToolboxNode("product(,,)", "Produit")};
|
||||
const ToolboxNode complexChildren[5] = {ToolboxNode("abs()", "Module"), ToolboxNode("arg()", "Argument"), ToolboxNode("re()", "Partie reelle"), ToolboxNode("im()", "Partie imaginaire"), ToolboxNode("conj()", "Conjugue")};
|
||||
const ToolboxNode probabilityChildren[2] = {ToolboxNode("binomial(,)", "Combinaison"), ToolboxNode("permute(,)", "Arrangement")};
|
||||
const ToolboxNode arithmeticChildren[4] = {ToolboxNode("gcd()", "PGCD"), ToolboxNode("lcm()", "PPCM"), ToolboxNode("rem()", "Reste division euclidienne"), ToolboxNode("quo()","Quotien division euclidienne")};
|
||||
const ToolboxNode arithmeticChildren[4] = {ToolboxNode("gcd(,)", "PGCD"), ToolboxNode("lcm(,)", "PPCM"), ToolboxNode("rem(,)", "Reste division euclidienne"), ToolboxNode("quo(,)","Quotien division euclidienne")};
|
||||
const ToolboxNode matricesChildren[5] = {ToolboxNode("inverse()", "Inverse"), ToolboxNode("det()", "Determinant"), ToolboxNode("transpose()", "Transposee"), ToolboxNode("trace()", "Trace"), ToolboxNode("dim()", "Taille")};
|
||||
const ToolboxNode listesChildren[5] = {ToolboxNode("sort<()", "Tri croissant"), ToolboxNode("sort>()", "Tri decroissant"), ToolboxNode("max()", "Maximum"), ToolboxNode("min()", "Minimum"), ToolboxNode("dim()", "Taille")};
|
||||
const ToolboxNode approximationChildren[4] = {ToolboxNode("floor()", "Partie entiere"), ToolboxNode("frac()", "Partie fractionnaire"), ToolboxNode("ceil()", "Plafond"), ToolboxNode("round(,)", "Arrondi")};
|
||||
|
||||
@@ -227,7 +227,7 @@ void TermSumController::ContentView::LegendView::setSumSuperscript(float start,
|
||||
}
|
||||
|
||||
void TermSumController::ContentView::LegendView::setSequenceName(const char * sequenceName) {
|
||||
ExpressionLayout ** childrenLayouts = (ExpressionLayout **)malloc(2*sizeof(ExpressionLayout *));
|
||||
ExpressionLayout * childrenLayouts[2];
|
||||
childrenLayouts[1] = new BaselineRelativeLayout(new StringLayout(sequenceName, 1, KDText::FontSize::Small), new StringLayout("n", 1, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript);
|
||||
childrenLayouts[0] = m_sumLayout;
|
||||
m_sumLayout = new HorizontalLayout(childrenLayouts, 2);
|
||||
|
||||
@@ -13,12 +13,15 @@ objs += $(addprefix poincare/src/,\
|
||||
cosine.o\
|
||||
derivative.o\
|
||||
determinant.o\
|
||||
division_quotient.o\
|
||||
division_remainder.o\
|
||||
expression.o\
|
||||
expression_lexer.o\
|
||||
expression_parser.o\
|
||||
fraction.o\
|
||||
function.o\
|
||||
global_context.o\
|
||||
great_common_divisor.o\
|
||||
hyperbolic_cosine.o\
|
||||
hyperbolic_sine.o\
|
||||
hyperbolic_tangent.o\
|
||||
@@ -27,6 +30,7 @@ objs += $(addprefix poincare/src/,\
|
||||
integral.o\
|
||||
list_data.o\
|
||||
leaf_expression.o\
|
||||
least_common_multiple.o\
|
||||
logarithm.o\
|
||||
matrix.o\
|
||||
matrix_data.o\
|
||||
|
||||
@@ -11,10 +11,13 @@
|
||||
#include <poincare/cosine.h>
|
||||
#include <poincare/derivative.h>
|
||||
#include <poincare/determinant.h>
|
||||
#include <poincare/division_quotient.h>
|
||||
#include <poincare/division_remainder.h>
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/fraction.h>
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/global_context.h>
|
||||
#include <poincare/great_common_divisor.h>
|
||||
#include <poincare/hyperbolic_cosine.h>
|
||||
#include <poincare/hyperbolic_sine.h>
|
||||
#include <poincare/hyperbolic_tangent.h>
|
||||
@@ -22,6 +25,7 @@
|
||||
#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>
|
||||
|
||||
21
poincare/include/poincare/division_quotient.h
Normal file
21
poincare/include/poincare/division_quotient.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef POINCARE_DIVISION_QUOTIENT_H
|
||||
#define POINCARE_DIVISION_QUOTIENT_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class DivisionQuotient : public Function {
|
||||
public:
|
||||
DivisionQuotient();
|
||||
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
|
||||
|
||||
21
poincare/include/poincare/division_remainder.h
Normal file
21
poincare/include/poincare/division_remainder.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef POINCARE_DIVISION_REMAINDER_H
|
||||
#define POINCARE_DIVISION_REMAINDER_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class DivisionRemainder : public Function {
|
||||
public:
|
||||
DivisionRemainder();
|
||||
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
|
||||
|
||||
@@ -20,7 +20,10 @@ public:
|
||||
Cosine,
|
||||
Derivative,
|
||||
Determinant,
|
||||
DivisionQuotient,
|
||||
DivisionRemainder,
|
||||
Float,
|
||||
GreatCommonDivisor,
|
||||
HyperbolicCosine,
|
||||
HyperbolicSine,
|
||||
HyperbolicTangent,
|
||||
@@ -28,6 +31,7 @@ public:
|
||||
Integer,
|
||||
Integral,
|
||||
Logarithm,
|
||||
LeastCommonMultiple,
|
||||
Matrix,
|
||||
MatrixInverse,
|
||||
Multiplication,
|
||||
|
||||
21
poincare/include/poincare/great_common_divisor.h
Normal file
21
poincare/include/poincare/great_common_divisor.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef POINCARE_GREAT_COMMON_DIVISOR_H
|
||||
#define POINCARE_GREAT_COMMON_DIVISOR_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class GreatCommonDivisor : public Function {
|
||||
public:
|
||||
GreatCommonDivisor();
|
||||
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
|
||||
|
||||
21
poincare/include/poincare/least_common_multiple.h
Normal file
21
poincare/include/poincare/least_common_multiple.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef POINCARE_LEAST_COMMON_MULTIPLE_H
|
||||
#define POINCARE_LEAST_COMMON_MULTIPLE_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class LeastCommonMultiple : public Function {
|
||||
public:
|
||||
LeastCommonMultiple();
|
||||
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
|
||||
|
||||
@@ -24,7 +24,8 @@ public:
|
||||
* buffer size */
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) override;
|
||||
float determinant(Context& context, AngleUnit angleUnit) const;
|
||||
Expression * inverse(Context& context, AngleUnit angleUnit) const;
|
||||
Expression * createInverse(Context& context, AngleUnit angleUnit) const;
|
||||
Expression * createTranspose(Context& context, AngleUnit angleUnit) const;
|
||||
private:
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
|
||||
float privateApproximate(Context& context, AngleUnit angleUnit) const override;
|
||||
|
||||
@@ -9,10 +9,10 @@ namespace Poincare {
|
||||
|
||||
class MatrixData {
|
||||
public:
|
||||
MatrixData(ListData * listData);
|
||||
MatrixData(ListData * listData, bool clone);
|
||||
MatrixData(Expression ** newOperands, int numberOfOperands, int m_numberOfColumns, int m_numberOfRows, bool cloneOperands);
|
||||
~MatrixData();
|
||||
void pushListData(ListData * listData);
|
||||
void pushListData(ListData * listData, bool clone);
|
||||
int numberOfRows();
|
||||
int numberOfColumns();
|
||||
Expression ** operands() const;
|
||||
|
||||
@@ -20,7 +20,9 @@ ExpressionLayout * Addition::privateCreateLayout(FloatDisplayMode floatDisplayMo
|
||||
children_layouts[0] = m_operands[0]->createLayout(floatDisplayMode, complexFormat);
|
||||
children_layouts[1] = new StringLayout("+", 1);
|
||||
children_layouts[2] = m_operands[1]->type() == Type::Opposite ? new ParenthesisLayout(m_operands[1]->createLayout(floatDisplayMode, complexFormat)) : m_operands[1]->createLayout(floatDisplayMode, complexFormat);
|
||||
return new HorizontalLayout(children_layouts, 3);
|
||||
ExpressionLayout * layout = new HorizontalLayout(children_layouts, 3);
|
||||
free(children_layouts);
|
||||
return layout;
|
||||
}
|
||||
|
||||
float Addition::privateApproximate(Context& context, AngleUnit angleUnit) const {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
extern "C" {
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
}
|
||||
|
||||
namespace Poincare {
|
||||
@@ -64,7 +65,7 @@ Expression * BinaryOperation::privateEvaluate(Context& context, AngleUnit angleU
|
||||
}
|
||||
|
||||
Expression * BinaryOperation::evaluateOnMatrixAndComplex(Matrix * m, Complex * c, Context& context, AngleUnit angleUnit) const {
|
||||
Expression * operands[m->numberOfRows() * m->numberOfColumns()];
|
||||
Expression ** operands = (Expression **)malloc(m->numberOfRows() * m->numberOfColumns()*sizeof(Expression *));
|
||||
for (int i = 0; i < m->numberOfRows() * m->numberOfColumns(); i++) {
|
||||
Expression * evaluation = m->operand(i)->evaluate(context, angleUnit);
|
||||
assert(evaluation->type() == Type::Matrix || evaluation->type() == Type::Complex);
|
||||
@@ -76,7 +77,9 @@ Expression * BinaryOperation::evaluateOnMatrixAndComplex(Matrix * m, Complex * c
|
||||
operands[i] = evaluateOnComplex((Complex *)evaluation, c, context, angleUnit);
|
||||
delete evaluation;
|
||||
}
|
||||
return new Matrix(operands, m->numberOfRows() * m->numberOfColumns(), m->numberOfColumns(), m->numberOfRows(), false);
|
||||
Expression * result = new Matrix(operands, m->numberOfRows() * m->numberOfColumns(), m->numberOfColumns(), m->numberOfRows(), false);
|
||||
free(operands);
|
||||
return result;
|
||||
}
|
||||
|
||||
Expression * BinaryOperation::evaluateOnComplexAndMatrix(Complex * c, Matrix * m, Context& context, AngleUnit angleUnit) const {
|
||||
@@ -87,7 +90,7 @@ Expression * BinaryOperation::evaluateOnMatrices(Matrix * m, Matrix * n, Context
|
||||
if (m->numberOfColumns() != n->numberOfColumns() || m->numberOfRows() != n->numberOfRows()) {
|
||||
return nullptr;
|
||||
}
|
||||
Expression * operands[m->numberOfRows() * m->numberOfColumns()];
|
||||
Expression ** operands = (Expression **)malloc(m->numberOfRows() * m->numberOfColumns()*sizeof(Expression *));
|
||||
for (int i = 0; i < m->numberOfRows() * m->numberOfColumns(); i++) {
|
||||
Expression * mEvaluation = m->operand(i)->evaluate(context, angleUnit);
|
||||
Expression * nEvaluation = n->operand(i)->evaluate(context, angleUnit);
|
||||
@@ -103,7 +106,9 @@ Expression * BinaryOperation::evaluateOnMatrices(Matrix * m, Matrix * n, Context
|
||||
delete mEvaluation;
|
||||
delete nEvaluation;
|
||||
}
|
||||
return new Matrix(operands, m->numberOfRows() * m->numberOfColumns(), m->numberOfColumns(), m->numberOfRows(), false);
|
||||
Expression * result = new Matrix(operands, m->numberOfRows() * m->numberOfColumns(), m->numberOfColumns(), m->numberOfRows(), false);
|
||||
free(operands);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ float BinomialCoefficient::privateApproximate(Context& context, AngleUnit angleU
|
||||
ExpressionLayout * BinomialCoefficient::privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const {
|
||||
assert(floatDisplayMode != FloatDisplayMode::Default);
|
||||
assert(complexFormat != ComplexFormat::Default);
|
||||
ExpressionLayout ** childrenLayouts = (ExpressionLayout **)malloc(2*sizeof(ExpressionLayout *));
|
||||
ExpressionLayout * childrenLayouts[2];
|
||||
childrenLayouts[0] = m_args[0]->createLayout(floatDisplayMode, complexFormat);
|
||||
childrenLayouts[1] = m_args[1]->createLayout(floatDisplayMode, complexFormat);
|
||||
return new ParenthesisLayout(new GridLayout(childrenLayouts, 2, 1));
|
||||
|
||||
39
poincare/src/division_quotient.cpp
Normal file
39
poincare/src/division_quotient.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#include <poincare/division_quotient.h>
|
||||
|
||||
extern "C" {
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
}
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
DivisionQuotient::DivisionQuotient() :
|
||||
Function("quo")
|
||||
{
|
||||
}
|
||||
|
||||
Expression::Type DivisionQuotient::type() const {
|
||||
return Type::DivisionQuotient;
|
||||
}
|
||||
|
||||
Expression * DivisionQuotient::cloneWithDifferentOperands(Expression** newOperands,
|
||||
int numberOfOperands, bool cloneOperands) const {
|
||||
assert(numberOfOperands == 1);
|
||||
assert(newOperands != nullptr);
|
||||
DivisionQuotient * dq = new DivisionQuotient();
|
||||
dq->setArgument(newOperands, numberOfOperands, cloneOperands);
|
||||
return dq;
|
||||
}
|
||||
|
||||
float DivisionQuotient::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(f1) || isnan(f2) || f1 != (int)f1 || f2 != (int)f2) {
|
||||
return NAN;
|
||||
}
|
||||
return floorf(f1/f2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
39
poincare/src/division_remainder.cpp
Normal file
39
poincare/src/division_remainder.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#include <poincare/division_remainder.h>
|
||||
|
||||
extern "C" {
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
}
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
DivisionRemainder::DivisionRemainder() :
|
||||
Function("rem")
|
||||
{
|
||||
}
|
||||
|
||||
Expression::Type DivisionRemainder::type() const {
|
||||
return Type::DivisionRemainder;
|
||||
}
|
||||
|
||||
Expression * DivisionRemainder::cloneWithDifferentOperands(Expression** newOperands,
|
||||
int numberOfOperands, bool cloneOperands) const {
|
||||
assert(numberOfOperands == 1);
|
||||
assert(newOperands != nullptr);
|
||||
DivisionRemainder * dr = new DivisionRemainder();
|
||||
dr->setArgument(newOperands, numberOfOperands, cloneOperands);
|
||||
return dr;
|
||||
}
|
||||
|
||||
float DivisionRemainder::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(f1) || isnan(f2) || f1 != (int)f1 || f2 != (int)f2) {
|
||||
return NAN;
|
||||
}
|
||||
return roundf(f1-f2*floorf(f1/f2));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -98,14 +98,18 @@ 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; }
|
||||
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; }
|
||||
inverse { poincare_expression_yylval.expression = new MatrixInverse(); return FUNCTION; }
|
||||
lcm { poincare_expression_yylval.expression = new LeastCommonMultiple(); return FUNCTION; }
|
||||
ln { poincare_expression_yylval.expression = new NaperianLogarithm(); return FUNCTION; }
|
||||
log { poincare_expression_yylval.expression = new Logarithm(); return FUNCTION; }
|
||||
permute { poincare_expression_yylval.expression = new PermuteCoefficient(); return FUNCTION; }
|
||||
product { poincare_expression_yylval.expression = new Product(); return FUNCTION; }
|
||||
quo { poincare_expression_yylval.expression = new DivisionQuotient(); return FUNCTION; }
|
||||
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; }
|
||||
sin { poincare_expression_yylval.expression = new Sine(); return FUNCTION; }
|
||||
sinh { poincare_expression_yylval.expression = new HyperbolicSine(); return FUNCTION; }
|
||||
|
||||
@@ -107,8 +107,8 @@ lstData:
|
||||
| lstData COMMA exp { $$ = $1; $$->pushExpression($3); }
|
||||
|
||||
mtxData:
|
||||
LEFT_BRACKET lstData RIGHT_BRACKET { $$ = new Poincare::MatrixData($2); }
|
||||
| mtxData LEFT_BRACKET lstData RIGHT_BRACKET { $$ = $1; $$->pushListData($3); }
|
||||
LEFT_BRACKET lstData RIGHT_BRACKET { $$ = new Poincare::MatrixData($2, true); delete $2; }
|
||||
| mtxData LEFT_BRACKET lstData RIGHT_BRACKET { $$ = $1; $$->pushListData($3, true); delete $3; }
|
||||
|
||||
number:
|
||||
DIGITS { $$ = new Poincare::Integer($1.address, false); }
|
||||
@@ -131,7 +131,7 @@ exp:
|
||||
| MINUS exp { $$ = new Poincare::Opposite($2, false); }
|
||||
| LEFT_PARENTHESIS exp RIGHT_PARENTHESIS { $$ = new Poincare::Parenthesis($2, false); }
|
||||
| LEFT_BRACKET mtxData RIGHT_BRACKET { $$ = new Poincare::Matrix($2); }
|
||||
| FUNCTION LEFT_PARENTHESIS lstData RIGHT_PARENTHESIS { $$ = $1; $1->setArgument($3, false);}
|
||||
| FUNCTION LEFT_PARENTHESIS lstData RIGHT_PARENTHESIS { $$ = $1; $1->setArgument($3, true); delete $3; }
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
@@ -78,7 +78,8 @@ ExpressionLayout * Function::privateCreateLayout(FloatDisplayMode floatDisplayMo
|
||||
grandChildrenLayouts[layoutIndex++] = m_args[i]->createLayout(floatDisplayMode, complexFormat);
|
||||
}
|
||||
ExpressionLayout * argumentLayouts = new HorizontalLayout(grandChildrenLayouts, 2*m_numberOfArguments-1);
|
||||
ExpressionLayout ** childrenLayouts = (ExpressionLayout **)malloc(2*sizeof(ExpressionLayout *));
|
||||
free(grandChildrenLayouts);
|
||||
ExpressionLayout * childrenLayouts[2];
|
||||
childrenLayouts[0] = new StringLayout(m_name, strlen(m_name));
|
||||
childrenLayouts[1] = new ParenthesisLayout(argumentLayouts);
|
||||
return new HorizontalLayout(childrenLayouts, 2);
|
||||
|
||||
52
poincare/src/great_common_divisor.cpp
Normal file
52
poincare/src/great_common_divisor.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#include <poincare/great_common_divisor.h>
|
||||
#include <poincare/complex.h>
|
||||
|
||||
extern "C" {
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
}
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
GreatCommonDivisor::GreatCommonDivisor() :
|
||||
Function("gcd")
|
||||
{
|
||||
}
|
||||
|
||||
Expression::Type GreatCommonDivisor::type() const {
|
||||
return Type::GreatCommonDivisor;
|
||||
}
|
||||
|
||||
Expression * GreatCommonDivisor::cloneWithDifferentOperands(Expression** newOperands,
|
||||
int numberOfOperands, bool cloneOperands) const {
|
||||
assert(numberOfOperands == 1);
|
||||
assert(newOperands != nullptr);
|
||||
GreatCommonDivisor * gcd = new GreatCommonDivisor();
|
||||
gcd->setArgument(newOperands, numberOfOperands, cloneOperands);
|
||||
return gcd;
|
||||
}
|
||||
|
||||
float GreatCommonDivisor::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(f1) || isnan(f2) || f1 != (int)f1 || f2 != (int)f2) {
|
||||
return NAN;
|
||||
}
|
||||
int a = (int)f2;
|
||||
int b = (int)f1;
|
||||
if (f1 > f2) {
|
||||
b = a;
|
||||
a = (int)f1;
|
||||
}
|
||||
int r = 0;
|
||||
while((int)b!=0){
|
||||
r = a - ((int)(a/b))*b;
|
||||
a = b;
|
||||
b = r;
|
||||
}
|
||||
return roundf((float)a);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ float Integral::privateApproximate(Context& context, AngleUnit angleUnit) const
|
||||
ExpressionLayout * Integral::privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const {
|
||||
assert(floatDisplayMode != FloatDisplayMode::Default);
|
||||
assert(complexFormat != ComplexFormat::Default);
|
||||
ExpressionLayout ** childrenLayouts = (ExpressionLayout **)malloc(2*sizeof(ExpressionLayout *));
|
||||
ExpressionLayout * childrenLayouts[2];
|
||||
childrenLayouts[0] = m_args[0]->createLayout(floatDisplayMode, complexFormat);
|
||||
childrenLayouts[1] = new StringLayout("dx", 2);
|
||||
return new IntegralLayout(m_args[1]->createLayout(floatDisplayMode, complexFormat), m_args[2]->createLayout(floatDisplayMode, complexFormat), new HorizontalLayout(childrenLayouts, 2));
|
||||
|
||||
@@ -8,11 +8,12 @@ namespace Poincare {
|
||||
|
||||
GridLayout::GridLayout(ExpressionLayout ** entryLayouts, int numberOfRows, int numberOfColumns) :
|
||||
ExpressionLayout(),
|
||||
m_entryLayouts(entryLayouts),
|
||||
m_numberOfRows(numberOfRows),
|
||||
m_numberOfColumns(numberOfColumns)
|
||||
{
|
||||
m_entryLayouts = (ExpressionLayout **)malloc(numberOfColumns*numberOfRows*sizeof(ExpressionLayout *));
|
||||
for (int i = 0; i < m_numberOfRows*m_numberOfColumns; i++) {
|
||||
m_entryLayouts[i] = entryLayouts[i];
|
||||
m_entryLayouts[i]->setParent(this);
|
||||
}
|
||||
m_baseline = height()/2 + KDText::stringSize(" ").height()/2;
|
||||
|
||||
@@ -9,9 +9,11 @@ extern "C" {
|
||||
namespace Poincare {
|
||||
|
||||
HorizontalLayout::HorizontalLayout(ExpressionLayout ** children_layouts, int number_of_children) :
|
||||
ExpressionLayout(), m_number_of_children(number_of_children), m_children_layouts(children_layouts) {
|
||||
ExpressionLayout(), m_number_of_children(number_of_children) {
|
||||
assert(number_of_children > 0);
|
||||
m_children_layouts = (ExpressionLayout **)malloc(number_of_children*sizeof(ExpressionLayout *));
|
||||
for (int i=0; i<m_number_of_children; i++) {
|
||||
m_children_layouts[i] = children_layouts[i];
|
||||
m_children_layouts[i]->setParent(this);
|
||||
if (m_children_layouts[i]->baseline() > m_baseline) {
|
||||
m_baseline = m_children_layouts[i]->baseline();
|
||||
|
||||
53
poincare/src/least_common_multiple.cpp
Normal file
53
poincare/src/least_common_multiple.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
#include <poincare/least_common_multiple.h>
|
||||
#include <poincare/complex.h>
|
||||
|
||||
extern "C" {
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
}
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
LeastCommonMultiple::LeastCommonMultiple() :
|
||||
Function("lcm")
|
||||
{
|
||||
}
|
||||
|
||||
Expression::Type LeastCommonMultiple::type() const {
|
||||
return Type::LeastCommonMultiple;
|
||||
}
|
||||
|
||||
Expression * LeastCommonMultiple::cloneWithDifferentOperands(Expression** newOperands,
|
||||
int numberOfOperands, bool cloneOperands) const {
|
||||
assert(numberOfOperands == 1);
|
||||
assert(newOperands != nullptr);
|
||||
LeastCommonMultiple * lcm = new LeastCommonMultiple();
|
||||
lcm->setArgument(newOperands, numberOfOperands, cloneOperands);
|
||||
return lcm;
|
||||
}
|
||||
|
||||
float LeastCommonMultiple::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(f1) || isnan(f2) || f1 != (int)f1 || f2 != (int)f2) {
|
||||
return NAN;
|
||||
}
|
||||
int a = (int)f2;
|
||||
int b = (int)f1;
|
||||
if (f1 > f2) {
|
||||
b = a;
|
||||
a = (int)f1;
|
||||
}
|
||||
int product = a*b;
|
||||
int r = 0;
|
||||
while((int)b!=0){
|
||||
r = a - ((int)(a/b))*b;
|
||||
a = b;
|
||||
b = r;
|
||||
}
|
||||
return roundf((float)(product/a));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ ExpressionLayout * Logarithm::privateCreateLayout(FloatDisplayMode floatDisplayM
|
||||
if (m_numberOfArguments == 1) {
|
||||
return Function::privateCreateLayout(floatDisplayMode, complexFormat);
|
||||
}
|
||||
ExpressionLayout ** childrenLayouts = (ExpressionLayout **)malloc(2*sizeof(ExpressionLayout *));
|
||||
ExpressionLayout * childrenLayouts[2];
|
||||
childrenLayouts[0] = new BaselineRelativeLayout(new StringLayout(m_name, strlen(m_name)), m_args[0]->createLayout(floatDisplayMode, complexFormat), BaselineRelativeLayout::Type::Subscript);
|
||||
childrenLayouts[1] = new ParenthesisLayout(m_args[1]->createLayout(floatDisplayMode, complexFormat));
|
||||
return new HorizontalLayout(childrenLayouts, 2);
|
||||
|
||||
@@ -52,7 +52,9 @@ ExpressionLayout * Matrix::privateCreateLayout(FloatDisplayMode floatDisplayMode
|
||||
for (int i = 0; i < numberOfOperands(); i++) {
|
||||
childrenLayouts[i] = operand(i)->createLayout(floatDisplayMode, complexFormat);
|
||||
}
|
||||
return new BracketLayout(new GridLayout(childrenLayouts, numberOfRows(), numberOfColumns()));
|
||||
ExpressionLayout * layout = new BracketLayout(new GridLayout(childrenLayouts, numberOfRows(), numberOfColumns()));
|
||||
free(childrenLayouts);
|
||||
return layout;
|
||||
}
|
||||
|
||||
float Matrix::privateApproximate(Context& context, AngleUnit angleUnit) const {
|
||||
@@ -62,7 +64,7 @@ float Matrix::privateApproximate(Context& context, AngleUnit angleUnit) const {
|
||||
|
||||
Expression * Matrix::privateEvaluate(Context& context, AngleUnit angleUnit) const {
|
||||
assert(angleUnit != AngleUnit::Default);
|
||||
Expression * operands[numberOfOperands()];
|
||||
Expression ** operands = (Expression **)malloc(numberOfOperands()*sizeof(Expression *));
|
||||
for (int i = 0; i < numberOfOperands(); i++) {
|
||||
operands[i] = operand(i)->evaluate(context, angleUnit);
|
||||
assert(operands[i]->type() == Type::Matrix || operands[i]->type() == Type::Complex);
|
||||
@@ -72,7 +74,9 @@ Expression * Matrix::privateEvaluate(Context& context, AngleUnit angleUnit) cons
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return new Matrix(new MatrixData(operands, numberOfOperands(), numberOfColumns(), numberOfRows(), false));
|
||||
Expression * matrix = new Matrix(new MatrixData(operands, numberOfOperands(), numberOfColumns(), numberOfRows(), false));
|
||||
free(operands);
|
||||
return matrix;
|
||||
}
|
||||
|
||||
Expression::Type Matrix::type() const {
|
||||
@@ -200,7 +204,7 @@ float Matrix::determinant(Context& context, AngleUnit angleUnit) const {
|
||||
return det;
|
||||
}
|
||||
|
||||
Expression * Matrix::inverse(Context& context, AngleUnit angleUnit) const {
|
||||
Expression * Matrix::createInverse(Context& context, AngleUnit angleUnit) const {
|
||||
if (numberOfColumns() != numberOfRows()) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -259,7 +263,7 @@ Expression * Matrix::inverse(Context& context, AngleUnit angleUnit) const {
|
||||
}
|
||||
}
|
||||
}
|
||||
Expression * operands[numberOfOperands()];
|
||||
Expression ** operands = (Expression **)malloc(numberOfOperands()*sizeof(Expression *));
|
||||
for (int i = 0; i < numberOfRows(); i++) {
|
||||
for (int j = 0; j < numberOfColumns(); j++) {
|
||||
operands[i*dim+j] = new Complex(Complex::Float(inv[i][j+dim]));
|
||||
@@ -269,7 +273,21 @@ Expression * Matrix::inverse(Context& context, AngleUnit angleUnit) const {
|
||||
free(inv[i]);
|
||||
}
|
||||
free(inv);
|
||||
return new Matrix(new MatrixData(operands, numberOfOperands(), numberOfColumns(), numberOfRows(), false));
|
||||
Expression * matrix = new Matrix(new MatrixData(operands, numberOfOperands(), numberOfColumns(), numberOfRows(), false));
|
||||
free(operands);
|
||||
return matrix;
|
||||
}
|
||||
|
||||
Expression * Matrix::createTranspose(Context& context, AngleUnit angleUnit) const {
|
||||
Expression ** operands = (Expression **)malloc(numberOfOperands()*sizeof(Expression *));
|
||||
for (int i = 0; i < numberOfRows(); i++) {
|
||||
for (int j = 0; j < numberOfColumns(); j++) {
|
||||
operands[j*numberOfRows()+i] = m_matrixData->operands()[i*numberOfColumns()+j]->clone();
|
||||
}
|
||||
}
|
||||
Expression * matrix = new Matrix(new MatrixData(operands, numberOfOperands(), numberOfRows(), numberOfColumns(), false));
|
||||
free(operands);
|
||||
return matrix;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ extern "C" {
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
MatrixData::MatrixData(ListData * listData) :
|
||||
MatrixData::MatrixData(ListData * listData, bool clone) :
|
||||
m_numberOfRows(1),
|
||||
m_numberOfColumns(0)
|
||||
{
|
||||
@@ -15,7 +15,11 @@ MatrixData::MatrixData(ListData * listData) :
|
||||
m_numberOfColumns = listData->numberOfOperands();
|
||||
m_operands = (Expression **)malloc(m_numberOfColumns*sizeof(Expression *));
|
||||
for (int i = 0; i < m_numberOfColumns; i++) {
|
||||
m_operands[i] = (Expression *)listData->operand(i);
|
||||
if (clone) {
|
||||
m_operands[i] = (Expression *)listData->operand(i)->clone();
|
||||
} else {
|
||||
m_operands[i] = (Expression *)listData->operand(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,14 +53,18 @@ MatrixData::~MatrixData() {
|
||||
free(m_operands);
|
||||
}
|
||||
|
||||
void MatrixData::pushListData(ListData * listData) {
|
||||
void MatrixData::pushListData(ListData * listData, bool clone) {
|
||||
Expression ** newOperands = (Expression **)malloc(((m_numberOfRows+1)*m_numberOfColumns)*sizeof(Expression *));
|
||||
for (int i = 0; i < m_numberOfRows*m_numberOfColumns; i++) {
|
||||
newOperands[i] = m_operands[i];
|
||||
}
|
||||
for (int i = 0; i < m_numberOfColumns; i++) {
|
||||
int max = listData->numberOfOperands();
|
||||
newOperands[m_numberOfRows*m_numberOfColumns+i] = i < max ? (Expression *)listData->operand(i) : defaultExpression();
|
||||
if (clone) {
|
||||
newOperands[m_numberOfRows*m_numberOfColumns+i] = i < max ? (Expression *)listData->operand(i)->clone() : defaultExpression();
|
||||
} else {
|
||||
newOperands[m_numberOfRows*m_numberOfColumns+i] = i < max ? (Expression *)listData->operand(i) : defaultExpression();
|
||||
}
|
||||
}
|
||||
free(m_operands);
|
||||
m_operands = newOperands;
|
||||
|
||||
@@ -47,7 +47,7 @@ Expression * MatrixInverse::privateEvaluate(Context& context, AngleUnit angleUni
|
||||
delete result;
|
||||
return resultEvaluation;
|
||||
}
|
||||
Expression * inverse = ((Matrix *)evaluation)->inverse(context, angleUnit);
|
||||
Expression * inverse = ((Matrix *)evaluation)->createInverse(context, angleUnit);
|
||||
delete evaluation;
|
||||
return inverse;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ Expression::Type Multiplication::type() const {
|
||||
ExpressionLayout * Multiplication::privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const {
|
||||
assert(floatDisplayMode != FloatDisplayMode::Default);
|
||||
assert(complexFormat != ComplexFormat::Default);
|
||||
ExpressionLayout** children_layouts = (ExpressionLayout **)malloc(3*sizeof(ExpressionLayout *));
|
||||
ExpressionLayout * children_layouts[3];
|
||||
children_layouts[0] = m_operands[0]->createLayout(floatDisplayMode, complexFormat);
|
||||
children_layouts[1] = new StringLayout("*", 1);
|
||||
children_layouts[2] = m_operands[1]->type() == Type::Opposite ? new ParenthesisLayout(m_operands[1]->createLayout(floatDisplayMode, complexFormat)) : m_operands[1]->createLayout(floatDisplayMode, complexFormat);
|
||||
@@ -45,7 +45,7 @@ Expression * Multiplication::evaluateOnMatrices(Matrix * m, Matrix * n, Context&
|
||||
if (m->numberOfColumns() != n->numberOfRows()) {
|
||||
return nullptr;
|
||||
}
|
||||
Expression * operands[m->numberOfRows() * n->numberOfColumns()];
|
||||
Expression ** operands = (Expression **)malloc(m->numberOfRows() * n->numberOfColumns()*sizeof(Expression *));
|
||||
for (int i = 0; i < m->numberOfRows(); i++) {
|
||||
for (int j = 0; j < n->numberOfColumns(); j++) {
|
||||
float a = 0.0f;
|
||||
@@ -69,7 +69,9 @@ Expression * Multiplication::evaluateOnMatrices(Matrix * m, Matrix * n, Context&
|
||||
operands[i*n->numberOfColumns()+j] = new Complex(Complex::Cartesian(a, b));
|
||||
}
|
||||
}
|
||||
return new Matrix(operands, m->numberOfRows() * n->numberOfColumns(), m->numberOfRows(), n->numberOfColumns(), false);
|
||||
Expression * matrix = new Matrix(operands, m->numberOfRows() * n->numberOfColumns(), m->numberOfRows(), n->numberOfColumns(), false);
|
||||
free(operands);
|
||||
return matrix;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ Expression * Opposite::privateEvaluate(Context& context, AngleUnit angleUnit) co
|
||||
ExpressionLayout * Opposite::privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const {
|
||||
assert(floatDisplayMode != FloatDisplayMode::Default);
|
||||
assert(complexFormat != ComplexFormat::Default);
|
||||
ExpressionLayout** children_layouts = (ExpressionLayout **)malloc(2*sizeof(ExpressionLayout *));
|
||||
ExpressionLayout * children_layouts[2];
|
||||
char string[2] = {'-', '\0'};
|
||||
children_layouts[0] = new StringLayout(string, 1);
|
||||
children_layouts[1] = m_operand->type() == Type::Opposite ? new ParenthesisLayout(m_operand->createLayout(floatDisplayMode, complexFormat)) : m_operand->createLayout(floatDisplayMode, complexFormat);
|
||||
@@ -80,7 +80,7 @@ Expression * Opposite::cloneWithDifferentOperands(Expression** newOperands,
|
||||
}
|
||||
|
||||
Expression * Opposite::evaluateOnMatrix(Matrix * m, Context& context, AngleUnit angleUnit) const {
|
||||
Expression * operands[m->numberOfRows() * m->numberOfColumns()];
|
||||
Expression ** operands = (Expression **)malloc(m->numberOfRows() * m->numberOfColumns()*sizeof(Expression *));
|
||||
for (int i = 0; i < m->numberOfRows() * m->numberOfColumns(); i++) {
|
||||
Expression * evaluation = m->operand(i)->evaluate(context, angleUnit);
|
||||
assert(evaluation->type() == Type::Matrix || evaluation->type() == Type::Complex);
|
||||
@@ -92,7 +92,9 @@ Expression * Opposite::evaluateOnMatrix(Matrix * m, Context& context, AngleUnit
|
||||
operands[i] = new Complex(Complex::Cartesian(-((Complex *)evaluation)->a(), -((Complex *)evaluation)->b()));
|
||||
delete evaluation;
|
||||
}
|
||||
return new Matrix(operands, m->numberOfRows() * m->numberOfColumns(), m->numberOfColumns(), m->numberOfRows(), false);
|
||||
Expression * matrix = new Matrix(operands, m->numberOfRows() * m->numberOfColumns(), m->numberOfColumns(), m->numberOfRows(), false);
|
||||
free(operands);
|
||||
return matrix;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ float Product::privateApproximate(Context& context, AngleUnit angleUnit) const {
|
||||
ExpressionLayout * Product::privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const {
|
||||
assert(floatDisplayMode != FloatDisplayMode::Default);
|
||||
assert(complexFormat != ComplexFormat::Default);
|
||||
ExpressionLayout ** childrenLayouts = (ExpressionLayout **)malloc(2*sizeof(ExpressionLayout *));
|
||||
ExpressionLayout * childrenLayouts[2];
|
||||
childrenLayouts[0] = new StringLayout("n=", 2);
|
||||
childrenLayouts[1] = m_args[1]->createLayout(floatDisplayMode, complexFormat);
|
||||
return new ProductLayout(new HorizontalLayout(childrenLayouts, 2), m_args[2]->createLayout(floatDisplayMode, complexFormat), m_args[0]->createLayout(floatDisplayMode, complexFormat));
|
||||
|
||||
@@ -30,7 +30,7 @@ Expression::Type Subtraction::type() const {
|
||||
ExpressionLayout * Subtraction::privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const {
|
||||
assert(floatDisplayMode != FloatDisplayMode::Default);
|
||||
assert(complexFormat != ComplexFormat::Default);
|
||||
ExpressionLayout** children_layouts = (ExpressionLayout **)malloc(3*sizeof(ExpressionLayout *));
|
||||
ExpressionLayout * children_layouts[3];
|
||||
children_layouts[0] = m_operands[0]->createLayout(floatDisplayMode, complexFormat);
|
||||
char string[2] = {'-', '\0'};
|
||||
children_layouts[1] = new StringLayout(string, 1);
|
||||
|
||||
@@ -50,7 +50,7 @@ float Sum::privateApproximate(Context& context, AngleUnit angleUnit) const {
|
||||
ExpressionLayout * Sum::privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const {
|
||||
assert(floatDisplayMode != FloatDisplayMode::Default);
|
||||
assert(complexFormat != ComplexFormat::Default);
|
||||
ExpressionLayout ** childrenLayouts = (ExpressionLayout **)malloc(2*sizeof(ExpressionLayout *));
|
||||
ExpressionLayout * childrenLayouts[2];
|
||||
childrenLayouts[0] = new StringLayout("n=", 2);
|
||||
childrenLayouts[1] = m_args[1]->createLayout(floatDisplayMode, complexFormat);
|
||||
return new SumLayout(new HorizontalLayout(childrenLayouts, 2), m_args[2]->createLayout(floatDisplayMode, complexFormat), m_args[0]->createLayout(floatDisplayMode, complexFormat));
|
||||
|
||||
Reference in New Issue
Block a user