mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-28 10:09:53 +01:00
[poincare] Fix Sum, Product, Sequence
This commit is contained in:
@@ -99,12 +99,15 @@ objs += $(addprefix poincare/src/,\
|
||||
power.o\
|
||||
print_float.o\
|
||||
preferences.o\
|
||||
product.o\
|
||||
rational.o\
|
||||
sequence.o\
|
||||
serialization_helper.o\
|
||||
simplification_helper.o\
|
||||
sine.o\
|
||||
square_root.o\
|
||||
subtraction.o\
|
||||
sum.o\
|
||||
symbol.o\
|
||||
tangent.o\
|
||||
tree_node.o\
|
||||
|
||||
@@ -133,6 +133,7 @@
|
||||
#include <poincare/matrix_inverse.h>
|
||||
#include <poincare/matrix_trace.h>
|
||||
#include <poincare/matrix_transpose.h>
|
||||
#include <poincare/product.h>
|
||||
#include <poincare/sine.h>
|
||||
#include <poincare/tangent.h>
|
||||
#include <poincare/hyperbolic_arc_cosine.h>
|
||||
@@ -156,6 +157,7 @@
|
||||
#include <poincare/opposite.h>
|
||||
#include <poincare/decimal.h>
|
||||
#include <poincare/rational.h>
|
||||
#include <poincare/sum.h>
|
||||
#include <poincare/symbol.h>
|
||||
#include <poincare/float.h>
|
||||
#include <poincare/parenthesis.h>
|
||||
|
||||
@@ -5,21 +5,43 @@
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Product : public Sequence {
|
||||
using Sequence::Sequence;
|
||||
class ProductNode : public SequenceNode {
|
||||
public:
|
||||
Type type() const override;
|
||||
// Allocation Failure
|
||||
static ProductNode * FailedAllocationStaticNode();
|
||||
ProductNode * failedAllocationStaticNode() override { return FailedAllocationStaticNode(); }
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(ProductNode); }
|
||||
#if POINCARE_TREE_LOG
|
||||
virtual void logNodeName(std::ostream & stream) const override {
|
||||
stream << "Product";
|
||||
}
|
||||
#endif
|
||||
|
||||
Type type() const override { return Type::Product; }
|
||||
private:
|
||||
const char * name() const override;
|
||||
int emptySequenceValue() const override;
|
||||
const char * name() const override { return "product"; }
|
||||
float emptySequenceValue() const override { return 1.0f; }
|
||||
LayoutRef createSequenceLayout(LayoutRef argumentLayout, LayoutRef subscriptLayout, LayoutRef superscriptLayout) const override;
|
||||
Evaluation<double> evaluateWithNextTerm(DoublePrecision p, Evaluation<double> * a, Evaluation<double> * b) const override {
|
||||
Evaluation<double> evaluateWithNextTerm(DoublePrecision p, Evaluation<double> a, Evaluation<double> b) const override {
|
||||
return templatedApproximateWithNextTerm<double>(a, b);
|
||||
}
|
||||
Evaluation<float> evaluateWithNextTerm(SinglePrecision p, Evaluation<float> * a, Evaluation<float> * b) const override {
|
||||
Evaluation<float> evaluateWithNextTerm(SinglePrecision p, Evaluation<float> a, Evaluation<float> b) const override {
|
||||
return templatedApproximateWithNextTerm<float>(a, b);
|
||||
}
|
||||
template<typename T> Evaluation<T> templatedApproximateWithNextTerm(Evaluation<T> * a, Evaluation<T> * b) const;
|
||||
template<typename T> Evaluation<T> templatedApproximateWithNextTerm(Evaluation<T> a, Evaluation<T> b) const;
|
||||
};
|
||||
|
||||
class Product : public Expression {
|
||||
friend class ProductNode;
|
||||
public:
|
||||
Product() : Expression(TreePool::sharedPool()->createTreeNode<ProductNode>()) {}
|
||||
Product(const ProductNode * n) : Expression(n) {}
|
||||
Product(Expression operand0, Expression operand1, Expression operand2) : Product() {
|
||||
replaceChildAtIndexInPlace(0, operand0);
|
||||
replaceChildAtIndexInPlace(1, operand1);
|
||||
replaceChildAtIndexInPlace(2, operand2);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -2,13 +2,15 @@
|
||||
#define POINCARE_SEQUENCE_H
|
||||
|
||||
#include <poincare/layout_helper.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/serialization_helper.h>
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/approximation_helper.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Sequence : public StaticHierarchy<3> {
|
||||
using StaticHierarchy<3>::StaticHierarchy;
|
||||
class SequenceNode : public ExpressionNode {
|
||||
public:
|
||||
int numberOfChildren() const override { return 3; }
|
||||
private:
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
@@ -16,13 +18,13 @@ private:
|
||||
}
|
||||
virtual LayoutRef createSequenceLayout(LayoutRef subscriptLayout, LayoutRef superscriptLayout, LayoutRef argumentLayout) const = 0;
|
||||
virtual const char * name() const = 0;
|
||||
/* Evaluation */
|
||||
/* Approximation */
|
||||
Evaluation<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
virtual int emptySequenceValue() const = 0;
|
||||
virtual Evaluation<float> evaluateWithNextTerm(SinglePrecision p, Evaluation<float> * a, Evaluation<float> * b) const = 0;
|
||||
virtual Evaluation<double> evaluateWithNextTerm(DoublePrecision p, Evaluation<double> * a, Evaluation<double> * b) const = 0;
|
||||
virtual float emptySequenceValue() const = 0;
|
||||
virtual Evaluation<float> evaluateWithNextTerm(SinglePrecision p, Evaluation<float> a, Evaluation<float> b) const = 0;
|
||||
virtual Evaluation<double> evaluateWithNextTerm(DoublePrecision p, Evaluation<double> a, Evaluation<double> b) const = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -5,21 +5,43 @@
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Sum : public Sequence {
|
||||
using Sequence::Sequence;
|
||||
class SumNode : public SequenceNode {
|
||||
public:
|
||||
Type type() const override;
|
||||
// Allocation Failure
|
||||
static SumNode * FailedAllocationStaticNode();
|
||||
SumNode * failedAllocationStaticNode() override { return FailedAllocationStaticNode(); }
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(SumNode); }
|
||||
#if POINCARE_TREE_LOG
|
||||
virtual void logNodeName(std::ostream & stream) const override {
|
||||
stream << "Sum";
|
||||
}
|
||||
#endif
|
||||
|
||||
Type type() const override { return Type::Sum; }
|
||||
private:
|
||||
const char * name() const override;
|
||||
int emptySequenceValue() const override;
|
||||
const char * name() const override { return "sum"; }
|
||||
float emptySequenceValue() const override { return 0.0f; }
|
||||
LayoutRef createSequenceLayout(LayoutRef argumentLayout, LayoutRef subscriptLayout, LayoutRef superscriptLayout) const override;
|
||||
Evaluation<double> evaluateWithNextTerm(DoublePrecision p, Evaluation<double> * a, Evaluation<double> * b) const override {
|
||||
Evaluation<double> evaluateWithNextTerm(DoublePrecision p, Evaluation<double> a, Evaluation<double> b) const override {
|
||||
return templatedApproximateWithNextTerm<double>(a, b);
|
||||
}
|
||||
Evaluation<float> evaluateWithNextTerm(SinglePrecision p, Evaluation<float> * a, Evaluation<float> * b) const override {
|
||||
Evaluation<float> evaluateWithNextTerm(SinglePrecision p, Evaluation<float> a, Evaluation<float> b) const override {
|
||||
return templatedApproximateWithNextTerm<float>(a, b);
|
||||
}
|
||||
template<typename T> Evaluation<T> templatedApproximateWithNextTerm(Evaluation<T> * a, Evaluation<T> * b) const;
|
||||
template<typename T> Evaluation<T> templatedApproximateWithNextTerm(Evaluation<T> a, Evaluation<T> b) const;
|
||||
};
|
||||
|
||||
class Sum : public Expression {
|
||||
friend class SumNode;
|
||||
public:
|
||||
Sum() : Expression(TreePool::sharedPool()->createTreeNode<SumNode>()) {}
|
||||
Sum(const SumNode * n) : Expression(n) {}
|
||||
Sum(Expression operand0, Expression operand1, Expression operand2) : Sum() {
|
||||
replaceChildAtIndexInPlace(0, operand0);
|
||||
replaceChildAtIndexInPlace(1, operand1);
|
||||
replaceChildAtIndexInPlace(2, operand2);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -143,8 +143,7 @@ log { return LOGFUNCTION; }
|
||||
prediction95 { poincare_expression_yylval.expression = new PredictionInterval(); return FUNCTION; }
|
||||
*/
|
||||
prediction { poincare_expression_yylval.expression = SimplePredictionInterval(); return FUNCTION; }
|
||||
/*product { poincare_expression_yylval.expression = new Product(); return FUNCTION; }
|
||||
*/
|
||||
product { poincare_expression_yylval.expression = Product(); return FUNCTION; }
|
||||
quo { poincare_expression_yylval.expression = DivisionQuotient(); return FUNCTION; }
|
||||
/*random { poincare_expression_yylval.expression = new Random(); return FUNCTION; }
|
||||
randint { poincare_expression_yylval.expression = new Randint(); return FUNCTION; }
|
||||
@@ -156,8 +155,7 @@ root { poincare_expression_yylval.expression = NthRoot(); return FUNCTION; }
|
||||
*/
|
||||
sin { poincare_expression_yylval.expression = Sine(); return FUNCTION; }
|
||||
sinh { poincare_expression_yylval.expression = HyperbolicSine(); return FUNCTION; }
|
||||
/*sum { poincare_expression_yylval.expression = new Sum(); return FUNCTION; }
|
||||
*/
|
||||
sum { poincare_expression_yylval.expression = Sum(); return FUNCTION; }
|
||||
tan { poincare_expression_yylval.expression = Tangent(); return FUNCTION; }
|
||||
tanh { poincare_expression_yylval.expression = HyperbolicTangent(); return FUNCTION; }
|
||||
trace { poincare_expression_yylval.expression = MatrixTrace(); return FUNCTION; }
|
||||
|
||||
@@ -9,45 +9,34 @@ extern "C" {
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
ExpressionNode::Type Product::type() const {
|
||||
return Type::Product;
|
||||
ProductNode * ProductNode::FailedAllocationStaticNode() {
|
||||
static AllocationFailureExpressionNode<ProductNode> failure;
|
||||
TreePool::sharedPool()->registerStaticNodeIfRequired(&failure);
|
||||
return &failure;
|
||||
}
|
||||
|
||||
Expression * Product::clone() const {
|
||||
Product * a = new Product(m_operands, true);
|
||||
return a;
|
||||
}
|
||||
|
||||
const char * Product::name() const {
|
||||
return "product";
|
||||
}
|
||||
|
||||
int Product::emptySequenceValue() const {
|
||||
return 1;
|
||||
}
|
||||
|
||||
LayoutRef Product::createSequenceLayout(LayoutRef argumentLayout, LayoutRef subscriptLayout, LayoutRef superscriptLayout) const {
|
||||
LayoutRef ProductNode::createSequenceLayout(LayoutRef argumentLayout, LayoutRef subscriptLayout, LayoutRef superscriptLayout) const {
|
||||
return ProductLayoutRef(argumentLayout, subscriptLayout, superscriptLayout);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Evaluation<T> * Product::templatedApproximateWithNextTerm(Evaluation<T> * a, Evaluation<T> * b) const {
|
||||
if (a->type() == Evaluation<T>::Type::Complex && b->type() == Evaluation<T>::Type::Complex) {
|
||||
Complex<T> * c = static_cast<Complex<T> *>(a);
|
||||
Complex<T> * d = static_cast<Complex<T> *>(b);
|
||||
return new Complex<T>((*c)*(*d));
|
||||
Evaluation<T> ProductNode::templatedApproximateWithNextTerm(Evaluation<T> a, Evaluation<T> b) const {
|
||||
if (a.type() == EvaluationNode<T>::Type::Complex && b.type() == EvaluationNode<T>::Type::Complex) {
|
||||
Complex<T> c = static_cast<Complex<T>&>(a);
|
||||
Complex<T> d = static_cast<Complex<T>&>(b);
|
||||
return Complex<T>(c.stdComplex()*d.stdComplex());
|
||||
}
|
||||
if (a->type() == Evaluation<T>::Type::Complex) {
|
||||
Complex<T> * c = static_cast<Complex<T> *>(a);
|
||||
assert(b->type() == Evaluation<T>::Type::MatrixComplex);
|
||||
MatrixComplex<T> * m = static_cast<MatrixComplex<T> *>(b);
|
||||
return new MatrixComplex<T>(Multiplication::computeOnComplexAndMatrix(*c, *m));
|
||||
if (a.type() == EvaluationNode<T>::Type::Complex) {
|
||||
Complex<T> c = static_cast<Complex<T> &>(a);
|
||||
assert(b.type() == EvaluationNode<T>::Type::MatrixComplex);
|
||||
MatrixComplex<T> m = static_cast<MatrixComplex<T> &>(b);
|
||||
return MultiplicationNode::computeOnComplexAndMatrix(c.stdComplex(), m);
|
||||
}
|
||||
assert(a->type() == Evaluation<T>::Type::MatrixComplex);
|
||||
assert(b->type() == Evaluation<T>::Type::MatrixComplex);
|
||||
MatrixComplex<T> * m = static_cast<MatrixComplex<T> *>(a);
|
||||
MatrixComplex<T> * n = static_cast<MatrixComplex<T> *>(b);
|
||||
return new MatrixComplex<T>(Multiplication::computeOnMatrices<T>(*m, *n));
|
||||
assert(a.type() == EvaluationNode<T>::Type::MatrixComplex);
|
||||
assert(b.type() == EvaluationNode<T>::Type::MatrixComplex);
|
||||
MatrixComplex<T> m = static_cast<MatrixComplex<T>&>(a);
|
||||
MatrixComplex<T> n = static_cast<MatrixComplex<T>&>(b);
|
||||
return MultiplicationNode::computeOnMatrices<T>(m, n);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,36 +11,29 @@ extern "C" {
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
LayoutRef Sequence::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
LayoutRef SequenceNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return createSequenceLayout(childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits), childAtIndex(1)->createLayout(floatDisplayMode, numberOfSignificantDigits), childAtIndex(2)->createLayout(floatDisplayMode, numberOfSignificantDigits));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Evaluation<T> Sequence::templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const {
|
||||
Evaluation<T> * aInput = childAtIndex(1)->approximate(T(), context, angleUnit);
|
||||
Evaluation<T> * bInput = childAtIndex(2)->approximate(T(), context, angleUnit);
|
||||
T start = aInput->toScalar();
|
||||
T end = bInput->toScalar();
|
||||
delete aInput;
|
||||
delete bInput;
|
||||
Evaluation<T> SequenceNode::templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const {
|
||||
Evaluation<T> aInput = childAtIndex(1)->approximate(T(), context, angleUnit);
|
||||
Evaluation<T> bInput = childAtIndex(2)->approximate(T(), context, angleUnit);
|
||||
T start = aInput.toScalar();
|
||||
T end = bInput.toScalar();
|
||||
if (std::isnan(start) || std::isnan(end) || start != (int)start || end != (int)end || end - start > k_maxNumberOfSteps) {
|
||||
return new Complex<T>(Complex<T>::Undefined());
|
||||
return Complex<T>::Undefined();
|
||||
}
|
||||
VariableContext<T> nContext = VariableContext<T>('n', &context);
|
||||
Evaluation<T> * result = new Complex<T>(emptySequenceValue());
|
||||
Evaluation<T> result = Complex<T>((T)emptySequenceValue());
|
||||
for (int i = (int)start; i <= (int)end; i++) {
|
||||
if (shouldStopProcessing()) {
|
||||
delete result;
|
||||
return new Complex<T>(Complex<T>::Undefined());
|
||||
if (Expression::shouldStopProcessing()) {
|
||||
return Complex<T>::Undefined();
|
||||
}
|
||||
nContext.setApproximationForVariable((T)i);
|
||||
Evaluation<T> * expression = childAtIndex(0)->approximate(T(), nContext, angleUnit);
|
||||
Evaluation<T> * newResult = evaluateWithNextTerm(T(), result, expression);
|
||||
delete result;
|
||||
delete expression;
|
||||
result = newResult;
|
||||
if (result == nullptr) {
|
||||
return new Complex<T>(Complex<T>::Undefined());
|
||||
result = evaluateWithNextTerm(T(), result, childAtIndex(0)->approximate(T(), nContext, angleUnit));
|
||||
if (result.isUndefined()) {
|
||||
return Complex<T>::Undefined();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -10,45 +10,35 @@ extern "C" {
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
ExpressionNode::Type Sum::type() const {
|
||||
return Type::Sum;
|
||||
SumNode * SumNode::FailedAllocationStaticNode() {
|
||||
static AllocationFailureExpressionNode<SumNode> failure;
|
||||
TreePool::sharedPool()->registerStaticNodeIfRequired(&failure);
|
||||
return &failure;
|
||||
}
|
||||
|
||||
Expression * Sum::clone() const {
|
||||
Sum * a = new Sum(m_operands, true);
|
||||
return a;
|
||||
}
|
||||
|
||||
const char * Sum::name() const {
|
||||
return "sum";
|
||||
}
|
||||
|
||||
int Sum::emptySequenceValue() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
LayoutRef Sum::createSequenceLayout(LayoutRef argumentLayout, LayoutRef subscriptLayout, LayoutRef superscriptLayout) const {
|
||||
LayoutRef SumNode::createSequenceLayout(LayoutRef argumentLayout, LayoutRef subscriptLayout, LayoutRef superscriptLayout) const {
|
||||
return SumLayoutRef(argumentLayout, subscriptLayout, superscriptLayout);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Evaluation<T> * Sum::templatedApproximateWithNextTerm(Evaluation<T> * a, Evaluation<T> * b) const {
|
||||
if (a->type() == Evaluation<T>::Type::Complex && b->type() == Evaluation<T>::Type::Complex) {
|
||||
Complex<T> * c = static_cast<Complex<T> *>(a);
|
||||
Complex<T> * d = static_cast<Complex<T> *>(b);
|
||||
return new Complex<T>((*c)+(*d));
|
||||
Evaluation<T> SumNode::templatedApproximateWithNextTerm(Evaluation<T> a, Evaluation<T> b) const {
|
||||
if (a.type() == EvaluationNode<T>::Type::Complex && b.type() == EvaluationNode<T>::Type::Complex) {
|
||||
Complex<T> c = static_cast<Complex<T>&>(a);
|
||||
Complex<T> d = static_cast<Complex<T>&>(b);
|
||||
return Complex<T>(c.stdComplex()+d.stdComplex());
|
||||
}
|
||||
if (a->type() == Evaluation<T>::Type::Complex) {
|
||||
Complex<T> * c = static_cast<Complex<T> *>(a);
|
||||
assert(b->type() == Evaluation<T>::Type::MatrixComplex);
|
||||
MatrixComplex<T> * m = static_cast<MatrixComplex<T> *>(b);
|
||||
return new MatrixComplex<T>(Addition::computeOnComplexAndMatrix(*c, *m));
|
||||
if (a.type() == EvaluationNode<T>::Type::Complex) {
|
||||
Complex<T> c = static_cast<Complex<T> &>(a);
|
||||
assert(b.type() == EvaluationNode<T>::Type::MatrixComplex);
|
||||
MatrixComplex<T> m = static_cast<MatrixComplex<T> &>(b);
|
||||
return AdditionNode::computeOnComplexAndMatrix(c.stdComplex(), m);
|
||||
}
|
||||
assert(a->type() == Evaluation<T>::Type::MatrixComplex);
|
||||
assert(b->type() == Evaluation<T>::Type::MatrixComplex);
|
||||
MatrixComplex<T> * m = static_cast<MatrixComplex<T> *>(a);
|
||||
MatrixComplex<T> * n = static_cast<MatrixComplex<T> *>(b);
|
||||
return new MatrixComplex<T>(Addition::computeOnMatrices<T>(*m, *n));
|
||||
assert(a.type() == EvaluationNode<T>::Type::MatrixComplex);
|
||||
assert(b.type() == EvaluationNode<T>::Type::MatrixComplex);
|
||||
MatrixComplex<T> m = static_cast<MatrixComplex<T>&>(a);
|
||||
MatrixComplex<T> n = static_cast<MatrixComplex<T>&>(b);
|
||||
return AdditionNode::computeOnMatrices<T>(m, n);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -45,8 +45,8 @@ QUIZ_CASE(poincare_parse_function) {
|
||||
assert_parsed_expression_type("prediction(0.1, 100)", ExpressionNode::Type::ConfidenceInterval);
|
||||
#if 0
|
||||
assert_parsed_expression_type("prediction95(0.1, 100)", ExpressionNode::Type::PredictionInterval);
|
||||
assert_parsed_expression_type("product(n, 4, 10)", ExpressionNode::Type::Product);
|
||||
#endif
|
||||
assert_parsed_expression_type("product(n, 4, 10)", ExpressionNode::Type::Product);
|
||||
assert_parsed_expression_type("quo(29, 10)", ExpressionNode::Type::DivisionQuotient);
|
||||
#if 0
|
||||
assert_parsed_expression_type("random()", ExpressionNode::Type::Random);
|
||||
@@ -58,8 +58,8 @@ QUIZ_CASE(poincare_parse_function) {
|
||||
assert_parsed_expression_type("R(2)", ExpressionNode::Type::SquareRoot);
|
||||
#if 0
|
||||
assert_parsed_expression_type("round(2,3)", ExpressionNode::Type::Round);
|
||||
assert_parsed_expression_type("sum(n, 4, 10)", ExpressionNode::Type::Sum);
|
||||
#endif
|
||||
assert_parsed_expression_type("sum(n, 4, 10)", ExpressionNode::Type::Sum);
|
||||
#if MATRICES_ARE_DEFINED
|
||||
assert_parsed_expression_type("trace([[1,2,3][4,5,6][7,8,9]])", ExpressionNode::Type::MatrixTrace);
|
||||
assert_parsed_expression_type("transpose([[1,2,3][4,5,6][7,8,9]])", ExpressionNode::Type::MatrixTranspose);
|
||||
@@ -124,10 +124,10 @@ QUIZ_CASE(poincare_function_evaluate) {
|
||||
assert_parsed_expression_evaluates_to<float>("permute(10, 4)", "5040");
|
||||
assert_parsed_expression_evaluates_to<double>("permute(10, 4)", "5040");
|
||||
|
||||
#endif
|
||||
assert_parsed_expression_evaluates_to<float>("product(n, 4, 10)", "604800");
|
||||
assert_parsed_expression_evaluates_to<double>("product(n, 4, 10)", "604800");
|
||||
|
||||
#endif
|
||||
assert_parsed_expression_evaluates_to<float>("quo(29, 10)", "2");
|
||||
assert_parsed_expression_evaluates_to<double>("quo(29, 10)", "2");
|
||||
|
||||
@@ -146,11 +146,9 @@ QUIZ_CASE(poincare_function_evaluate) {
|
||||
|
||||
assert_parsed_expression_evaluates_to<float>("R(-1)", "I");
|
||||
assert_parsed_expression_evaluates_to<double>("R(-1)", "I");
|
||||
#if 0
|
||||
|
||||
assert_parsed_expression_evaluates_to<float>("sum(n, 4, 10)", "49");
|
||||
assert_parsed_expression_evaluates_to<double>("sum(n, 4, 10)", "49");
|
||||
#endif
|
||||
|
||||
#if MATRICES_ARE_DEFINED
|
||||
assert_parsed_expression_evaluates_to<float>("trace([[1,2,3][4,5,6][7,8,9]])", "15");
|
||||
@@ -184,9 +182,9 @@ QUIZ_CASE(poincare_function_evaluate) {
|
||||
assert_parsed_expression_evaluates_to<float>("prediction95(0.1, 100)", "[[0.0412,0.1588]]");
|
||||
assert_parsed_expression_evaluates_to<double>("prediction95(0.1, 100)", "[[0.0412,0.1588]]");
|
||||
|
||||
#endif
|
||||
assert_parsed_expression_evaluates_to<float>("product(2+n*I, 1, 5)", "(-100)-540*I");
|
||||
assert_parsed_expression_evaluates_to<double>("product(2+n*I, 1, 5)", "(-100)-540*I");
|
||||
#endif
|
||||
|
||||
assert_parsed_expression_evaluates_to<float>("root(3+I, 3)", "1.459366+0.1571201*I");
|
||||
assert_parsed_expression_evaluates_to<double>("root(3+I, 3)", "1.4593656008684+1.5712012294394E-1*I");
|
||||
@@ -199,11 +197,10 @@ QUIZ_CASE(poincare_function_evaluate) {
|
||||
|
||||
assert_parsed_expression_evaluates_to<float>("R(3+I)", "1.755317+0.2848488*I");
|
||||
assert_parsed_expression_evaluates_to<double>("R(3+I)", "1.7553173018244+2.8484878459314E-1*I");
|
||||
#if 0
|
||||
|
||||
assert_parsed_expression_evaluates_to<double>("sum(2+n*I,1,5)", "10+15*I");
|
||||
assert_parsed_expression_evaluates_to<double>("sum(2+n*I,1,5)", "10+15*I");
|
||||
#endif
|
||||
|
||||
#if MATRICES_ARE_DEFINED
|
||||
assert_parsed_expression_evaluates_to<float>("transpose([[1,2,3][4,5,-6][7,8,9]])", "[[1,4,7][2,5,8][3,-6,9]]");
|
||||
assert_parsed_expression_evaluates_to<float>("transpose([[1,7,5][4,2,8]])", "[[1,4][7,2][5,8]]");
|
||||
|
||||
Reference in New Issue
Block a user