mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
[poincare/InvBinom]
This commit is contained in:
@@ -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 \
|
||||
|
||||
@@ -70,6 +70,7 @@ public:
|
||||
HyperbolicTangent,
|
||||
ImaginaryPart,
|
||||
Integral,
|
||||
InvBinom,
|
||||
InvNorm,
|
||||
LeastCommonMultiple,
|
||||
Logarithm,
|
||||
|
||||
48
poincare/include/poincare/inv_binom.h
Normal file
48
poincare/include/poincare/inv_binom.h
Normal 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
|
||||
@@ -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>
|
||||
|
||||
85
poincare/src/inv_binom.cpp
Normal file
85
poincare/src/inv_binom.cpp
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user