Numworks Epsilon  1.4.1
Graphing Calculator Operating System
sequence_context.h
Go to the documentation of this file.
1 #ifndef SEQUENCE_SEQUENCE_CONTEXT_H
2 #define SEQUENCE_SEQUENCE_CONTEXT_H
3 
4 #include <poincare.h>
5 
6 namespace Sequence {
7 
8 constexpr static int MaxRecurrenceDepth = 2;
9 static constexpr int MaxNumberOfSequences = 2;
10 
11 class SequenceStore;
12 class SequenceContext;
13 
14 template<typename T>
16 public:
18  T valueOfSequenceAtPreviousRank(int sequenceIndex, int rank) const;
19  void resetCache();
20  bool iterateUntilRank(int n, SequenceStore * sequenceStore, SequenceContext * sqctx);
21 private:
22  constexpr static int k_maxRecurrentRank = 10000;
23  /* Cache:
24  * In order to accelerate the computation of values of recurrent sequences,
25  * we memoize the last computed values of the sequence and their associated
26  * ranks (n and n+1 for instance). Thereby, when another evaluation at a
27  * superior rank k > n+1 is called, we avoid iterating from 0 but can start
28  * from n. */
29  void step(SequenceStore * sequenceStore, SequenceContext * sqctx);
30  int m_rank;
31  T m_values[MaxNumberOfSequences][MaxRecurrenceDepth+1];
32 };
33 
35 public:
36  SequenceContext(Poincare::Context * parentContext, SequenceStore * sequenceStore) :
37  Context(),
38  m_floatSequenceContext(),
39  m_doubleSequenceContext(),
40  m_sequenceStore(sequenceStore),
41  m_parentContext(parentContext) {}
42  /* expressionForSymbol & setExpressionForSymbolName directly call the parent
43  * context respective methods. Indeed, special chars like n, u(n), u(n+1),
44  * v(n), v(n+1) are taken into accound only when evaluating sequences which
45  * is done in another context. */
46  const Poincare::Expression * expressionForSymbol(const Poincare::Symbol * symbol) override {
47  return m_parentContext->expressionForSymbol(symbol);
48  }
49  void setExpressionForSymbolName(const Poincare::Expression * expression, const Poincare::Symbol * symbol, Poincare::Context & context) override {
50  m_parentContext->setExpressionForSymbolName(expression, symbol, context);
51  }
52  template<typename T> T valueOfSequenceAtPreviousRank(int sequenceIndex, int rank) const {
53  if (sizeof(T) == sizeof(float)) {
54  return m_floatSequenceContext.valueOfSequenceAtPreviousRank(sequenceIndex, rank);
55  }
56  return m_doubleSequenceContext.valueOfSequenceAtPreviousRank(sequenceIndex, rank);
57  }
58  void resetCache() {
59  m_floatSequenceContext.resetCache();
60  m_doubleSequenceContext.resetCache();
61  }
62  template<typename T> bool iterateUntilRank(int n) {
63  if (sizeof(T) == sizeof(float)) {
64  return m_floatSequenceContext.iterateUntilRank(n, m_sequenceStore, this);
65  }
66  return m_doubleSequenceContext.iterateUntilRank(n, m_sequenceStore, this);
67  }
68 private:
69  TemplatedSequenceContext<float> m_floatSequenceContext;
70  TemplatedSequenceContext<double> m_doubleSequenceContext;
71  SequenceStore * m_sequenceStore;
72  Poincare::Context * m_parentContext;
73 };
74 
75 }
76 
77 #endif
virtual const Expression * expressionForSymbol(const Symbol *symbol)=0
#define T(x)
Definition: events.cpp:26
T valueOfSequenceAtPreviousRank(int sequenceIndex, int rank) const
const Poincare::Expression * expressionForSymbol(const Poincare::Symbol *symbol) override
Definition: app.cpp:7
void setExpressionForSymbolName(const Poincare::Expression *expression, const Poincare::Symbol *symbol, Poincare::Context &context) override
SequenceContext(Poincare::Context *parentContext, SequenceStore *sequenceStore)
virtual void setExpressionForSymbolName(const Expression *expression, const Symbol *symbol, Context &context)=0
T valueOfSequenceAtPreviousRank(int sequenceIndex, int rank) const
bool iterateUntilRank(int n, SequenceStore *sequenceStore, SequenceContext *sqctx)