Blame view

Giac_maj/epsilon-giac/apps/sequence/sequence.h 4.44 KB
6663b6c9   adorian   projet complet av...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
  #ifndef SEQUENCE_SEQUENCE_H
  #define SEQUENCE_SEQUENCE_H
  
  #include "../shared/function.h"
  #include <assert.h>
  
  namespace Sequence {
  
  class Sequence : public Shared::Function {
  public:
    enum class Type {
      Explicite = 0,
      SingleRecurrence = 1,
      DoubleRecurrence = 2
    };
    Sequence(const char * text = nullptr, KDColor color = KDColorBlack);
    ~Sequence();
    Sequence& operator=(const Sequence& other);
    Sequence& operator=(Sequence&& other) = delete;
    Sequence(const Sequence& other) = delete;
    Sequence(Sequence&& other) = delete;
    uint32_t checksum() override;
    Type type();
    void setType(Type type);
    const char * firstInitialConditionText();
    const char * secondInitialConditionText();
    Poincare::Expression * firstInitialConditionExpression() const;
    Poincare::Expression * secondInitialConditionExpression() const;
    Poincare::ExpressionLayout * firstInitialConditionLayout();
    Poincare::ExpressionLayout * secondInitialConditionLayout();
    void setContent(const char * c) override;
    void setFirstInitialConditionContent(const char * c);
    void setSecondInitialConditionContent(const char * c);
    int numberOfElements();
    Poincare::ExpressionLayout * nameLayout();
    Poincare::ExpressionLayout * definitionName();
    Poincare::ExpressionLayout * firstInitialConditionName();
    Poincare::ExpressionLayout * secondInitialConditionName();
    bool isDefined() override;
    bool isEmpty() override;
    float evaluateAtAbscissa(float x, Poincare::Context * context) const override {
      return templatedEvaluateAtAbscissa(x, context);
    }
    double evaluateAtAbscissa(double x, Poincare::Context * context) const override {
      return templatedEvaluateAtAbscissa(x, context);
    }
    double sumOfTermsBetweenAbscissa(double start, double end, Poincare::Context * context);
    void tidy() override;
  private:
    constexpr static int k_maxRecurrentRank = 10000;
    constexpr static double k_maxNumberOfTermsInSum = 100000.0;
    constexpr static size_t k_dataLengthInBytes = (3*TextField::maxBufferSize()+3)*sizeof(char)+1;
    static_assert((k_dataLengthInBytes & 0x3) == 0, "The sequence data size is not a multiple of 4 bytes (cannot compute crc)"); // Assert that dataLengthInBytes is a multiple of 4
    char symbol() const override;
    template<typename T> T templatedEvaluateAtAbscissa(T x, Poincare::Context * context) const;
    Type m_type;
    char m_firstInitialConditionText[TextField::maxBufferSize()];
    char m_secondInitialConditionText[TextField::maxBufferSize()];
    mutable Poincare::Expression * m_firstInitialConditionExpression;
    mutable Poincare::Expression * m_secondInitialConditionExpression;
    Poincare::ExpressionLayout * m_firstInitialConditionLayout;
    Poincare::ExpressionLayout * m_secondInitialConditionLayout;
    Poincare::ExpressionLayout * m_nameLayout;
    Poincare::ExpressionLayout * m_definitionName;
    Poincare::ExpressionLayout * m_firstInitialConditionName;
    Poincare::ExpressionLayout * m_secondInitialConditionName;
    /* In order to accelerate the computation of values of recurrent sequences,
     * we memoize the last computed values of the sequence and their associated
     * ranks (n and n+1 for instance). Thereby, when another evaluation at a
     * superior rank k > n+1 is called, we avoid iterating from 0 but can start
     * from n. */
    constexpr static int k_maxRecurrenceDepth = 2;
    mutable int m_indexBufferFloat[k_maxRecurrenceDepth];
    mutable int m_indexBufferDouble[k_maxRecurrenceDepth];
    mutable float m_bufferFloat[k_maxRecurrenceDepth];
    mutable double m_bufferDouble[k_maxRecurrenceDepth];
    void resetBuffer() const;
    template<typename T> void setBufferValue(T value, int i) const {
      assert(i >= 0 && i < k_maxRecurrentRank);
      if (sizeof(T) == sizeof(float)) {
        m_bufferFloat[i] = value;
      } else {
        m_bufferDouble[i] = value;
      }
    }
    template<typename T> void setBufferIndexValue(int index, int i) const {
      assert(i >= 0 && i < k_maxRecurrentRank);
      if (sizeof(T) == sizeof(float)) {
        m_indexBufferFloat[i] = index;
      } else {
        m_indexBufferDouble[i] = index;
      }
    }
    template<typename T> T bufferValue(int i) const {
      assert(i >= 0 && i < k_maxRecurrentRank);
      if (sizeof(T) == sizeof(float)) {
        return m_bufferFloat[i];
      } else {
        return m_bufferDouble[i];
      }
    }
    template<typename T> int indexBuffer(int i) const {
      assert(i >= 0 && i < k_maxRecurrentRank);
      if (sizeof(T) == sizeof(float)) {
        return m_indexBufferFloat[i];
      } else {
        return m_indexBufferDouble[i];
      }
    }
  };
  
  }
  
  #endif