From 5c443e04120233170b5ca4e06018c2aa290f5563 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Mon, 26 Aug 2019 10:44:19 +0200 Subject: [PATCH] [poincare/normal_distribution_function] Factorize code in parent class --- poincare/Makefile | 1 + poincare/include/poincare/expression.h | 3 +- poincare/include/poincare/inv_norm.h | 10 ++--- poincare/include/poincare/norm_cdf.h | 14 ++----- poincare/include/poincare/norm_cdf2.h | 14 ++----- poincare/include/poincare/norm_pdf.h | 14 ++----- .../poincare/normal_distribution_function.h | 26 ++++++++++++ poincare/src/inv_norm.cpp | 16 ++------ poincare/src/norm_cdf.cpp | 29 ------------- poincare/src/norm_cdf2.cpp | 29 ------------- poincare/src/norm_pdf.cpp | 28 ------------- poincare/src/normal_distribution_function.cpp | 41 +++++++++++++++++++ 12 files changed, 89 insertions(+), 136 deletions(-) create mode 100644 poincare/include/poincare/normal_distribution_function.h create mode 100644 poincare/src/normal_distribution_function.cpp diff --git a/poincare/Makefile b/poincare/Makefile index 049e6db31..7e103af34 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -99,6 +99,7 @@ poincare_src += $(addprefix poincare/src/,\ norm_cdf.cpp \ norm_cdf2.cpp \ norm_pdf.cpp \ + normal_distribution_function.cpp \ nth_root.cpp \ number.cpp \ opposite.cpp \ diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index b5c033ad2..10ada5808 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -66,9 +66,10 @@ class Expression : public TreeHandle { friend class Multiplication; friend class MultiplicationNode; friend class NaperianLogarithm; - friend class NormPDF; + friend class NormalDistributionFunction; friend class NormCDF; friend class NormCDF2; + friend class NormPDF; friend class NthRoot; friend class Number; friend class Opposite; diff --git a/poincare/include/poincare/inv_norm.h b/poincare/include/poincare/inv_norm.h index 8a25ef037..edf0a60a6 100644 --- a/poincare/include/poincare/inv_norm.h +++ b/poincare/include/poincare/inv_norm.h @@ -2,11 +2,11 @@ #define POINCARE_INV_NORM_H #include -#include +#include namespace Poincare { -class InvNormNode final : public ExpressionNode { +class InvNormNode final : public NormalDistributionFunctionNode { public: // TreeNode @@ -28,8 +28,6 @@ private: // Simplication Expression shallowReduce(ReductionContext reductionContext) override; - LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; }; - LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } // Evaluation Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } @@ -37,9 +35,9 @@ private: template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; -class InvNorm final : public Expression { +class InvNorm final : public NormalDistributionFunction { public: - InvNorm(const InvNormNode * n) : Expression(n) {} + InvNorm(const InvNormNode * n) : NormalDistributionFunction(n) {} static InvNorm Builder(Expression child0, Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1, child2).array(), 3); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("invnorm", 3, &UntypedBuilderThreeChildren); Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); diff --git a/poincare/include/poincare/norm_cdf.h b/poincare/include/poincare/norm_cdf.h index 7a92ce7e7..f6d117547 100644 --- a/poincare/include/poincare/norm_cdf.h +++ b/poincare/include/poincare/norm_cdf.h @@ -2,11 +2,11 @@ #define POINCARE_NORM_CDF_H #include -#include +#include namespace Poincare { -class NormCDFNode final : public ExpressionNode { +class NormCDFNode final : public NormalDistributionFunctionNode { public: // TreeNode @@ -28,23 +28,17 @@ private: Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; - // Simplication - Expression shallowReduce(ReductionContext reductionContext) override; - LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; }; - LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } - // Evaluation Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; -class NormCDF final : public Expression { +class NormCDF final : public NormalDistributionFunction { public: - NormCDF(const NormCDFNode * n) : Expression(n) {} + NormCDF(const NormCDFNode * n) : NormalDistributionFunction(n) {} static NormCDF Builder(Expression child0, Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1, child2).array(), 3); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("normcdf", 3, &UntypedBuilderThreeChildren); - Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; } diff --git a/poincare/include/poincare/norm_cdf2.h b/poincare/include/poincare/norm_cdf2.h index c2e2e6587..cb02dc4b0 100644 --- a/poincare/include/poincare/norm_cdf2.h +++ b/poincare/include/poincare/norm_cdf2.h @@ -2,11 +2,11 @@ #define POINCARE_NORM_CDF2_H #include -#include +#include namespace Poincare { -class NormCDF2Node final : public ExpressionNode { +class NormCDF2Node final : public NormalDistributionFunctionNode { public: // TreeNode @@ -28,23 +28,17 @@ private: Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; - // Simplication - Expression shallowReduce(ReductionContext reductionContext) override; - LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; }; - LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } - // Evaluation Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; -class NormCDF2 final : public Expression { +class NormCDF2 final : public NormalDistributionFunction { public: - NormCDF2(const NormCDF2Node * n) : Expression(n) {} + NormCDF2(const NormCDF2Node * n) : NormalDistributionFunction(n) {} static NormCDF2 Builder(Expression child0, Expression child1, Expression child2, Expression child3) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1, child2, child3).array(), 4); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("normcdf2", 4, &UntypedBuilderFourChildren); - Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; } diff --git a/poincare/include/poincare/norm_pdf.h b/poincare/include/poincare/norm_pdf.h index b5b375819..e7c8ac58c 100644 --- a/poincare/include/poincare/norm_pdf.h +++ b/poincare/include/poincare/norm_pdf.h @@ -2,11 +2,11 @@ #define POINCARE_NORM_PDF_H #include -#include +#include namespace Poincare { -class NormPDFNode final : public ExpressionNode { +class NormPDFNode final : public NormalDistributionFunctionNode { public: // TreeNode @@ -28,23 +28,17 @@ private: Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; - // Simplication - Expression shallowReduce(ReductionContext reductionContext) override; - LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; }; - LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } - // Evaluation Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; -class NormPDF final : public Expression { +class NormPDF final : public NormalDistributionFunction { public: - NormPDF(const NormPDFNode * n) : Expression(n) {} + NormPDF(const NormPDFNode * n) : NormalDistributionFunction(n) {} static NormPDF Builder(Expression child0, Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1, child2).array(), 3); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("normpdf", 3, &UntypedBuilderThreeChildren); - Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; } diff --git a/poincare/include/poincare/normal_distribution_function.h b/poincare/include/poincare/normal_distribution_function.h new file mode 100644 index 000000000..746a29f5a --- /dev/null +++ b/poincare/include/poincare/normal_distribution_function.h @@ -0,0 +1,26 @@ +#ifndef POINCARE_NORMAL_DISTRIBUTION_FUNCTION_H +#define POINCARE_NORMAL_DISTRIBUTION_FUNCTION_H + +#include + +namespace Poincare { + +// NormalDistributionFunctions are NormCDF, NormCDF2, InvNorm and NormPDF + +class NormalDistributionFunctionNode : public ExpressionNode { +private: + // Simplication + Expression shallowReduce(ReductionContext reductionContext) override; + LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; }; + LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; } +}; + +class NormalDistributionFunction : public Expression { +public: + NormalDistributionFunction(const NormalDistributionFunctionNode * n) : Expression(n) {} + Expression shallowReduce(Context * context, bool * stopReduction = nullptr); +}; + +} + +#endif diff --git a/poincare/src/inv_norm.cpp b/poincare/src/inv_norm.cpp index 751258590..67d9a0510 100644 --- a/poincare/src/inv_norm.cpp +++ b/poincare/src/inv_norm.cpp @@ -41,26 +41,16 @@ Evaluation InvNormNode::templatedApproximate(Context * context, Preferences:: Expression InvNorm::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { - Expression e = Expression::defaultShallowReduce(); - if (e.isUndefined()) { + bool stopReduction = false; + Expression e = NormalDistributionFunction::shallowReduce(reductionContext.context(), &stopReduction); + if (stopReduction) { return e; } } Expression a = childAtIndex(0); Expression mu = childAtIndex(1); - Expression var = childAtIndex(2); Context * context = reductionContext.context(); - // Check mu and var - bool muAndVarOK = false; - bool couldCheckMuAndVar = NormalDistribution::ExpressionParametersAreOK(&muAndVarOK, mu, var, context); - if (!couldCheckMuAndVar) { - return *this; - } - if (!muAndVarOK) { - return replaceWithUndefinedInPlace(); - } - // Check a if (a.deepIsMatrix(context)) { return replaceWithUndefinedInPlace(); diff --git a/poincare/src/norm_cdf.cpp b/poincare/src/norm_cdf.cpp index 47f63f4df..29e8f1b6a 100644 --- a/poincare/src/norm_cdf.cpp +++ b/poincare/src/norm_cdf.cpp @@ -23,10 +23,6 @@ int NormCDFNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloa return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, NormCDF::s_functionHelper.name()); } -Expression NormCDFNode::shallowReduce(ReductionContext reductionContext) { - return NormCDF(this).shallowReduce(reductionContext); -} - template Evaluation NormCDFNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Evaluation aEvaluation = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); @@ -41,29 +37,4 @@ Evaluation NormCDFNode::templatedApproximate(Context * context, Preferences:: return Complex::Builder(NormalDistribution::CumulativeDistributiveFunctionAtAbscissa(a, mu, var)); } -Expression NormCDF::shallowReduce(ExpressionNode::ReductionContext reductionContext) { - { - Expression e = Expression::defaultShallowReduce(); - if (e.isUndefined()) { - return e; - } - } - - Expression mu = childAtIndex(1); - Expression var = childAtIndex(2); - Context * context = reductionContext.context(); - - // Check mu and var - bool muAndVarOK = false; - bool couldCheckMuAndVar = NormalDistribution::ExpressionParametersAreOK(&muAndVarOK, mu, var, context); - if (!couldCheckMuAndVar) { - return *this; - } - if (!muAndVarOK) { - return replaceWithUndefinedInPlace(); - } - - return *this; -} - } diff --git a/poincare/src/norm_cdf2.cpp b/poincare/src/norm_cdf2.cpp index bc541c22d..0e9cac2c4 100644 --- a/poincare/src/norm_cdf2.cpp +++ b/poincare/src/norm_cdf2.cpp @@ -23,10 +23,6 @@ int NormCDF2Node::serialize(char * buffer, int bufferSize, Preferences::PrintFlo return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, NormCDF2::s_functionHelper.name()); } -Expression NormCDF2Node::shallowReduce(ReductionContext reductionContext) { - return NormCDF2(this).shallowReduce(reductionContext); -} - template Evaluation NormCDF2Node::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Evaluation aEvaluation = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); @@ -48,29 +44,4 @@ Evaluation NormCDF2Node::templatedApproximate(Context * context, Preferences: return Complex::Builder(NormalDistribution::CumulativeDistributiveFunctionAtAbscissa(b, mu, var) - NormalDistribution::CumulativeDistributiveFunctionAtAbscissa(a, mu, var)); } -Expression NormCDF2::shallowReduce(ExpressionNode::ReductionContext reductionContext) { - { - Expression e = Expression::defaultShallowReduce(); - if (e.isUndefined()) { - return e; - } - } - // TODO Factorize with norm_cdf and inv_norm ? - Expression mu = childAtIndex(2); - Expression var = childAtIndex(3); - Context * context = reductionContext.context(); - - // Check mu and var - bool muAndVarOK = false; - bool couldCheckMuAndVar = NormalDistribution::ExpressionParametersAreOK(&muAndVarOK, mu, var, context); - if (!couldCheckMuAndVar) { - return *this; - } - if (!muAndVarOK) { - return replaceWithUndefinedInPlace(); - } - - return *this; -} - } diff --git a/poincare/src/norm_pdf.cpp b/poincare/src/norm_pdf.cpp index 43d3120f5..00e329c3d 100644 --- a/poincare/src/norm_pdf.cpp +++ b/poincare/src/norm_pdf.cpp @@ -23,10 +23,6 @@ int NormPDFNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloa return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, NormPDF::s_functionHelper.name()); } -Expression NormPDFNode::shallowReduce(ReductionContext reductionContext) { - return NormPDF(this).shallowReduce(reductionContext); -} - template Evaluation NormPDFNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Evaluation xEvaluation = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); @@ -41,28 +37,4 @@ Evaluation NormPDFNode::templatedApproximate(Context * context, Preferences:: return Complex::Builder(NormalDistribution::EvaluateAtAbscissa(x, mu, var)); } -Expression NormPDF::shallowReduce(ExpressionNode::ReductionContext reductionContext) { - { - Expression e = Expression::defaultShallowReduce(); - if (e.isUndefined()) { - return e; - } - } - Expression mu = childAtIndex(1); - Expression var = childAtIndex(2); - Context * context = reductionContext.context(); - - // Check mu and var - bool muAndVarOK = false; - bool couldCheckMuAndVar = NormalDistribution::ExpressionParametersAreOK(&muAndVarOK, mu, var, context); - if (!couldCheckMuAndVar) { - return *this; - } - if (!muAndVarOK) { - return replaceWithUndefinedInPlace(); - } - - return *this; -} - } diff --git a/poincare/src/normal_distribution_function.cpp b/poincare/src/normal_distribution_function.cpp new file mode 100644 index 000000000..53acdd596 --- /dev/null +++ b/poincare/src/normal_distribution_function.cpp @@ -0,0 +1,41 @@ +#include +#include +#include + +namespace Poincare { + +Expression NormalDistributionFunctionNode::shallowReduce(ReductionContext reductionContext) { + return NormalDistributionFunction(this).shallowReduce(reductionContext.context()); +} + +Expression NormalDistributionFunction::shallowReduce(Context * context, bool * stopReduction) { + if (stopReduction != nullptr) { + *stopReduction = true; + } + { + Expression e = Expression::defaultShallowReduce(); + if (e.isUndefined()) { + return e; + } + } + + Expression mu = childAtIndex(1); + Expression var = childAtIndex(2); + + // Check mu and var + bool muAndVarOK = false; + bool couldCheckMuAndVar = NormalDistribution::ExpressionParametersAreOK(&muAndVarOK, mu, var, context); + if (!couldCheckMuAndVar) { + return *this; + } + if (!muAndVarOK) { + return replaceWithUndefinedInPlace(); + } + + if (stopReduction != nullptr) { + *stopReduction = false; + } + return *this; +} + +}