mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-21 06:40:37 +01:00
[poincare] Sine
This commit is contained in:
@@ -69,6 +69,7 @@ objs += $(addprefix poincare/src/,\
|
||||
rational.o\
|
||||
serialization_helper.o\
|
||||
simplification_helper.o\
|
||||
sine.o\
|
||||
square_root.o\
|
||||
subtraction.o\
|
||||
symbol.o\
|
||||
|
||||
@@ -108,6 +108,7 @@
|
||||
#include <poincare/global_context.h>
|
||||
#include <poincare/addition.h>
|
||||
#include <poincare/cosine.h>
|
||||
#include <poincare/sine.h>
|
||||
#include <poincare/matrix_complex.h>
|
||||
#include <poincare/multiplication.h>
|
||||
#include <poincare/power.h>
|
||||
|
||||
@@ -14,6 +14,7 @@ class Context;
|
||||
|
||||
class Expression : public TreeByValue {
|
||||
friend class CosineNode;
|
||||
friend class SineNode;
|
||||
friend class ExpressionNode;
|
||||
friend class Multiplication;
|
||||
friend class Subtraction;
|
||||
|
||||
@@ -1,32 +1,50 @@
|
||||
#ifndef POINCARE_SINE_H
|
||||
#define POINCARE_SINE_H
|
||||
|
||||
#include <poincare/layout_helper.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/approximation_helper.h>
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/layout_helper.h>
|
||||
#include <poincare/serialization_helper.h>
|
||||
#include <poincare/trigonometry.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Sine : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
friend class Tangent;
|
||||
float characteristicXRange(Context & context, Preferences::AngleUnit angleUnit) const override;
|
||||
class SineNode : public ExpressionNode {
|
||||
//friend class Tangent;
|
||||
public:
|
||||
Type type() const override;
|
||||
template<typename T> static std::complex<T> computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit = Preferences::AngleUnit::Radian);
|
||||
// Allocation Failure
|
||||
static SineNode * FailedAllocationStaticNode();
|
||||
SineNode * failedAllocationStaticNode() override { return FailedAllocationStaticNode(); }
|
||||
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(SineNode); }
|
||||
int numberOfChildren() const override { return 1; }
|
||||
#if POINCARE_TREE_LOG
|
||||
virtual void logNodeName(std::ostream & stream) const override {
|
||||
stream << "Sine";
|
||||
}
|
||||
#endif
|
||||
|
||||
// Properties
|
||||
Type type() const override { return Type::Sine; }
|
||||
float characteristicXRange(Context & context, Preferences::AngleUnit angleUnit) const override;
|
||||
|
||||
template<typename T> static Complex<T> computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit = Preferences::AngleUnit::Radian);
|
||||
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
// Layout
|
||||
LayoutReference createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, name());
|
||||
}
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, name());
|
||||
}
|
||||
const char * name() const { return "sin"; }
|
||||
/* Simplication */
|
||||
Expression shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
|
||||
// Simplication
|
||||
Expression shallowReduce(Context& context, Preferences::AngleUnit angleUnit) const override;
|
||||
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
@@ -35,6 +53,17 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
class Sine : public Expression {
|
||||
public:
|
||||
Sine() : Expression(TreePool::sharedPool()->createTreeNode<SineNode>()) {}
|
||||
Sine(const SineNode * n) : Expression(n) {}
|
||||
Sine(Expression operand) : Sine() {
|
||||
replaceChildAtIndexInPlace(0, operand);
|
||||
}
|
||||
|
||||
Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -156,8 +156,9 @@ rem { poincare_expression_yylval.expression = new DivisionRemainder(); return FU
|
||||
*/
|
||||
root { poincare_expression_yylval.expression = NthRoot(); return FUNCTION; }
|
||||
/*round { poincare_expression_yylval.expression = new Round(); return FUNCTION; }
|
||||
sin { poincare_expression_yylval.expression = new Sine(); return FUNCTION; }
|
||||
sinh { poincare_expression_yylval.expression = new HyperbolicSine(); return FUNCTION; }
|
||||
*/
|
||||
sin { poincare_expression_yylval.expression = Sine(); return FUNCTION; }
|
||||
/*sinh { poincare_expression_yylval.expression = new HyperbolicSine(); return FUNCTION; }
|
||||
sum { poincare_expression_yylval.expression = new Sum(); return FUNCTION; }
|
||||
tan { poincare_expression_yylval.expression = new Tangent(); return FUNCTION; }
|
||||
tanh { poincare_expression_yylval.expression = new HyperbolicTangent(); return FUNCTION; }
|
||||
|
||||
@@ -1,49 +1,43 @@
|
||||
#include <poincare/sine.h>
|
||||
#include <poincare/trigonometry.h>
|
||||
#include <poincare/hyperbolic_sine.h>
|
||||
#include <poincare/multiplication.h>
|
||||
#include <poincare/symbol.h>
|
||||
#include <poincare/complex.h>
|
||||
#include <poincare/simplification_helper.h>
|
||||
#include <ion.h>
|
||||
extern "C" {
|
||||
#include <assert.h>
|
||||
}
|
||||
#include <cmath>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
Expression::Type Sine::type() const {
|
||||
return Expression::Type::Sine;
|
||||
SineNode * SineNode::FailedAllocationStaticNode() {
|
||||
static AllocationFailureExpressionNode<SineNode> failure;
|
||||
TreePool::sharedPool()->registerStaticNodeIfRequired(&failure);
|
||||
return &failure;
|
||||
}
|
||||
|
||||
Expression * Sine::clone() const {
|
||||
Sine * a = new Sine(m_operands, true);
|
||||
return a;
|
||||
}
|
||||
|
||||
float Sine::characteristicXRange(Context & context, Preferences::AngleUnit angleUnit) const {
|
||||
return Trigonometry::characteristicXRange(this, context, angleUnit);
|
||||
float SineNode::characteristicXRange(Context & context, Preferences::AngleUnit angleUnit) const {
|
||||
return Trigonometry::characteristicXRange(Sine(this), context, angleUnit);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::complex<T> Sine::computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit) {
|
||||
Complex<T> SineNode::computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit) {
|
||||
std::complex<T> angleInput = Trigonometry::ConvertToRadian(c, angleUnit);
|
||||
std::complex<T> res = std::sin(angleInput);
|
||||
return Trigonometry::RoundToMeaningfulDigits(res);
|
||||
return Complex<T>(Trigonometry::RoundToMeaningfulDigits(res));
|
||||
}
|
||||
|
||||
Expression Sine::shallowReduce(Context& context, Preferences::AngleUnit angleUnit) {
|
||||
Expression * e = Expression::defaultShallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
Expression SineNode::shallowReduce(Context& context, Preferences::AngleUnit angleUnit) const {
|
||||
return Sine(this).shallowReduce(context, angleUnit);
|
||||
}
|
||||
|
||||
Expression Sine::shallowReduce(Context& context, Preferences::AngleUnit angleUnit) const {
|
||||
Expression e = Expression::defaultShallowReduce(context, angleUnit);
|
||||
if (e.isUndefinedOrAllocationFailure()) {
|
||||
return e;
|
||||
}
|
||||
#if MATRIX_EXACT_REDUCING
|
||||
Expression * op = editableOperand(0);
|
||||
if (op->type() == Type::Matrix) {
|
||||
return SimplificationHelper::Map(this, context, angleUnit);
|
||||
Expression op = childAtIndex(0);
|
||||
if (op.type() == ExpressionNode::Type::Matrix) {
|
||||
return SimplificationHelper::Map(*this, context, angleUnit);
|
||||
}
|
||||
#endif
|
||||
return Trigonometry::shallowReduceDirectFunction(this, context, angleUnit);
|
||||
return Trigonometry::shallowReduceDirectFunction(*this, context, angleUnit);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,9 +7,7 @@
|
||||
using namespace Poincare;
|
||||
|
||||
QUIZ_CASE(poincare_parse_trigo) {
|
||||
#if 0
|
||||
assert_parsed_expression_type("sin(0)", ExpressionNode::Type::Sine);
|
||||
#endif
|
||||
assert_parsed_expression_type("cos(0)", ExpressionNode::Type::Cosine);
|
||||
#if 0
|
||||
assert_parsed_expression_type("tan(0)", ExpressionNode::Type::Tangent);
|
||||
@@ -47,7 +45,6 @@ QUIZ_CASE(poincare_trigo_evaluate) {
|
||||
assert_parsed_expression_evaluates_to<float>("cos(I-4)", "(-1.008625)-0.889395*I", Radian);
|
||||
assert_parsed_expression_evaluates_to<float>("cos(I-4)", "0.997716+0.001218*I", Degree, Cartesian, 6);
|
||||
|
||||
#if 0
|
||||
/* sin: R -> R (oscillator)
|
||||
* Ri -> Ri (odd)
|
||||
*/
|
||||
@@ -69,6 +66,7 @@ QUIZ_CASE(poincare_trigo_evaluate) {
|
||||
assert_parsed_expression_evaluates_to<float>("sin(I-4)", "1.16781-0.768163*I", Radian, Cartesian, 6);
|
||||
assert_parsed_expression_evaluates_to<float>("sin(I-4)", "(-0.069767)+0.017412*I", Degree, Cartesian, 6);
|
||||
|
||||
#if 0
|
||||
/* tan: R -> R (tangent-style)
|
||||
* Ri -> Ri (odd)
|
||||
*/
|
||||
@@ -389,7 +387,6 @@ QUIZ_CASE(poincare_trigo_simplify) {
|
||||
assert_parsed_expression_simplify_to("cos(-60)", "1/2", Preferences::AngleUnit::Degree);
|
||||
assert_parsed_expression_simplify_to("cos(7380/5)", "(1+R(5))/4", Preferences::AngleUnit::Degree);
|
||||
assert_parsed_expression_simplify_to("cos(112.5)", "-R(2-R(2))/2", Preferences::AngleUnit::Degree);
|
||||
#if 0
|
||||
// -- sin
|
||||
assert_parsed_expression_simplify_to("sin(0)", "0");
|
||||
assert_parsed_expression_simplify_to("sin(P)", "0");
|
||||
@@ -426,6 +423,7 @@ QUIZ_CASE(poincare_trigo_simplify) {
|
||||
assert_parsed_expression_simplify_to("sin(-60)", "-R(3)/2", Preferences::AngleUnit::Degree);
|
||||
assert_parsed_expression_simplify_to("sin(612)", "-(R(2)*R(5+R(5)))/4", Preferences::AngleUnit::Degree);
|
||||
assert_parsed_expression_simplify_to("sin(36)", "(R(2)*R(5-R(5)))/4", Preferences::AngleUnit::Degree);
|
||||
#if 0
|
||||
// -- tan
|
||||
assert_parsed_expression_simplify_to("tan(0)", "0");
|
||||
assert_parsed_expression_simplify_to("tan(P)", "0");
|
||||
|
||||
Reference in New Issue
Block a user