diff --git a/kandinsky/fonts/LargeSourcePixel.ttf b/kandinsky/fonts/LargeSourcePixel.ttf index db90c796e..9cc44fbb1 100644 Binary files a/kandinsky/fonts/LargeSourcePixel.ttf and b/kandinsky/fonts/LargeSourcePixel.ttf differ diff --git a/kandinsky/fonts/SmallSourcePixel.ttf b/kandinsky/fonts/SmallSourcePixel.ttf index 5acc17fca..239c7607a 100644 Binary files a/kandinsky/fonts/SmallSourcePixel.ttf and b/kandinsky/fonts/SmallSourcePixel.ttf differ diff --git a/poincare/Makefile b/poincare/Makefile index e1891c279..542dfcdd2 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -15,6 +15,9 @@ objs += $(addprefix poincare/src/,\ fraction.o\ function.o\ global_context.o\ + hyperbolic_cosine.o\ + hyperbolic_sine.o\ + hyperbolic_tangent.o\ integer.o\ integral.o\ list_data.o\ diff --git a/poincare/include/poincare.h b/poincare/include/poincare.h index 809cfd181..351162662 100644 --- a/poincare/include/poincare.h +++ b/poincare/include/poincare.h @@ -11,6 +11,9 @@ #include #include #include +#include +#include +#include #include #include #include diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index e1735af4a..517538fb1 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -15,6 +15,9 @@ class Expression { Cosine, Derivative, Float, + HyperbolicCosine, + HyperbolicSine, + HyperbolicTangent, Integer, Integral, Logarithm, diff --git a/poincare/include/poincare/hyperbolic_cosine.h b/poincare/include/poincare/hyperbolic_cosine.h new file mode 100644 index 000000000..740fec627 --- /dev/null +++ b/poincare/include/poincare/hyperbolic_cosine.h @@ -0,0 +1,16 @@ +#ifndef POINCARE_HYPERBOLIC_COSINE_H +#define POINCARE_HYPERBOLIC_COSINE_H + +#include + +class HyperbolicCosine : public Function { +public: + HyperbolicCosine(); + float approximate(Context & context, AngleUnit angleUnit = AngleUnit::Radian) const override; + Type type() const override; + Expression * cloneWithDifferentOperands(Expression ** newOperands, + int numberOfOperands, bool cloneOperands = true) const override; + Expression * evaluate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override; +}; + +#endif diff --git a/poincare/include/poincare/hyperbolic_sine.h b/poincare/include/poincare/hyperbolic_sine.h new file mode 100644 index 000000000..baabf0421 --- /dev/null +++ b/poincare/include/poincare/hyperbolic_sine.h @@ -0,0 +1,16 @@ +#ifndef POINCARE_HYPERBOLIC_SINE_H +#define POINCARE_HYPERBOLIC_SINE_H + +#include + +class HyperbolicSine : public Function { +public: + HyperbolicSine(); + float approximate(Context & context, AngleUnit angleUnit = AngleUnit::Radian) const override; + Type type() const override; + Expression * cloneWithDifferentOperands(Expression ** newOperands, + int numberOfOperands, bool cloneOperands = true) const override; + Expression * evaluate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override; +}; + +#endif diff --git a/poincare/include/poincare/hyperbolic_tangent.h b/poincare/include/poincare/hyperbolic_tangent.h new file mode 100644 index 000000000..6db771ed9 --- /dev/null +++ b/poincare/include/poincare/hyperbolic_tangent.h @@ -0,0 +1,16 @@ +#ifndef POINCARE_HYPERBOLIC_TANGENT_H +#define POINCARE_HYPERBOLIC_TANGENT_H + +#include + +class HyperbolicTangent : public Function { +public: + HyperbolicTangent(); + float approximate(Context & context, AngleUnit angleUnit = AngleUnit::Radian) const override; + Type type() const override; + Expression * cloneWithDifferentOperands(Expression ** newOperands, + int numberOfOperands, bool cloneOperands = true) const override; + Expression * evaluate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override; +}; + +#endif diff --git a/poincare/src/expression_lexer.l b/poincare/src/expression_lexer.l index 40b966d46..e9bddd8ec 100644 --- a/poincare/src/expression_lexer.l +++ b/poincare/src/expression_lexer.l @@ -88,9 +88,12 @@ abs { poincare_expression_yylval.expression = new AbsoluteValue(); return FUNCTI diff { poincare_expression_yylval.expression = new Derivative(); return FUNCTION; } ans { poincare_expression_yylval.character = Symbol::SpecialSymbols::Ans; return SYMBOL; } sin { poincare_expression_yylval.expression = new Sine(); return FUNCTION; } +sinh { poincare_expression_yylval.expression = new HyperbolicSine(); return FUNCTION; } cos { poincare_expression_yylval.expression = new Cosine(); return FUNCTION; } +cosh { poincare_expression_yylval.expression = new HyperbolicCosine(); return FUNCTION; } int { poincare_expression_yylval.expression = new Integral(); return FUNCTION; } tan { poincare_expression_yylval.expression = new Tangent(); return FUNCTION; } +tanh { poincare_expression_yylval.expression = new HyperbolicTangent(); return FUNCTION; } log { poincare_expression_yylval.expression = new Logarithm(); return FUNCTION; } ln { poincare_expression_yylval.expression = new NaperianLogarithm(); return FUNCTION; } root { poincare_expression_yylval.expression = new NthRoot(); return FUNCTION; } diff --git a/poincare/src/hyperbolic_cosine.cpp b/poincare/src/hyperbolic_cosine.cpp new file mode 100644 index 000000000..c2b3b3a57 --- /dev/null +++ b/poincare/src/hyperbolic_cosine.cpp @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include +#include +extern "C" { +#include +#include +} + +HyperbolicCosine::HyperbolicCosine() : + Function("cosh") +{ +} + +Expression::Type HyperbolicCosine::type() const { + return Type::HyperbolicCosine; +} + +Expression * HyperbolicCosine::cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands) const { + assert(numberOfOperands == 1); + assert(newOperands != nullptr); + HyperbolicCosine * hc = new HyperbolicCosine(); + hc->setArgument(newOperands, numberOfOperands, cloneOperands); + return hc; +} + +float HyperbolicCosine::approximate(Context& context, AngleUnit angleUnit) const { + return (expf(m_args[0]->approximate(context, angleUnit))+expf(-m_args[0]->approximate(context, angleUnit)))/2.0f; +} + +Expression * HyperbolicCosine::evaluate(Context& context, AngleUnit angleUnit) const { + Expression * evaluation = m_args[0]->evaluate(context, angleUnit); + assert(evaluation->type() == Type::Matrix || evaluation->type() == Type::Complex); + if (evaluation->type() == Type::Matrix) { + delete evaluation; + return new Complex(NAN); + } + Expression * arguments[2]; + arguments[0] = new Complex(M_E); + arguments[1] = evaluation; + Expression * exp1 = new Power(arguments, true); + arguments[1] = new Opposite(evaluation, true); + Expression * exp2 = new Power(arguments, true); + delete arguments[1]; + delete arguments[0]; + delete evaluation; + arguments[0] = exp1; + arguments[1] = exp2; + Expression * sum = new Addition(arguments, true); + delete exp1; + delete exp2; + arguments[0] = sum; + arguments[1] = new Complex(2.0f); + Expression * result = new Fraction(arguments, true); + delete arguments[1]; + delete arguments[0]; + Expression * resultEvaluation = result->evaluate(context, angleUnit); + delete result; + return resultEvaluation; +} diff --git a/poincare/src/hyperbolic_sine.cpp b/poincare/src/hyperbolic_sine.cpp new file mode 100644 index 000000000..c07849be4 --- /dev/null +++ b/poincare/src/hyperbolic_sine.cpp @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include +#include +extern "C" { +#include +#include +} + +HyperbolicSine::HyperbolicSine() : + Function("sinh") +{ +} + +Expression::Type HyperbolicSine::type() const { + return Type::HyperbolicSine; +} + +Expression * HyperbolicSine::cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands) const { + assert(numberOfOperands == 1); + assert(newOperands != nullptr); + HyperbolicSine * hs = new HyperbolicSine(); + hs->setArgument(newOperands, numberOfOperands, cloneOperands); + return hs; +} + +float HyperbolicSine::approximate(Context& context, AngleUnit angleUnit) const { + return (expf(m_args[0]->approximate(context, angleUnit))-expf(-m_args[0]->approximate(context, angleUnit)))/2.0f; +} + +Expression * HyperbolicSine::evaluate(Context& context, AngleUnit angleUnit) const { + Expression * evaluation = m_args[0]->evaluate(context, angleUnit); + assert(evaluation->type() == Type::Matrix || evaluation->type() == Type::Complex); + if (evaluation->type() == Type::Matrix) { + delete evaluation; + return new Complex(NAN); + } + Expression * arguments[2]; + arguments[0] = new Complex(M_E); + arguments[1] = evaluation; + Expression * exp1 = new Power(arguments, true); + arguments[1] = new Opposite(evaluation, true); + Expression * exp2 = new Power(arguments, true); + delete arguments[1]; + delete arguments[0]; + delete evaluation; + arguments[0] = exp1; + arguments[1] = exp2; + Expression * sub = new Subtraction(arguments, true); + delete exp1; + delete exp2; + arguments[0] = sub; + arguments[1] = new Complex(2.0f); + Expression * result = new Fraction(arguments, true); + delete arguments[1]; + delete arguments[0]; + Expression * resultEvaluation = result->evaluate(context, angleUnit); + delete result; + return resultEvaluation; +} diff --git a/poincare/src/hyperbolic_tangent.cpp b/poincare/src/hyperbolic_tangent.cpp new file mode 100644 index 000000000..d122e99fd --- /dev/null +++ b/poincare/src/hyperbolic_tangent.cpp @@ -0,0 +1,53 @@ +#include +#include +#include +#include +#include +extern "C" { +#include +#include +} + +HyperbolicTangent::HyperbolicTangent() : + Function("tanh") +{ +} + +Expression::Type HyperbolicTangent::type() const { + return Type::HyperbolicTangent; +} + +Expression * HyperbolicTangent::cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands) const { + assert(numberOfOperands == 1); + assert(newOperands != nullptr); + HyperbolicTangent * ht = new HyperbolicTangent(); + ht->setArgument(newOperands, numberOfOperands, cloneOperands); + return ht; +} + +float HyperbolicTangent::approximate(Context& context, AngleUnit angleUnit) const { + return (expf(m_args[0]->approximate(context, angleUnit))-expf(-m_args[0]->approximate(context, angleUnit)))/ + (expf(m_args[0]->approximate(context, angleUnit))+expf(-m_args[0]->approximate(context, angleUnit))); +} + +Expression * HyperbolicTangent::evaluate(Context& context, AngleUnit angleUnit) const { + Expression * evaluation = m_args[0]->evaluate(context, angleUnit); + assert(evaluation->type() == Type::Matrix || evaluation->type() == Type::Complex); + if (evaluation->type() == Type::Matrix) { + delete evaluation; + return new Complex(NAN); + } + Expression * arguments[2]; + arguments[0] = new HyperbolicSine(); + ((Function *)arguments[0])->setArgument(&evaluation, 1, true); + arguments[1] = new HyperbolicCosine(); + ((Function *)arguments[1])->setArgument(&evaluation, 1, true); + delete evaluation; + Expression * result = new Fraction(arguments, true); + delete arguments[1]; + delete arguments[0]; + Expression * resultEvaluation = result->evaluate(context, angleUnit); + delete result; + return resultEvaluation; +}