Numworks Epsilon  1.4.1
Graphing Calculator Operating System
sequence.cpp
Go to the documentation of this file.
1 #include <quiz.h>
2 #include <string.h>
3 #include <assert.h>
4 #include <cmath>
5 #include "../sequence_store.h"
6 #include "../sequence_context.h"
7 
8 using namespace Poincare;
9 
10 namespace Sequence {
11 
12 void check_sequences_defined_by(double result[2][10], Sequence::Type typeU, const char * definitionU, const char * conditionU1 = nullptr, const char * conditionU2 = nullptr, Sequence::Type typeV = Sequence::Type::Explicit, const char * definitionV = nullptr, const char * conditionV1 = nullptr, const char * conditionV2 = nullptr) {
13  GlobalContext globalContext;
14  SequenceStore store;
15  SequenceContext sequenceContext(&globalContext, &store);
16 
17  Sequence * u = nullptr;
18  Sequence * v = nullptr;
19  if (definitionU) {
20  u = store.addEmptyFunction();
21  assert(u->name()[0] == 'u');
22  u->setType(typeU);
23  u->setContent(definitionU);
24  if (conditionU1) {
25  u->setFirstInitialConditionContent(conditionU1);
26  }
27  if (conditionU2) {
28  u->setSecondInitialConditionContent(conditionU2);
29  }
30  }
31  if (definitionV) {
32  if (store.numberOfFunctions() == 0) {
33  Sequence * tempU = store.addEmptyFunction();
34  v = store.addEmptyFunction();
35  store.removeFunction(tempU);
36  v = store.functionAtIndex(0);
37  } else {
38  assert(store.numberOfFunctions() == 1);
39  v = store.addEmptyFunction();
40  }
41  v->setType(typeV);
42  v->setContent(definitionV);
43  if (conditionV1) {
44  v->setFirstInitialConditionContent(conditionV1);
45  }
46  if (conditionV2) {
47  v->setSecondInitialConditionContent(conditionV2);
48  }
49  }
50  for (int j = 0; j < 10; j++) {
51  if (u && u->isDefined()) {
52  double un = u->evaluateAtAbscissa((double)j, &sequenceContext);
53  assert((std::isnan(un) && std::isnan(result[0][j])) || (un == result[0][j]));
54  }
55  if (v && v->isDefined()) {
56  double vn = v->evaluateAtAbscissa((double)j, &sequenceContext);
57  assert((std::isnan(vn) && std::isnan(result[1][j])) || (vn == result[1][j]));
58  }
59  }
60 }
61 
62 QUIZ_CASE(sequence_evaluation) {
63  // u(n) = n
64  double result0[2][10] = {{0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0}, {}};
65  check_sequences_defined_by(result0, Sequence::Type::Explicit, "n");
66 
67  // u(n+1) = u(n)+n, u(0) = 0
68  double result1[2][10] = {{0.0, 0.0, 1.0, 3.0, 6.0, 10.0, 15.0, 21.0, 28.0, 36.0}, {}};
69  check_sequences_defined_by(result1, Sequence::Type::SingleRecurrence, "u(n)+n", "0");
70 
71  // u(n+2) = u(n+1)+u(n)+n, u(0) = 0, u(1) = 0
72  double result2[2][10] = {{0.0, 0.0, 0.0, 1.0, 3.0, 7.0, 14.0, 26.0, 46.0, 79.0}, {}};
73  check_sequences_defined_by(result2, Sequence::Type::DoubleRecurrence, "u(n)+u(n+1)+n", "0", "0");
74 
75  // u independent, v defined with u
76  // u(n) = n; v(n) = u(n)+n
77  double result3[2][10] = {{0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0},
78  {0.0, 2.0, 4.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0, 18.0}};
79  check_sequences_defined_by(result3, Sequence::Type::Explicit, "n", nullptr, nullptr, Sequence::Type::Explicit, "u(n)+n");
80 
81  // u(n+1) = u(n)+n, u(0) = 0; v(n) = u(n)+n
82  double result4[2][10] = {{0.0, 0.0, 1.0, 3.0, 6.0, 10.0, 15.0, 21.0, 28.0, 36.0},
83  {0.0, 1.0, 3.0, 6.0, 10.0, 15.0, 21.0, 28.0, 36.0, 45.0}};
84  check_sequences_defined_by(result4, Sequence::Type::SingleRecurrence, "n+u(n)", "0", nullptr, Sequence::Type::Explicit, "u(n)+n");
85 
86  // u(n+2) = u(n+1)+u(n)+n, u(0) = 0, u(1) = 0; v(n) = u(n)+n
87  double result5[2][10] = {{0.0, 0.0, 0.0, 1.0, 3.0, 7.0, 14.0, 26.0, 46.0, 79.0},
88  {0.0, 1.0, 2.0, 4.0, 7.0, 12.0, 20.0, 33.0, 54.0, 88.0}};
89  check_sequences_defined_by(result5, Sequence::Type::DoubleRecurrence, "n+u(n)+u(n+1)", "0", "0", Sequence::Type::Explicit, "u(n)+n");
90 
91  // u(n) = n; v(n+1) = u(n)+u(n+1)+n, v(0) = 0
92  double result6[2][10] = {{0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0},
93  {0.0, 1.0, 4.0, 7.0, 10.0, 13.0, 16.0, 19.0, 22.0, 25.0}};
94  check_sequences_defined_by(result6, Sequence::Type::Explicit, "n", nullptr, nullptr, Sequence::Type::SingleRecurrence, "u(n)+u(n+1)+n", "0");
95 
96  // u(n+1) = u(n)+n, u(0) = 0; v(n+1) = u(n)+u(n+1)+n, v(0) = 0
97  double result7[2][10] = {{0.0, 0.0, 1.0, 3.0, 6.0, 10.0, 15.0, 21.0, 28.0, 36.0},
98  {0.0, 0.0, 2.0, 6.0, 12.0, 20.0, 30.0, 42.0, 56.0, 72.0}};
99  check_sequences_defined_by(result7, Sequence::Type::SingleRecurrence, "n+u(n)", "0", nullptr, Sequence::Type::SingleRecurrence, "u(n)+u(n+1)+n", "0");
100 
101  // u(n+2) = u(n+1)+u(n)+n, u(0) = 0, u(1) = 0; v(n+1) = u(n)+u(n+1)+n, v(0) = 0
102  double result8[2][10] = {{0.0, 0.0, 0.0, 1.0, 3.0, 7.0, 14.0, 26.0, 46.0, 79.0},
103  {0.0, 0.0, 1.0, 3.0, 7.0, 14.0, 26.0, 46.0, 79.0, 133.0}};
104  check_sequences_defined_by(result8, Sequence::Type::DoubleRecurrence, "n+u(n)+u(n+1)", "0", "0", Sequence::Type::SingleRecurrence, "u(n)+u(n+1)+n", "0");
105 
106  // u(n) = n; v(n+2) = u(n)+u(n+1)+n, v(0) = 0, v(1)=0
107  double result9[2][10] = {{0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0},
108  {0.0, 0.0, 1.0, 4.0, 7.0, 10.0, 13.0, 16.0, 19.0, 22.0}};
109  check_sequences_defined_by(result9, Sequence::Type::Explicit, "n", nullptr, nullptr, Sequence::Type::DoubleRecurrence, "u(n)+u(n+1)+n", "0", "0");
110 
111  // u(n+1) = u(n)+n, u(0) = 0; v(n+2) = u(n)+u(n+1)+n, v(0) = 0, v(1)=0
112  double result10[2][10] = {{0.0, 0.0, 1.0, 3.0, 6.0, 10.0, 15.0, 21.0, 28.0, 36.0},
113  {0.0, 0.0, 0.0, 2.0, 6.0, 12.0, 20.0, 30.0, 42.0, 56.0}};
114  check_sequences_defined_by(result10, Sequence::Type::SingleRecurrence, "n+u(n)", "0", nullptr, Sequence::Type::DoubleRecurrence, "u(n)+u(n+1)+n", "0", "0");
115 
116  // u(n+2) = u(n+1)+u(n)+n, u(0) = 0, u(1) = 0; v(n+2) = u(n)+u(n+1)+n, v(0) = 0, v(1)=0
117  double result11[2][10] = {{0.0, 0.0, 0.0, 1.0, 3.0, 7.0, 14.0, 26.0, 46.0, 79.0},
118  {0.0, 0.0, 0.0, 1.0, 3.0, 7.0, 14.0, 26.0, 46.0, 79.0}};
119  check_sequences_defined_by(result11, Sequence::Type::DoubleRecurrence, "n+u(n)+u(n+1)", "0", "0", Sequence::Type::DoubleRecurrence, "u(n)+u(n+1)+n", "0", "0");
120 
121  // v independent, u defined with v
122 
123  // u(n) = v(n); v(n) = u(n)
124  double result12[2][10] = {{NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN},
125  {NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN}};
126  check_sequences_defined_by(result12, Sequence::Type::Explicit, "v(n)", nullptr, nullptr, Sequence::Type::Explicit, "u(n)");
127 
128  // u(n+1) = v(n)+n, u(0)=0; v(n) = u(n)+n
129  double result13[2][10] = {{0.0, 0.0, 2.0, 6.0, 12.0, 20.0, 30.0, 42.0, 56.0, 72.0}, {0.0, 1.0, 4.0, 9.0, 16.0, 25.0, 36.0, 49.0, 64.0, 81}};
130  check_sequences_defined_by(result13, Sequence::Type::SingleRecurrence, "v(n)+n", "0", nullptr, Sequence::Type::Explicit, "u(n)+n");
131 
132  // u(n+2) = v(n+1)+u(n+1)+v(n)+u(n)+n, u(1) = 0; u(0)=0; v(n) = u(n)+n
133  double result14[2][10] = {{0.0, 0.0, 1.0, 6.0, 21.0, 64.0, 183.0, 510.0, 1405.0, 3852.0}, {0.0, 1.0, 3.0, 9.0, 25.0, 69.0, 189.0, 517.0, 1413.0, 3861.0}};
134  check_sequences_defined_by(result14, Sequence::Type::DoubleRecurrence, "v(n+1)+v(n)+u(n+1)+u(n)+n", "0", "0", Sequence::Type::Explicit, "u(n)+n");
135 
136  // u(n) = v(n)+n; v(n+1) = u(n)+n, v(0)=0
137  double result15[2][10] = {{0.0, 1.0, 4.0, 9.0, 16.0, 25.0, 36.0, 49.0, 64.0, 81},
138  {0.0, 0.0, 2.0, 6.0, 12.0, 20.0, 30.0, 42.0, 56.0, 72.0}};
139  check_sequences_defined_by(result15, Sequence::Type::Explicit, "v(n)+n", nullptr, nullptr, Sequence::Type::SingleRecurrence, "u(n)+n", "0");
140 
141  // u(n+1) = v(n)+n, u(0)=0; v(n+1) = u(n)+n, v(0)=0
142  double result16[2][10] = {{0.0, 0.0, 1.0, 3.0, 6.0, 10.0, 15.0, 21.0, 28.0, 36.0}, {0.0, 0.0, 1.0, 3.0, 6.0, 10.0, 15.0, 21.0, 28.0, 36.0}};
143  check_sequences_defined_by(result16, Sequence::Type::SingleRecurrence, "v(n)+n", "0", nullptr, Sequence::Type::SingleRecurrence, "u(n)+n", "0");
144 
145  // u(n+2) = v(n+1)+u(n+1)+v(n)+u(n)+n, u(1) = 0, u(0) = 0; v(n+1) = u(n)+n, v(0)=0
146  double result17[2][10] = {{0.0, 0.0, 0.0, 2.0, 7.0, 19.0, 46.0, 105.0, 233.0, 509.0}, {0.0, 0.0, 1.0, 2.0, 5.0, 11.0, 24.0, 52.0, 112.0, 241.0}};
147  check_sequences_defined_by(result17, Sequence::Type::DoubleRecurrence, "v(n+1)+v(n)+u(n+1)+u(n)+n", "0", "0", Sequence::Type::SingleRecurrence, "u(n)+n", "0");
148 
149  // u(n) = n; v undefined
150  double result18[2][10] = {{0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0}, {NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN}};
151  check_sequences_defined_by(result18, Sequence::Type::Explicit, "n");
152 
153  // u undefined; v(n) = n
154  double result19[2][10] = {{NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN}, {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0}};
155  check_sequences_defined_by(result19, Sequence::Type::Explicit, nullptr, nullptr, nullptr, Sequence::Type::Explicit, "n");
156 }
157 
158 }
void setFirstInitialConditionContent(const char *c)
Definition: sequence.cpp:190
#define NAN
Definition: math.h:30
#define assert(e)
Definition: assert.h:9
Sequence * functionAtIndex(int i) override
void check_sequences_defined_by(double result[2][10], Sequence::Type typeU, const char *definitionU, const char *conditionU1=nullptr, const char *conditionU2=nullptr, Sequence::Type typeV=Sequence::Type::Explicit, const char *definitionV=nullptr, const char *conditionV1=nullptr, const char *conditionV2=nullptr)
Definition: sequence.cpp:12
bool isDefined() override
Definition: sequence.cpp:270
void setSecondInitialConditionContent(const char *c)
Definition: sequence.cpp:202
const char * name() const
Definition: function.cpp:68
#define isnan(x)
Definition: math.h:43
void setType(Type type)
Definition: sequence.cpp:107
Sequence * addEmptyFunction() override
void setContent(const char *c) override
Definition: sequence.cpp:186
Definition: app.cpp:7
QUIZ_CASE(sequence_evaluation)
Definition: sequence.cpp:62
float evaluateAtAbscissa(float x, Poincare::Context *context) const override
Definition: sequence.h:49
void removeFunction(Shared::Function *f) override