mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
[poincare] InvNorm
This commit is contained in:
@@ -82,6 +82,7 @@ poincare_src += $(addprefix poincare/src/,\
|
|||||||
infinity.cpp \
|
infinity.cpp \
|
||||||
integer.cpp \
|
integer.cpp \
|
||||||
integral.cpp \
|
integral.cpp \
|
||||||
|
inv_norm.cpp \
|
||||||
layout_helper.cpp \
|
layout_helper.cpp \
|
||||||
least_common_multiple.cpp \
|
least_common_multiple.cpp \
|
||||||
logarithm.cpp \
|
logarithm.cpp \
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ class Expression : public TreeHandle {
|
|||||||
friend class HyperbolicTrigonometricFunction;
|
friend class HyperbolicTrigonometricFunction;
|
||||||
friend class ImaginaryPart;
|
friend class ImaginaryPart;
|
||||||
friend class Integral;
|
friend class Integral;
|
||||||
|
friend class InvNorm;
|
||||||
friend class LeastCommonMultiple;
|
friend class LeastCommonMultiple;
|
||||||
friend class Logarithm;
|
friend class Logarithm;
|
||||||
friend class Matrix;
|
friend class Matrix;
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ public:
|
|||||||
HyperbolicTangent,
|
HyperbolicTangent,
|
||||||
ImaginaryPart,
|
ImaginaryPart,
|
||||||
Integral,
|
Integral,
|
||||||
|
InvNorm,
|
||||||
LeastCommonMultiple,
|
LeastCommonMultiple,
|
||||||
Logarithm,
|
Logarithm,
|
||||||
MatrixTrace,
|
MatrixTrace,
|
||||||
|
|||||||
50
poincare/include/poincare/inv_norm.h
Normal file
50
poincare/include/poincare/inv_norm.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
#ifndef POINCARE_INV_NORM_H
|
||||||
|
#define POINCARE_INV_NORM_H
|
||||||
|
|
||||||
|
#include <poincare/approximation_helper.h>
|
||||||
|
#include <poincare/expression.h>
|
||||||
|
|
||||||
|
namespace Poincare {
|
||||||
|
|
||||||
|
class InvNormNode final : public ExpressionNode {
|
||||||
|
public:
|
||||||
|
|
||||||
|
// TreeNode
|
||||||
|
size_t size() const override { return sizeof(InvNormNode); }
|
||||||
|
int numberOfChildren() const override;
|
||||||
|
#if POINCARE_TREE_LOG
|
||||||
|
virtual void logNodeName(std::ostream & stream) const override {
|
||||||
|
stream << "InvNorm";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Properties
|
||||||
|
Type type() const override { return Type::InvNorm; }
|
||||||
|
|
||||||
|
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;
|
||||||
|
LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; };
|
||||||
|
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
|
||||||
|
|
||||||
|
// 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 InvNorm final : public Expression {
|
||||||
|
public:
|
||||||
|
InvNorm(const InvNormNode * n) : Expression(n) {}
|
||||||
|
static InvNorm Builder(Expression child0, Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder<InvNorm, InvNormNode>(ArrayBuilder<TreeHandle>(child0, child1, child2).array(), 3); }
|
||||||
|
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("invnorm", 3, &UntypedBuilderThreeChildren<InvNorm>);
|
||||||
|
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -40,6 +40,7 @@
|
|||||||
#include <poincare/infinity.h>
|
#include <poincare/infinity.h>
|
||||||
#include <poincare/integer.h>
|
#include <poincare/integer.h>
|
||||||
#include <poincare/integral.h>
|
#include <poincare/integral.h>
|
||||||
|
#include <poincare/inv_norm.h>
|
||||||
#include <poincare/least_common_multiple.h>
|
#include <poincare/least_common_multiple.h>
|
||||||
#include <poincare/logarithm.h>
|
#include <poincare/logarithm.h>
|
||||||
#include <poincare/matrix.h>
|
#include <poincare/matrix.h>
|
||||||
|
|||||||
52
poincare/src/inv_norm.cpp
Normal file
52
poincare/src/inv_norm.cpp
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#include <poincare/inv_norm.h>
|
||||||
|
#include <poincare/layout_helper.h>
|
||||||
|
#include <poincare/normal_distribution.h>
|
||||||
|
#include <poincare/serialization_helper.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
namespace Poincare {
|
||||||
|
|
||||||
|
constexpr Expression::FunctionHelper InvNorm::s_functionHelper;
|
||||||
|
|
||||||
|
int InvNormNode::numberOfChildren() const { return InvNorm::s_functionHelper.numberOfChildren(); }
|
||||||
|
|
||||||
|
Layout InvNormNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||||
|
return LayoutHelper::Prefix(InvNorm(this), floatDisplayMode, numberOfSignificantDigits, InvNorm::s_functionHelper.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
int InvNormNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||||
|
return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, InvNorm::s_functionHelper.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
Expression InvNormNode::shallowReduce(ReductionContext reductionContext) {
|
||||||
|
return InvNorm(this).shallowReduce(reductionContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Evaluation<T> InvNormNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const {
|
||||||
|
Evaluation<T> aEvaluation = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit);
|
||||||
|
Evaluation<T> muEvaluation = childAtIndex(1)->approximate(T(), context, complexFormat, angleUnit);
|
||||||
|
Evaluation<T> sigmaEvaluation = childAtIndex(2)->approximate(T(), context, complexFormat, angleUnit);
|
||||||
|
|
||||||
|
T a = aEvaluation.toScalar();
|
||||||
|
T mu = muEvaluation.toScalar();
|
||||||
|
T sigma = sigmaEvaluation.toScalar();
|
||||||
|
|
||||||
|
if (std::isnan(a) || std::isnan(mu) || std::isnan(sigma)) {
|
||||||
|
return Complex<T>::Undefined();
|
||||||
|
}
|
||||||
|
return Complex<T>::Builder(NormalDistribution::CumulativeDistributiveInverseForProbability<T>(a, mu, sigma));
|
||||||
|
}
|
||||||
|
|
||||||
|
Expression InvNorm::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
|
||||||
|
{
|
||||||
|
Expression e = Expression::defaultShallowReduce();
|
||||||
|
if (e.isUndefined()) {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//TODO LEA
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -47,16 +47,16 @@ T NormalDistribution::StandardNormalCumulativeDistributiveFunctionAtAbscissa(T a
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T NormalDistribution::StandardNormalCumulativeDistributiveInverseForProbability(T probability) {
|
T NormalDistribution::StandardNormalCumulativeDistributiveInverseForProbability(T probability) {
|
||||||
if (probability >= 1.0) {
|
if (probability >= (T)1.0) {
|
||||||
return INFINITY;
|
return INFINITY;
|
||||||
}
|
}
|
||||||
if (probability <= 0.0) {
|
if (probability <= (T)0.0) {
|
||||||
return -INFINITY;
|
return -INFINITY;
|
||||||
}
|
}
|
||||||
if (probability < 0.5) {
|
if (probability < (T)0.5) {
|
||||||
return -StandardNormalCumulativeDistributiveInverseForProbability(1.0-probability);
|
return -StandardNormalCumulativeDistributiveInverseForProbability(((T)1.0)-probability);
|
||||||
}
|
}
|
||||||
return std::sqrt(2.0) * erfInv(2.0 * probability - 1.0);
|
return std::sqrt((T)2.0) * erfInv(((T)2.0) * probability - (T)1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template float NormalDistribution::EvaluateAtAbscissa<float>(float, float, float);
|
template float NormalDistribution::EvaluateAtAbscissa<float>(float, float, float);
|
||||||
|
|||||||
@@ -116,6 +116,7 @@ private:
|
|||||||
&ImaginaryPart::s_functionHelper,
|
&ImaginaryPart::s_functionHelper,
|
||||||
&Integral::s_functionHelper,
|
&Integral::s_functionHelper,
|
||||||
&MatrixInverse::s_functionHelper,
|
&MatrixInverse::s_functionHelper,
|
||||||
|
&InvNorm::s_functionHelper,
|
||||||
&LeastCommonMultiple::s_functionHelper,
|
&LeastCommonMultiple::s_functionHelper,
|
||||||
&NaperianLogarithm::s_functionHelper,
|
&NaperianLogarithm::s_functionHelper,
|
||||||
&CommonLogarithm::s_functionHelper,
|
&CommonLogarithm::s_functionHelper,
|
||||||
|
|||||||
@@ -302,6 +302,7 @@ template HyperbolicTangent TreeHandle::FixedArityBuilder<HyperbolicTangent, Hype
|
|||||||
template ImaginaryPart TreeHandle::FixedArityBuilder<ImaginaryPart, ImaginaryPartNode>(TreeHandle*, size_t);
|
template ImaginaryPart TreeHandle::FixedArityBuilder<ImaginaryPart, ImaginaryPartNode>(TreeHandle*, size_t);
|
||||||
template Integral TreeHandle::FixedArityBuilder<Integral, IntegralNode>(TreeHandle*, size_t);
|
template Integral TreeHandle::FixedArityBuilder<Integral, IntegralNode>(TreeHandle*, size_t);
|
||||||
template IntegralLayout TreeHandle::FixedArityBuilder<IntegralLayout, IntegralLayoutNode>(TreeHandle*, size_t);
|
template IntegralLayout TreeHandle::FixedArityBuilder<IntegralLayout, IntegralLayoutNode>(TreeHandle*, size_t);
|
||||||
|
template InvNorm TreeHandle::FixedArityBuilder<InvNorm, InvNormNode>(TreeHandle*, size_t);
|
||||||
template LeastCommonMultiple TreeHandle::FixedArityBuilder<LeastCommonMultiple, LeastCommonMultipleNode>(TreeHandle*, size_t);
|
template LeastCommonMultiple TreeHandle::FixedArityBuilder<LeastCommonMultiple, LeastCommonMultipleNode>(TreeHandle*, size_t);
|
||||||
template LeftParenthesisLayout TreeHandle::FixedArityBuilder<LeftParenthesisLayout, LeftParenthesisLayoutNode>(TreeHandle*, size_t);
|
template LeftParenthesisLayout TreeHandle::FixedArityBuilder<LeftParenthesisLayout, LeftParenthesisLayoutNode>(TreeHandle*, size_t);
|
||||||
template LeftSquareBracketLayout TreeHandle::FixedArityBuilder<LeftSquareBracketLayout, LeftSquareBracketLayoutNode>(TreeHandle*, size_t);
|
template LeftSquareBracketLayout TreeHandle::FixedArityBuilder<LeftSquareBracketLayout, LeftSquareBracketLayoutNode>(TreeHandle*, size_t);
|
||||||
|
|||||||
@@ -270,6 +270,9 @@ QUIZ_CASE(poincare_approximation_function) {
|
|||||||
assert_expression_approximates_to<float>("int(x,x, 1, 2)", "1.5");
|
assert_expression_approximates_to<float>("int(x,x, 1, 2)", "1.5");
|
||||||
assert_expression_approximates_to<double>("int(x,x, 1, 2)", "1.5");
|
assert_expression_approximates_to<double>("int(x,x, 1, 2)", "1.5");
|
||||||
|
|
||||||
|
assert_expression_approximates_to<float>("invnorm(0.56, 1.3, 2.4)", "1.662326");
|
||||||
|
//assert_expression_approximates_to<double>("invnorm(0.56, 1.3, 2.4)", "1.6623258450088"); FIXME precision error
|
||||||
|
|
||||||
assert_expression_approximates_to<float>("ln(2)", "0.6931472");
|
assert_expression_approximates_to<float>("ln(2)", "0.6931472");
|
||||||
assert_expression_approximates_to<double>("ln(2)", "6.9314718055995ᴇ-1");
|
assert_expression_approximates_to<double>("ln(2)", "6.9314718055995ᴇ-1");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user