Merge changes If0640ecd,Idd8545cf,Iae352e67,I44329fb7

* changes:
  [ion]  Correct event text in events
  [poincare] Parse "3->A" (sto)
  [apps][poincare] Add a submenu to toolbox about fluctuation intervals
  [poincare] Add tests on symbols
This commit is contained in:
Émilie Feral
2017-03-16 17:37:08 +01:00
committed by Gerrit
17 changed files with 347 additions and 9 deletions

View File

@@ -15,13 +15,15 @@ const ToolboxNode matricesChildren[5] = {ToolboxNode("inverse()", "Inverse"), To
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")};
const ToolboxNode trigonometryChildren[6] = {ToolboxNode("cosh()", "cosh"), ToolboxNode("sinh()", "sinh"), ToolboxNode("tanh()", "tanh"), ToolboxNode("acosh()", "acosh"), ToolboxNode("asinh()", "asinh"), ToolboxNode("atanh()", "atanh")};
const ToolboxNode predictionChildren[3] = {ToolboxNode("prediction95(,)", "Intervalle fluctuation 95%"), ToolboxNode("prediction(,)", "Intervalle fluctuation simple"), ToolboxNode("confidence(,)", "Intervalle de confiance")};
const ToolboxNode menu[11] = {ToolboxNode("abs()", "Valeur absolue"), ToolboxNode("root(,)", "Racine k-ieme"), ToolboxNode("log(,)", "Logarithme base a"),
const ToolboxNode menu[12] = {ToolboxNode("abs()", "Valeur absolue"), ToolboxNode("root(,)", "Racine k-ieme"), ToolboxNode("log(,)", "Logarithme base a"),
ToolboxNode("Calcul", nullptr, calculChildren, 4), ToolboxNode("Nombre complexe", nullptr, complexChildren, 5),
ToolboxNode("Probabilite", nullptr, probabilityChildren, 2), ToolboxNode("Arithmetique", nullptr, arithmeticChildren, 4),
ToolboxNode("Matrice", nullptr, matricesChildren, 5), ToolboxNode("Liste", nullptr, listesChildren, 5),
ToolboxNode("Approximation", nullptr, approximationChildren, 4), ToolboxNode("Trigonometrie hyperbolique", nullptr, trigonometryChildren, 6)};
const ToolboxNode toolboxModel = ToolboxNode("Toolbox", nullptr, menu, 11);
ToolboxNode("Approximation", nullptr, approximationChildren, 4), ToolboxNode("Trigonometrie hyperbolique", nullptr, trigonometryChildren, 6),
ToolboxNode("Intervalle fluctuation", nullptr, predictionChildren, 3)};
const ToolboxNode toolboxModel = ToolboxNode("Toolbox", nullptr, menu, 12);
/* State */

View File

@@ -28,6 +28,8 @@ static constexpr const char k_pi[2] = {Ion::Charset::SmallPi, 0};
static constexpr const char k_root[4] = {Ion::Charset::Root, '(', ')', 0};
static constexpr const char k_complexI[2] = {Ion::Charset::IComplex, 0};
static constexpr const char k_exponential[5] = {Ion::Charset::Exponential, '^', '(', ')', 0};
static constexpr const char k_sto[2] = {Ion::Charset::Sto, 0};
static constexpr const char k_exponent[2] = {Ion::Charset::Exponent, 0};
static constexpr EventData s_dataForEvent[] = {
// Plain
@@ -39,12 +41,12 @@ static constexpr EventData s_dataForEvent[] = {
T("7"), T("8"), T("9"), T("("), T(")"), U(),
T("4"), T("5"), T("6"), T("*"), T("/"), U(),
T("1"), T("2"), T("3"), T("+"), T("-"), U(),
T("0"), T("."), T("E"), TL(), TL(), U(),
T("0"), T("."), T(k_exponent), TL(), TL(), U(),
// Shift
U(), U(), U(), U(), U(), U(),
U(), U(), U(), U(), U(), U(),
U(), U(), TL(), TL(), TL(), TL(),
T("["), T("]"), T("{"), T("}"), T("_"), T("sto"),
T("["), T("]"), T("{"), T("}"), T("_"), T(k_sto),
T("asin()"), T("acos()"), T("atan()"), T("="), T("<"), T(">"),
U(), U(), TL(), TL(), TL(), TL(),
U(), U(), TL(), TL(), TL(), TL(),

View File

@@ -13,6 +13,7 @@ objs += $(addprefix poincare/src/,\
ceiling.o\
complex.o\
complex_argument.o\
confidence_interval.o\
conjugate.o\
cosine.o\
derivative.o\
@@ -54,12 +55,14 @@ objs += $(addprefix poincare/src/,\
parenthesis.o\
permute_coefficient.o\
power.o\
prediction_interval.o\
preferences.o\
product.o\
reel_part.o\
round.o\
sine.o\
square_root.o\
store.o\
subtraction.o\
sum.o\
symbol.o\
@@ -98,6 +101,7 @@ tests += $(addprefix poincare/test/,\
power.cpp\
simplify_utils.cpp\
subtraction.cpp\
symbol.cpp\
trigo.cpp\
)

View File

@@ -10,6 +10,7 @@
#include <poincare/ceiling.h>
#include <poincare/complex.h>
#include <poincare/complex_argument.h>
#include <poincare/confidence_interval.h>
#include <poincare/conjugate.h>
#include <poincare/context.h>
#include <poincare/cosine.h>
@@ -47,12 +48,14 @@
#include <poincare/parenthesis.h>
#include <poincare/permute_coefficient.h>
#include <poincare/power.h>
#include <poincare/prediction_interval.h>
#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/store.h>
#include <poincare/subtraction.h>
#include <poincare/sum.h>
#include <poincare/symbol.h>

View File

@@ -0,0 +1,22 @@
#ifndef POINCARE_CONFIDENCE_INTERVAL_H
#define POINCARE_CONFIDENCE_INTERVAL_H
#include <poincare/function.h>
namespace Poincare {
class ConfidenceInterval : public Function {
public:
ConfidenceInterval();
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

@@ -20,6 +20,7 @@ public:
Ceiling,
Complex,
ComplexArgument,
ConfidenceInterval,
Conjugate,
Cosine,
Derivative,
@@ -50,6 +51,7 @@ public:
NaperianLogarithm,
NthRoot,
Opposite,
PredictionInterval,
Fraction,
Parenthesis,
PermuteCoefficient,
@@ -59,6 +61,7 @@ public:
Round,
Sine,
SquareRoot,
Store,
Sum,
Subtraction,
Symbol,

View File

@@ -13,6 +13,7 @@ class Integer;
class GlobalContext : public Context {
public:
GlobalContext();
~GlobalContext();
/* The expression recorded in global context is already a final expression.
* Otherwise, we would need the context and the angle unit to evaluate it */
const Expression * expressionForSymbol(const Symbol * symbol) override;

View File

@@ -0,0 +1,22 @@
#ifndef POINCARE_PREDICTION_INTERVAL_H
#define POINCARE_PREDICTION_INTERVAL_H
#include <poincare/function.h>
namespace Poincare {
class PredictionInterval : public Function {
public:
PredictionInterval();
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,29 @@
#ifndef POINCARE_STORE_H
#define POINCARE_STORE_H
#include <poincare/expression.h>
#include <poincare/symbol.h>
namespace Poincare {
class Store : public Expression {
public:
Store(Symbol * symbol, Expression * value, bool clone = true);
~Store();
Type type() const override;
const Expression * operand(int i) const override;
int numberOfOperands() const override;
Expression * clone() const override;
Expression * cloneWithDifferentOperands(Expression ** newOperands,
int numberOfOperands, bool cloneOperands = true) const override;
private:
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
Expression * privateEvaluate(Context& context, AngleUnit angleUnit) const override;
float privateApproximate(Context& context, AngleUnit angleUnit) const override;
Symbol * m_symbol;
Expression * m_value;
};
}
#endif

View File

@@ -0,0 +1,44 @@
#include <poincare/confidence_interval.h>
#include <poincare/matrix.h>
extern "C" {
#include <assert.h>
#include <math.h>
}
namespace Poincare {
ConfidenceInterval::ConfidenceInterval() :
Function("confidence")
{
}
Expression::Type ConfidenceInterval::type() const {
return Type::ConfidenceInterval;
}
Expression * ConfidenceInterval::cloneWithDifferentOperands(Expression** newOperands,
int numberOfOperands, bool cloneOperands) const {
assert(numberOfOperands == 1);
assert(newOperands != nullptr);
ConfidenceInterval * ci = new ConfidenceInterval();
ci->setArgument(newOperands, numberOfOperands, cloneOperands);
return ci;
}
float ConfidenceInterval::privateApproximate(Context& context, AngleUnit angleUnit) const {
assert(angleUnit != AngleUnit::Default);
return NAN;
}
Expression * ConfidenceInterval::privateEvaluate(Context& context, AngleUnit angleUnit) const {
assert(angleUnit != AngleUnit::Default);
float f = m_args[0]->approximate(context, angleUnit);
float n = m_args[1]->approximate(context, angleUnit);
Expression * operands[2];
operands[0] = new Complex(Complex::Float(f - 1.0f/sqrtf(n)));
operands[1] = new Complex(Complex::Float(f + 1.0f/sqrtf(n)));
return new Matrix(new MatrixData(operands, 2, 2, 1, false));
}
}

View File

@@ -1,6 +1,7 @@
#include <poincare/expression.h>
#include <poincare/preferences.h>
#include <poincare/function.h>
#include <poincare/symbol.h>
#include <poincare/list_data.h>
#include <poincare/matrix_data.h>
#include "expression_parser.hpp"

View File

@@ -100,6 +100,7 @@ atan { poincare_expression_yylval.expression = new ArcTangent(); return FUNCTION
atanh { poincare_expression_yylval.expression = new HyperbolicArcTangent(); return FUNCTION; }
binomial { poincare_expression_yylval.expression = new BinomialCoefficient(); return FUNCTION; }
ceil { poincare_expression_yylval.expression = new Ceiling(); return FUNCTION; }
confidence { poincare_expression_yylval.expression = new ConfidenceInterval(); 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; }
@@ -116,6 +117,8 @@ lcm { poincare_expression_yylval.expression = new LeastCommonMultiple(); return
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; }
prediction95 { poincare_expression_yylval.expression = new PredictionInterval(); return FUNCTION; }
prediction { poincare_expression_yylval.expression = new ConfidenceInterval(); 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; }
@@ -134,6 +137,7 @@ transpose { poincare_expression_yylval.expression = new MatrixTranspose(); retur
\x90 { poincare_expression_yylval.expression = new SquareRoot(); return FUNCTION; }
\x8b { return ICOMPLEX; }
\x8e { poincare_expression_yylval.character = yytext[0]; return SYMBOL; }
\x8f { return STO; }
\+ { return PLUS; }
\- { return MINUS; }
\* { return MULTIPLY; }

View File

@@ -29,6 +29,7 @@ void poincare_expression_yyerror(Poincare::Expression ** expressionOutput, char
* be useful to retrieve the value of Integers for example). */
%union {
Poincare::Expression * expression;
Poincare::Symbol * symbol;
Poincare::ListData * listData;
Poincare::MatrixData * matrixData;
Poincare::Function * function;
@@ -49,7 +50,6 @@ void poincare_expression_yyerror(Poincare::Expression ** expressionOutput, char
%token <string> DIGITS
%token <character> SYMBOL
%token <function> FUNCTION
%token <complex> ICOMPLEX
/* Operator tokens */
%token PLUS
@@ -66,6 +66,8 @@ void poincare_expression_yyerror(Poincare::Expression ** expressionOutput, char
%token COMMA
%token DOT
%token EE
%token ICOMPLEX
%token STO
/* Make the operators left associative.
* This makes 1 - 2 - 5 be (1 - 2) - 5 instead of 1 - (2 - 5).
@@ -80,6 +82,7 @@ void poincare_expression_yyerror(Poincare::Expression ** expressionOutput, char
* If you need to define precedence in order to avoid shift/redice conflicts for
* other situations your grammar is most likely ambiguous.
*/
%left STO
%left PLUS
%left MINUS
%left MULTIPLY
@@ -89,6 +92,7 @@ void poincare_expression_yyerror(Poincare::Expression ** expressionOutput, char
/* The "exp" symbol uses the "expression" part of the union. */
%type <expression> exp;
%type <expression> number;
%type <symbol> symb;
%type <listData> lstData;
%type <matrixData> mtxData;
@@ -119,10 +123,14 @@ number:
| DOT DIGITS EE MINUS DIGITS { $$ = new Poincare::Complex(nullptr, 0, false, $2.address, $2.length, $5.address, $5.length, true); }
| DIGITS DOT DIGITS EE MINUS DIGITS { $$ = new Poincare::Complex($1.address, $1.length, false, $3.address, $3.length, $6.address, $6.length, true); }
symb:
SYMBOL { $$ = new Poincare::Symbol($1); }
exp:
number { $$ = $1; }
exp STO symb {$$ = new Poincare::Store($3, $1, false); }
| number { $$ = $1; }
| ICOMPLEX { $$ = new Poincare::Complex(Poincare::Complex::Cartesian(0.0f, 1.0f)); }
| SYMBOL { $$ = new Poincare::Symbol($1); }
| symb { $$ = $1; }
| exp PLUS exp { Poincare::Expression * terms[2] = {$1,$3}; $$ = new Poincare::Addition(terms, false); }
| exp MINUS exp { Poincare::Expression * terms[2] = {$1,$3}; $$ = new Poincare::Subtraction(terms, false); }
| exp MULTIPLY exp { Poincare::Expression * terms[2] = {$1,$3}; $$ = new Poincare::Multiplication(terms, false); }

View File

@@ -14,6 +14,15 @@ GlobalContext::GlobalContext() :
}
}
GlobalContext::~GlobalContext() {
for (int i = 0; i < k_maxNumberOfScalarExpressions; i++) {
if (m_expressions[i] != nullptr) {
delete m_expressions[i];
}
m_expressions[i] = nullptr;
}
}
Complex * GlobalContext::defaultExpression() {
static Complex * defaultExpression = new Complex(Complex::Float(0.0f));
return defaultExpression;
@@ -44,7 +53,11 @@ const Expression * GlobalContext::expressionForSymbol(const Symbol * symbol) {
void GlobalContext::setExpressionForSymbolName(Expression * expression, const Symbol * symbol) {
int index = symbolIndex(symbol);
assert(expression->type() == Expression::Type::Complex);
m_expressions[index] = expression;
if (m_expressions[index] != nullptr) {
delete m_expressions[index];
m_expressions[index] = nullptr;
}
m_expressions[index] = expression->clone();
}
}

View File

@@ -0,0 +1,44 @@
#include <poincare/prediction_interval.h>
#include <poincare/matrix.h>
extern "C" {
#include <assert.h>
#include <math.h>
}
namespace Poincare {
PredictionInterval::PredictionInterval() :
Function("prediction95")
{
}
Expression::Type PredictionInterval::type() const {
return Type::PredictionInterval;
}
Expression * PredictionInterval::cloneWithDifferentOperands(Expression** newOperands,
int numberOfOperands, bool cloneOperands) const {
assert(numberOfOperands == 1);
assert(newOperands != nullptr);
PredictionInterval * pi = new PredictionInterval();
pi->setArgument(newOperands, numberOfOperands, cloneOperands);
return pi;
}
float PredictionInterval::privateApproximate(Context& context, AngleUnit angleUnit) const {
assert(angleUnit != AngleUnit::Default);
return NAN;
}
Expression * PredictionInterval::privateEvaluate(Context& context, AngleUnit angleUnit) const {
assert(angleUnit != AngleUnit::Default);
float p = m_args[0]->approximate(context, angleUnit);
float n = m_args[1]->approximate(context, angleUnit);
Expression * operands[2];
operands[0] = new Complex(Complex::Float(p - 1.96f*sqrtf(p*(1-p))/sqrtf(n)));
operands[1] = new Complex(Complex::Float(p + 1.96f*sqrtf(p*(1-p))/sqrtf(n)));
return new Matrix(new MatrixData(operands, 2, 2, 1, false));
}
}

82
poincare/src/store.cpp Normal file
View File

@@ -0,0 +1,82 @@
extern "C" {
#include <assert.h>
#include <stdlib.h>
}
#include <poincare/store.h>
#include <ion.h>
#include <poincare/complex.h>
#include <poincare/context.h>
#include "layout/horizontal_layout.h"
#include "layout/string_layout.h"
namespace Poincare {
Store::Store(Symbol * symbol, Expression * value, bool clone) :
m_symbol(symbol),
m_value(value)
{
if (clone) {
m_symbol = (Symbol *)symbol->clone();
m_value = value->clone();
}
}
Store::~Store() {
delete m_symbol;
delete m_value;
}
Expression::Type Store::type() const {
return Type::Store;
}
const Expression * Store::operand(int i) const {
if (i == 0) {
return m_symbol;
}
return m_value;
}
int Store::numberOfOperands() const {
return 2;
}
Expression * Store::clone() const {
Expression * newOperands[2];
newOperands[0] = m_symbol;
newOperands[1] = m_value;
return this->cloneWithDifferentOperands(newOperands, 2, true);
}
Expression * Store::cloneWithDifferentOperands(Expression ** newOperands, int numberOfOperands, bool cloneOperands) const {
assert(numberOfOperands == 2);
assert(newOperands != nullptr);
assert(newOperands[0]->type() == Type::Symbol);
return new Store((Symbol *)newOperands[0], newOperands[1], cloneOperands);
}
ExpressionLayout * Store::privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const {
assert(floatDisplayMode != FloatDisplayMode::Default);
assert(complexFormat != ComplexFormat::Default);
ExpressionLayout * childrenLayouts[3];
childrenLayouts[0] = m_value->createLayout(floatDisplayMode, complexFormat);
const char stoSymbol[2] = {Ion::Charset::Sto, 0};
childrenLayouts[1] = new StringLayout(stoSymbol, 1);
childrenLayouts[2] = m_symbol->createLayout(floatDisplayMode, complexFormat);
return new HorizontalLayout(childrenLayouts, 3);
}
Expression * Store::privateEvaluate(Context& context, AngleUnit angleUnit) const {
assert(angleUnit != AngleUnit::Default);
Expression * valueEvaluation = m_value->evaluate(context, angleUnit);
context.setExpressionForSymbolName(valueEvaluation, m_symbol);
return valueEvaluation;
}
float Store::privateApproximate(Context& context, AngleUnit angleUnit) const {
assert(angleUnit != AngleUnit::Default);
return NAN;
}
}

54
poincare/test/symbol.cpp Normal file
View File

@@ -0,0 +1,54 @@
#include <quiz.h>
#include <poincare.h>
#include <math.h>
#include <ion.h>
#include <assert.h>
using namespace Poincare;
QUIZ_CASE(poincare_parse_symbol) {
char piText[2] = {Ion::Charset::SmallPi, 0};
Expression * e = Expression::parse(piText);
assert(e->type() == Expression::Type::Symbol);
delete e;
char eText[2] = {Ion::Charset::Exponential, 0};
e = Expression::parse(eText);
assert(e->type() == Expression::Type::Symbol);
delete e;
char iText[10] = {Ion::Charset::IComplex, 0};
e = Expression::parse(iText);
assert(e->type() == Expression::Type::Complex);
delete e;
char floatText[10] = {'1', '.', '2', Ion::Charset::Exponent, '3', 0};
e = Expression::parse(floatText);
assert(e->type() == Expression::Type::Complex);
delete e;
e = Expression::parse("ans");
assert(e->type() == Expression::Type::Symbol);
delete e;
}
QUIZ_CASE(poincare_symbol_approximate) {
GlobalContext globalContext;
char piText[2] = {Ion::Charset::SmallPi, 0};
Expression * e = Expression::parse(piText);
assert(fabsf(e->approximate(globalContext)-M_PI) <= 0.0001f);
delete e;
char eText[2] = {Ion::Charset::Exponential, 0};
e = Expression::parse(eText);
assert(fabsf(e->approximate(globalContext)-M_E) <= 0.0001f);
delete e;
char floatText[10] = {'1', '.', '2', Ion::Charset::Exponent, '3', 0};
e = Expression::parse(floatText);
assert(fabsf(e->approximate(globalContext)-1200.0f) <= 0.0001f);
delete e;
}