[poincare/InvBinom]

This commit is contained in:
Léa Saviot
2019-08-26 15:53:18 +02:00
parent 56448e3c41
commit ddba1f6050
7 changed files with 138 additions and 0 deletions

View File

@@ -86,6 +86,7 @@ poincare_src += $(addprefix poincare/src/,\
infinity.cpp \
integer.cpp \
integral.cpp \
inv_binom.cpp \
inv_norm.cpp \
layout_helper.cpp \
least_common_multiple.cpp \

View File

@@ -70,6 +70,7 @@ public:
HyperbolicTangent,
ImaginaryPart,
Integral,
InvBinom,
InvNorm,
LeastCommonMultiple,
Logarithm,

View File

@@ -0,0 +1,48 @@
#ifndef POINCARE_INV_BINOM_H
#define POINCARE_INV_BINOM_H
#include <poincare/approximation_helper.h>
#include <poincare/binomial_distribution_function.h>
namespace Poincare {
class InvBinomNode final : public BinomialDistributionFunctionNode {
public:
// TreeNode
size_t size() const override { return sizeof(InvBinomNode); }
int numberOfChildren() const override;
#if POINCARE_TREE_LOG
virtual void logNodeName(std::ostream & stream) const override {
stream << "InvBinom";
}
#endif
// Properties
Type type() const override { return Type::InvBinom; }
private:
// Layout
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;
// Evaluation
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
};
class InvBinom final : public BinomialDistributionFunction {
public:
InvBinom(const InvBinomNode * n) : BinomialDistributionFunction(n) {}
static InvBinom Builder(Expression child0, Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder<InvBinom, InvBinomNode>(ArrayBuilder<TreeHandle>(child0, child1, child2).array(), 3); }
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("invbinom", 3, &UntypedBuilderThreeChildren<InvBinom>);
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
};
}
#endif

View File

@@ -42,6 +42,7 @@
#include <poincare/infinity.h>
#include <poincare/integer.h>
#include <poincare/integral.h>
#include <poincare/inv_binom.h>
#include <poincare/inv_norm.h>
#include <poincare/least_common_multiple.h>
#include <poincare/logarithm.h>

View File

@@ -0,0 +1,85 @@
#include <poincare/inv_binom.h>
#include <poincare/infinity.h>
#include <poincare/integer.h>
#include <poincare/layout_helper.h>
#include <poincare/binomial_distribution.h>
#include <poincare/rational.h>
#include <poincare/serialization_helper.h>
#include <assert.h>
namespace Poincare {
constexpr Expression::FunctionHelper InvBinom::s_functionHelper;
int InvBinomNode::numberOfChildren() const { return InvBinom::s_functionHelper.numberOfChildren(); }
Layout InvBinomNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
return LayoutHelper::Prefix(InvBinom(this), floatDisplayMode, numberOfSignificantDigits, InvBinom::s_functionHelper.name());
}
int InvBinomNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, InvBinom::s_functionHelper.name());
}
Expression InvBinomNode::shallowReduce(ReductionContext reductionContext) {
return InvBinom(this).shallowReduce(reductionContext);
}
template<typename T>
Evaluation<T> InvBinomNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const {
Evaluation<T> aEvaluation = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit);
Evaluation<T> nEvaluation = childAtIndex(1)->approximate(T(), context, complexFormat, angleUnit);
Evaluation<T> pEvaluation = childAtIndex(2)->approximate(T(), context, complexFormat, angleUnit);
T a = aEvaluation.toScalar();
T n = nEvaluation.toScalar();
T p = pEvaluation.toScalar();
// CumulativeDistributiveInverseForProbability handles bad n and p values
return Complex<T>::Builder(BinomialDistribution::CumulativeDistributiveInverseForProbability<T>(a, n, p));
}
Expression InvBinom::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
{
bool stopReduction = false;
Expression e = BinomialDistributionFunction::shallowReduce(reductionContext.context(), &stopReduction);
if (stopReduction) {
return e;
}
}
Expression a = childAtIndex(0);
Expression n = childAtIndex(1);
Context * context = reductionContext.context();
// Check a
if (a.deepIsMatrix(context)) {
return replaceWithUndefinedInPlace();
}
if (a.type() != ExpressionNode::Type::Rational) {
return *this;
}
// Special values
// Undef if a < 0 or a > 1
Rational rationalA = static_cast<Rational &>(a);
if (rationalA.isNegative()) {
return replaceWithUndefinedInPlace();
}
Integer num = rationalA.unsignedIntegerNumerator();
Integer den = rationalA.integerDenominator();
if (den.isLowerThan(num)) {
return replaceWithUndefinedInPlace();
}
// TODO LEA if a == 0, check p ?
// n if a == 1
if (rationalA.isOne()) {
replaceWithInPlace(n);
return n;
}
return *this;
}
}

View File

@@ -117,6 +117,7 @@ private:
&MatrixIdentity::s_functionHelper,
&ImaginaryPart::s_functionHelper,
&Integral::s_functionHelper,
&InvBinom::s_functionHelper,
&MatrixInverse::s_functionHelper,
&InvNorm::s_functionHelper,
&LeastCommonMultiple::s_functionHelper,

View File

@@ -304,6 +304,7 @@ template HyperbolicTangent TreeHandle::FixedArityBuilder<HyperbolicTangent, Hype
template ImaginaryPart TreeHandle::FixedArityBuilder<ImaginaryPart, ImaginaryPartNode>(TreeHandle*, size_t);
template Integral TreeHandle::FixedArityBuilder<Integral, IntegralNode>(TreeHandle*, size_t);
template IntegralLayout TreeHandle::FixedArityBuilder<IntegralLayout, IntegralLayoutNode>(TreeHandle*, size_t);
template InvBinom TreeHandle::FixedArityBuilder<InvBinom, InvBinomNode>(TreeHandle*, size_t);
template InvNorm TreeHandle::FixedArityBuilder<InvNorm, InvNormNode>(TreeHandle*, size_t);
template LeastCommonMultiple TreeHandle::FixedArityBuilder<LeastCommonMultiple, LeastCommonMultipleNode>(TreeHandle*, size_t);
template LeftParenthesisLayout TreeHandle::FixedArityBuilder<LeftParenthesisLayout, LeftParenthesisLayoutNode>(TreeHandle*, size_t);