[poincare] Create a class hyperbolic tangent

Change-Id: Ib810a31912d3d0f5e32dae31acb792dae8315d4a
This commit is contained in:
Émilie Feral
2017-02-03 11:13:12 +01:00
parent 74f722efb9
commit 1adc5fa38d
6 changed files with 73 additions and 0 deletions

View File

@@ -17,6 +17,7 @@ objs += $(addprefix poincare/src/,\
global_context.o\
hyperbolic_cosine.o\
hyperbolic_sine.o\
hyperbolic_tangent.o\
integer.o\
integral.o\
list_data.o\

View File

@@ -13,6 +13,7 @@
#include <poincare/global_context.h>
#include <poincare/hyperbolic_cosine.h>
#include <poincare/hyperbolic_sine.h>
#include <poincare/hyperbolic_tangent.h>
#include <poincare/integer.h>
#include <poincare/integral.h>
#include <poincare/list_data.h>

View File

@@ -17,6 +17,7 @@ class Expression {
Float,
HyperbolicCosine,
HyperbolicSine,
HyperbolicTangent,
Integer,
Integral,
Logarithm,

View File

@@ -0,0 +1,16 @@
#ifndef POINCARE_HYPERBOLIC_TANGENT_H
#define POINCARE_HYPERBOLIC_TANGENT_H
#include <poincare/function.h>
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

View File

@@ -93,6 +93,7 @@ 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; }

View File

@@ -0,0 +1,53 @@
#include <poincare/hyperbolic_tangent.h>
#include <poincare/hyperbolic_cosine.h>
#include <poincare/hyperbolic_sine.h>
#include <poincare/complex.h>
#include <poincare/fraction.h>
extern "C" {
#include <assert.h>
#include <math.h>
}
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;
}