4 #include "../../poincare/src/layout/string_layout.h" 5 #include "../../poincare/src/layout/baseline_relative_layout.h" 16 m_type(
Type::Explicit),
17 m_firstInitialConditionText(),
18 m_secondInitialConditionText(),
19 m_firstInitialConditionExpression(nullptr),
20 m_secondInitialConditionExpression(nullptr),
21 m_firstInitialConditionLayout(nullptr),
22 m_secondInitialConditionLayout(nullptr),
23 m_nameLayout(nullptr),
24 m_definitionName(nullptr),
25 m_firstInitialConditionName(nullptr),
26 m_secondInitialConditionName(nullptr),
31 Sequence::~Sequence() {
32 if (m_firstInitialConditionLayout !=
nullptr) {
33 delete m_firstInitialConditionLayout;
34 m_firstInitialConditionLayout =
nullptr;
36 if (m_secondInitialConditionLayout !=
nullptr) {
37 delete m_secondInitialConditionLayout;
38 m_secondInitialConditionLayout =
nullptr;
40 if (m_firstInitialConditionExpression !=
nullptr) {
41 delete m_firstInitialConditionExpression;
42 m_firstInitialConditionExpression =
nullptr;
44 if (m_secondInitialConditionExpression !=
nullptr) {
45 delete m_secondInitialConditionExpression;
46 m_secondInitialConditionExpression =
nullptr;
48 if (m_nameLayout !=
nullptr) {
50 m_nameLayout =
nullptr;
52 if (m_definitionName !=
nullptr) {
53 delete m_definitionName;
54 m_definitionName =
nullptr;
56 if (m_firstInitialConditionName !=
nullptr) {
57 delete m_firstInitialConditionName;
58 m_firstInitialConditionName =
nullptr;
60 if (m_secondInitialConditionName !=
nullptr) {
61 delete m_secondInitialConditionName;
62 m_secondInitialConditionName =
nullptr;
70 const char * contentText = other.
text();
71 const char * firstInitialText = other.m_firstInitialConditionText;
72 const char * secondInitialText = other.m_secondInitialConditionText;
73 Function::operator=(other);
74 setType(other.m_type);
75 setInitialRank(other.m_initialRank);
76 setContent(contentText);
77 setFirstInitialConditionContent(firstInitialText);
78 setSecondInitialConditionContent(secondInitialText);
83 char data[k_dataLengthInBytes/
sizeof(char)] = {};
88 *intAdress = m_initialRank;
89 data[k_dataLengthInBytes-3] = (char)m_type;
90 data[k_dataLengthInBytes-2] = name()!=
nullptr ? name()[0] : 0;
91 data[k_dataLengthInBytes-1] = (char)(isActive() ? 1 : 0);
95 const char * Sequence::firstInitialConditionText() {
96 return m_firstInitialConditionText;
99 const char * Sequence::secondInitialConditionText() {
100 return m_secondInitialConditionText;
107 void Sequence::setType(
Type type) {
108 if (m_type == Type::Explicit) {
118 case Type::SingleRecurrence:
125 case Type::DoubleRecurrence:
127 char ex[12] =
"u(n+1)+u(n)";
134 setFirstInitialConditionContent(
"");
135 setSecondInitialConditionContent(
"");
138 void Sequence::setInitialRank(
int rank) {
139 m_initialRank = rank;
140 if (m_firstInitialConditionName !=
nullptr) {
141 delete m_firstInitialConditionName;
142 m_firstInitialConditionName =
nullptr;
144 if (m_secondInitialConditionName !=
nullptr) {
145 delete m_secondInitialConditionName;
146 m_secondInitialConditionName =
nullptr;
151 if (m_firstInitialConditionExpression ==
nullptr) {
154 return m_firstInitialConditionExpression;
158 if (m_secondInitialConditionExpression ==
nullptr) {
161 return m_secondInitialConditionExpression;
165 if (m_firstInitialConditionLayout ==
nullptr) {
166 Expression * nonSimplifedExpression = Expression::parse(m_firstInitialConditionText);
167 if (nonSimplifedExpression) {
168 m_firstInitialConditionLayout = nonSimplifedExpression->
createLayout(PrintFloat::Mode::Decimal);
169 delete nonSimplifedExpression;
172 return m_firstInitialConditionLayout;
176 if (m_secondInitialConditionLayout ==
nullptr) {
177 Expression * nonSimplifedExpression = Expression::parse(m_secondInitialConditionText);
178 if (nonSimplifedExpression) {
179 m_secondInitialConditionLayout = nonSimplifedExpression->
createLayout(PrintFloat::Mode::Decimal);
180 delete nonSimplifedExpression;
183 return m_secondInitialConditionLayout;
186 void Sequence::setContent(
const char *
c) {
187 Function::setContent(
c);
190 void Sequence::setFirstInitialConditionContent(
const char *
c) {
191 strlcpy(m_firstInitialConditionText,
c,
sizeof(m_firstInitialConditionText));
192 if (m_firstInitialConditionExpression !=
nullptr) {
193 delete m_firstInitialConditionExpression;
194 m_firstInitialConditionExpression =
nullptr;
196 if (m_firstInitialConditionLayout !=
nullptr) {
197 delete m_firstInitialConditionLayout;
198 m_firstInitialConditionLayout =
nullptr;
202 void Sequence::setSecondInitialConditionContent(
const char *
c) {
203 strlcpy(m_secondInitialConditionText,
c,
sizeof(m_secondInitialConditionText));
204 if (m_secondInitialConditionExpression !=
nullptr) {
205 delete m_secondInitialConditionExpression;
206 m_secondInitialConditionExpression =
nullptr;
208 if (m_secondInitialConditionLayout !=
nullptr) {
209 delete m_secondInitialConditionLayout;
210 m_secondInitialConditionLayout =
nullptr;
214 char Sequence::symbol()
const {
218 int Sequence::numberOfElements() {
219 return (
int)m_type + 1;
223 if (m_nameLayout ==
nullptr) {
230 if (m_definitionName ==
nullptr) {
231 if (m_type == Type::Explicit) {
234 if (m_type == Type::SingleRecurrence) {
237 if (m_type == Type::DoubleRecurrence) {
241 return m_definitionName;
245 char buffer[k_initialRankNumberOfDigits+1];
247 if (m_firstInitialConditionName ==
nullptr) {
248 if (m_type == Type::SingleRecurrence) {
251 if (m_type == Type::DoubleRecurrence) {
255 return m_firstInitialConditionName;
259 char buffer[k_initialRankNumberOfDigits+1];
261 if (m_secondInitialConditionName ==
nullptr) {
262 if (m_type == Type::DoubleRecurrence) {
267 return m_secondInitialConditionName;
270 bool Sequence::isDefined() {
273 return strlen(text()) != 0;
274 case Type::SingleRecurrence:
275 return strlen(text()) != 0 &&
strlen(firstInitialConditionText()) != 0;
277 return strlen(text()) != 0 &&
strlen(firstInitialConditionText()) != 0 &&
strlen(secondInitialConditionText()) != 0;
281 bool Sequence::isEmpty() {
284 return Function::isEmpty();
285 case Type::SingleRecurrence:
286 return Function::isEmpty() &&
strlen(m_firstInitialConditionText) == 0;
288 return Function::isEmpty() &&
strlen(m_firstInitialConditionText) == 0 &&
strlen(m_secondInitialConditionText) == 0;
304 if (n < m_initialRank || n < 0) {
326 return expression(sqctx)->template approximateToScalar<T>(ctx);
328 case Type::SingleRecurrence:
330 if (n == m_initialRank) {
331 return firstInitialConditionExpression(sqctx)->template approximateToScalar<T>(*sqctx);
339 return expression(sqctx)->template approximateToScalar<T>(ctx);
343 if (n == m_initialRank) {
344 return firstInitialConditionExpression(sqctx)->template approximateToScalar<T>(*sqctx);
346 if (n == m_initialRank+1) {
347 return secondInitialConditionExpression(sqctx)->template approximateToScalar<T>(*sqctx);
355 return expression(sqctx)->template approximateToScalar<T>(ctx);
360 double Sequence::sumBetweenBounds(
double start,
double end,
Context * context)
const {
368 if (i == i-1.0 || i == i+1.0) {
371 result += evaluateAtAbscissa(i, context);
376 void Sequence::tidy() {
378 if (m_firstInitialConditionLayout !=
nullptr) {
379 delete m_firstInitialConditionLayout;
380 m_firstInitialConditionLayout =
nullptr;
382 if (m_secondInitialConditionLayout !=
nullptr) {
383 delete m_secondInitialConditionLayout;
384 m_secondInitialConditionLayout =
nullptr;
386 if (m_firstInitialConditionExpression !=
nullptr) {
387 delete m_firstInitialConditionExpression;
388 m_firstInitialConditionExpression =
nullptr;
390 if (m_secondInitialConditionExpression !=
nullptr) {
391 delete m_secondInitialConditionExpression;
392 m_secondInitialConditionExpression =
nullptr;
394 if (m_nameLayout !=
nullptr) {
396 m_nameLayout =
nullptr;
398 if (m_definitionName !=
nullptr) {
399 delete m_definitionName;
400 m_definitionName =
nullptr;
402 if (m_firstInitialConditionName !=
nullptr) {
403 delete m_firstInitialConditionName;
404 m_firstInitialConditionName =
nullptr;
406 if (m_secondInitialConditionName !=
nullptr) {
407 delete m_secondInitialConditionName;
408 m_secondInitialConditionName =
nullptr;
412 template double Sequence::templatedApproximateAtAbscissa<double>(double,
SequenceContext*)
const;
413 template float Sequence::templatedApproximateAtAbscissa<float>(float,
SequenceContext*)
const;
414 template double Sequence::approximateToNextRank<double>(int,
SequenceContext*)
const;
415 template float Sequence::approximateToNextRank<float>(int,
SequenceContext*)
const;
int writeTextInBuffer(char *buffer, int bufferSize) const
static constexpr int maxBufferSize()
const char * text() const
size_t strlcpy(char *dst, const char *src, size_t len)
size_t strlen(const char *s)
ExpressionLayout * createLayout(PrintFloat::Mode floatDisplayMode=PrintFloat::Mode::Default, ComplexFormat complexFormat=ComplexFormat::Default) const
bool iterateUntilRank(int n)
static Complex< T > Float(T x)
uint32_t crc32(const uint32_t *data, size_t length)
static constexpr const char * k_sequenceNames[MaxNumberOfSequences]
T valueOfSequenceAtPreviousRank(int sequenceIndex, int rank) const
void setExpressionForSymbolName(const Expression *expression, const Symbol *symbol, Context &context) override
void setValueForSymbol(T value, const Poincare::Symbol *symbol)
static Expression * ParseAndSimplify(const char *text, Context &context, AngleUnit angleUnit=AngleUnit::Default)