[apps] Sequence: enable to defined dependent sequences

This commit is contained in:
Émilie Feral
2017-12-13 17:06:08 +01:00
committed by EmilieNumworks
parent 81e0148325
commit 032cafdb04
13 changed files with 258 additions and 176 deletions

View File

@@ -17,8 +17,9 @@ app_objs += $(addprefix apps/sequence/,\
list/type_parameter_controller.o\
values/interval_parameter_controller.o\
values/values_controller.o\
local_context.o\
cache_context.o\
sequence.o\
sequence_context.o\
sequence_store.o\
sequence_title_cell.o\
)

View File

@@ -55,7 +55,7 @@ void App::Snapshot::tidy() {
App::App(Container * container, Snapshot * snapshot) :
FunctionApp(container, snapshot, &m_inputViewController),
m_nContext(((AppsContainer *)container)->globalContext()),
m_sequenceContext(((AppsContainer *)container)->globalContext(), snapshot->sequenceStore()),
m_listController(&m_listFooter, snapshot->sequenceStore(), &m_listHeader, &m_listFooter),
m_listFooter(&m_listHeader, &m_listController, &m_listController, ButtonRowController::Position::Bottom, ButtonRowController::Style::EmbossedGrey),
m_listHeader(nullptr, &m_listFooter, &m_listController),
@@ -78,10 +78,7 @@ InputViewController * App::inputViewController() {
}
Context * App::localContext() {
if (m_tabViewController.activeTab() == 0) {
return &m_nContext;
}
return TextFieldDelegateApp::localContext();
return &m_sequenceContext;
}
const char * App::XNT() {

View File

@@ -3,7 +3,7 @@
#include <escher.h>
#include <poincare.h>
#include "local_context.h"
#include "sequence_context.h"
#include "sequence_store.h"
#include "graph/graph_controller.h"
#include "graph/curve_view_range.h"
@@ -39,7 +39,7 @@ public:
const char * XNT() override;
private:
App(Container * container, Snapshot * snapshot);
LocalContext<float> m_nContext;
SequenceContext m_sequenceContext;
ListController m_listController;
ButtonRowController m_listFooter;
ButtonRowController m_listHeader;

View File

@@ -1,4 +1,4 @@
#include "local_context.h"
#include "cache_context.h"
#include <cmath>
using namespace Poincare;
@@ -6,7 +6,7 @@ using namespace Poincare;
namespace Sequence {
template<typename T>
LocalContext<T>::LocalContext(Context * parentContext) :
CacheContext<T>::CacheContext(Context * parentContext) :
VariableContext<T>('n', parentContext),
m_values{{Complex<T>::Float(NAN), Complex<T>::Float(NAN)},
{Complex<T>::Float(NAN), Complex<T>::Float(NAN)}}
@@ -14,7 +14,7 @@ LocalContext<T>::LocalContext(Context * parentContext) :
}
template<typename T>
const Expression * LocalContext<T>::expressionForSymbol(const Symbol * symbol) {
const Expression * CacheContext<T>::expressionForSymbol(const Symbol * symbol) {
if (symbol->name() == Symbol::SpecialSymbols::un || symbol->name() == Symbol::SpecialSymbols::un1 ||
symbol->name() == Symbol::SpecialSymbols::vn || symbol->name() == Symbol::SpecialSymbols::vn1) {
return &m_values[nameIndexForSymbol(symbol)][rankIndexForSymbol(symbol)];
@@ -23,16 +23,12 @@ const Expression * LocalContext<T>::expressionForSymbol(const Symbol * symbol) {
}
template<typename T>
void LocalContext<T>::setValueForSequenceRank(T value, const char * sequenceName, int rank) {
for (int i = 0; i < SequenceStore::k_maxNumberOfSequences; i++) {
if (strcmp(sequenceName, SequenceStore::k_sequenceNames[i]) == 0) {
m_values[i][rank] = Complex<T>::Float(value);
}
}
void CacheContext<T>::setValueForSymbol(T value, const Poincare::Symbol * symbol) {
m_values[nameIndexForSymbol(symbol)][rankIndexForSymbol(symbol)] = Complex<T>::Float(value);
}
template<typename T>
int LocalContext<T>::nameIndexForSymbol(const Poincare::Symbol * symbol) {
int CacheContext<T>::nameIndexForSymbol(const Poincare::Symbol * symbol) {
switch (symbol->name()) {
case Symbol::SpecialSymbols::un:
return 0;
@@ -48,7 +44,7 @@ int LocalContext<T>::nameIndexForSymbol(const Poincare::Symbol * symbol) {
}
template<typename T>
int LocalContext<T>::rankIndexForSymbol(const Poincare::Symbol * symbol) {
int CacheContext<T>::rankIndexForSymbol(const Poincare::Symbol * symbol) {
switch (symbol->name()) {
case Symbol::SpecialSymbols::un:
return 0;
@@ -63,7 +59,7 @@ int LocalContext<T>::rankIndexForSymbol(const Poincare::Symbol * symbol) {
}
}
template class LocalContext<float>;
template class LocalContext<double>;
template class CacheContext<float>;
template class CacheContext<double>;
}

View File

@@ -0,0 +1,23 @@
#ifndef SEQUENCE_CACHE_CONTEXT_H
#define SEQUENCE_CACHE_CONTEXT_H
#include <poincare.h>
#include "sequence_context.h"
namespace Sequence {
template<typename T>
class CacheContext : public Poincare::VariableContext<T> {
public:
CacheContext(Poincare::Context * parentContext);
const Poincare::Expression * expressionForSymbol(const Poincare::Symbol * symbol) override;
void setValueForSymbol(T value, const Poincare::Symbol * symbol);
private:
int nameIndexForSymbol(const Poincare::Symbol * symbol);
int rankIndexForSymbol(const Poincare::Symbol * symbol);
Poincare::Complex<T> m_values[MaxNumberOfSequences][MaxRecurrenceDepth];
};
}
#endif

View File

@@ -41,7 +41,7 @@ private:
View * loadView() override;
void unloadView(View * view) override;
static constexpr KDCoordinate k_emptySubRowHeight = 30;
constexpr static int k_maxNumberOfRows = 3*SequenceStore::k_maxNumberOfSequences;
constexpr static int k_maxNumberOfRows = 3*MaxNumberOfSequences;
SequenceStore * m_sequenceStore;
SequenceTitleCell * m_sequenceTitleCells[k_maxNumberOfRows];
Shared::FunctionExpressionCell * m_expressionCells[k_maxNumberOfRows];

View File

@@ -1,24 +0,0 @@
#ifndef SEQUENCE_LOCAL_CONTEXT_H
#define SEQUENCE_LOCAL_CONTEXT_H
#include <poincare.h>
#include "sequence_store.h"
namespace Sequence {
template<typename T>
class LocalContext : public Poincare::VariableContext<T> {
public:
LocalContext(Poincare::Context * parentContext);
const Poincare::Expression * expressionForSymbol(const Poincare::Symbol * symbol) override;
void setValueForSequenceRank(T value, const char * sequenceName, int rank);
private:
constexpr static int k_depth = 2;
int nameIndexForSymbol(const Poincare::Symbol * symbol);
int rankIndexForSymbol(const Poincare::Symbol * symbol);
Poincare::Complex<T> m_values[SequenceStore::k_maxNumberOfSequences][k_depth];
};
}
#endif

View File

@@ -1,5 +1,6 @@
#include "sequence.h"
#include "local_context.h"
#include "sequence_store.h"
#include "cache_context.h"
#include "../../poincare/src/layout/string_layout.h"
#include "../../poincare/src/layout/baseline_relative_layout.h"
#include <string.h>
@@ -22,11 +23,7 @@ Sequence::Sequence(const char * text, KDColor color) :
m_nameLayout(nullptr),
m_definitionName(nullptr),
m_firstInitialConditionName(nullptr),
m_secondInitialConditionName(nullptr),
m_indexBufferFloat{-1, -1},
m_indexBufferDouble{-1, -1},
m_bufferFloat{NAN, NAN},
m_bufferDouble{NAN, NAN}
m_secondInitialConditionName(nullptr)
{
}
@@ -77,7 +74,6 @@ Sequence& Sequence::operator=(const Sequence& other) {
setContent(contentText);
setFirstInitialConditionContent(firstInitialText);
setSecondInitialConditionContent(secondInitialText);
resetBuffer();
return *this;
}
@@ -130,7 +126,7 @@ void Sequence::setType(Type type) {
}
setFirstInitialConditionContent("");
setSecondInitialConditionContent("");
resetBuffer();
//sqctx->resetCache();
}
Poincare::Expression * Sequence::firstInitialConditionExpression(Context * context) const {
@@ -177,7 +173,7 @@ Poincare::ExpressionLayout * Sequence::secondInitialConditionLayout() {
void Sequence::setContent(const char * c) {
Function::setContent(c);
resetBuffer();
//sqctx->resetCache();
}
void Sequence::setFirstInitialConditionContent(const char * c) {
@@ -190,7 +186,7 @@ void Sequence::setFirstInitialConditionContent(const char * c) {
delete m_firstInitialConditionLayout;
m_firstInitialConditionLayout = nullptr;
}
resetBuffer();
//sqctx->resetCache();
}
void Sequence::setSecondInitialConditionContent(const char * c) {
@@ -203,7 +199,7 @@ void Sequence::setSecondInitialConditionContent(const char * c) {
delete m_secondInitialConditionLayout;
m_secondInitialConditionLayout = nullptr;
}
resetBuffer();
//sqctx->resetCache();
}
char Sequence::symbol() const {
@@ -281,71 +277,66 @@ bool Sequence::isEmpty() {
}
template<typename T>
T Sequence::templatedApproximateAtAbscissa(T x, Poincare::Context * context) const {
T Sequence::templatedApproximateAtAbscissa(T x, SequenceContext * sqctx) const {
T n = std::round(x);
int sequenceIndex = name() == SequenceStore::k_sequenceNames[0] ? 0 : 1;
if (sqctx->iterateUntilRank<T>(n)) {
return sqctx->valueOfSequenceAtPreviousRank<T>(sequenceIndex, 0);
}
return NAN;
}
template<typename T>
T Sequence::approximateToNextRank(int n, SequenceContext * sqctx) const {
CacheContext<T> ctx = CacheContext<T>(sqctx);
T un = sqctx->valueOfSequenceAtPreviousRank<T>(0, 0);
T unm1 = sqctx->valueOfSequenceAtPreviousRank<T>(0, 1);
T unm2 = sqctx->valueOfSequenceAtPreviousRank<T>(0, 2);
T vn = sqctx->valueOfSequenceAtPreviousRank<T>(1, 0);
T vnm1 = sqctx->valueOfSequenceAtPreviousRank<T>(1, 1);
T vnm2 = sqctx->valueOfSequenceAtPreviousRank<T>(1, 2);
Poincare::Symbol nSymbol(symbol());
Poincare::Symbol vnSymbol(Symbol::SpecialSymbols::vn);
Poincare::Symbol vn1Symbol(Symbol::SpecialSymbols::vn1);
Poincare::Symbol unSymbol(Symbol::SpecialSymbols::un);
Poincare::Symbol un1Symbol(Symbol::SpecialSymbols::un1);
switch (m_type) {
case Type::Explicite:
if (n < 0) {
return NAN;
}
return Shared::Function::evaluateAtAbscissa(n, context);
{
ctx.setValueForSymbol(un, &unSymbol);
ctx.setValueForSymbol(vn, &vnSymbol);
Poincare::Complex<T> e = Poincare::Complex<T>::Float(n);
ctx.setExpressionForSymbolName(&e, &nSymbol, *sqctx);
return expression(sqctx)->template approximateToScalar<T>(ctx);
}
case Type::SingleRecurrence:
{
if (n < 0 || n > k_maxRecurrentRank) {
return NAN;
}
if (n == 0) {
setBufferIndexValue<T>(0,0);
setBufferValue(firstInitialConditionExpression(context)->approximateToScalar<T>(*context), 0);
return bufferValue<T>(0);
return firstInitialConditionExpression(sqctx)->template approximateToScalar<T>(*sqctx);
}
LocalContext<T> subContext = LocalContext<T>(context);
Poincare::Symbol nSymbol(symbol());
int start = indexBuffer<T>(0) < 0 || indexBuffer<T>(0) > n ? 0 : indexBuffer<T>(0);
T un = indexBuffer<T>(0) < 0 || indexBuffer<T>(0) > n ? firstInitialConditionExpression(context)->approximateToScalar<T>(*context) : bufferValue<T>(0);
for (int i = start; i < n; i++) {
subContext.setValueForSequenceRank(un, name(), 0);
Poincare::Complex<T> e = Poincare::Complex<T>::Float(i);
subContext.setExpressionForSymbolName(&e, &nSymbol, subContext);
un = expression(&subContext)-> template approximateToScalar<T>(subContext);
}
setBufferValue(un, 0);
setBufferIndexValue<T>(n, 0);
return un;
ctx.setValueForSymbol(un, &un1Symbol);
ctx.setValueForSymbol(unm1, &unSymbol);
ctx.setValueForSymbol(vn, &vn1Symbol);
ctx.setValueForSymbol(vnm1, &vnSymbol);
Poincare::Complex<T> e = Poincare::Complex<T>::Float(n-1);
ctx.setExpressionForSymbolName(&e, &nSymbol, *sqctx);
return expression(sqctx)->template approximateToScalar<T>(ctx);
}
default:
{
if (n < 0 || n > k_maxRecurrentRank) {
return NAN;
}
if (n == 0) {
return firstInitialConditionExpression(context)->approximateToScalar<T>(*context);
return firstInitialConditionExpression(sqctx)->template approximateToScalar<T>(*sqctx);
}
if (n == 1) {
setBufferIndexValue<T>(0, 0);
setBufferValue(firstInitialConditionExpression(context)->approximateToScalar<T>(*context), 0);
setBufferIndexValue<T>(1, 1);
setBufferValue(secondInitialConditionExpression(context)->approximateToScalar<T>(*context), 1);
return bufferValue<T>(1);
return secondInitialConditionExpression(sqctx)->template approximateToScalar<T>(*sqctx);
}
LocalContext<T> subContext = LocalContext<T>(context);
Poincare::Symbol nSymbol(symbol());
int start = indexBuffer<T>(0) >= 0 && indexBuffer<T>(0) < n && indexBuffer<T>(1) > 0 && indexBuffer<T>(1) <= n && indexBuffer<T>(0) + 1 == indexBuffer<T>(1) ? indexBuffer<T>(0) : 0;
T un = indexBuffer<T>(0) >= 0 && indexBuffer<T>(0) < n && indexBuffer<T>(1) > 0 && indexBuffer<T>(1) <= n && indexBuffer<T>(0) + 1 == indexBuffer<T>(1) ? bufferValue<T>(0) : firstInitialConditionExpression(context)->approximateToScalar<T>(*context);
T un1 = indexBuffer<T>(0) >= 0 && indexBuffer<T>(0) < n && indexBuffer<T>(1) > 0 && indexBuffer<T>(1) <= n && indexBuffer<T>(0) + 1 == indexBuffer<T>(1) ? bufferValue<T>(1) : secondInitialConditionExpression(context)->approximateToScalar<T>(*context);
for (int i = start; i < n-1; i++) {
subContext.setValueForSequenceRank(un, name(), 0);
subContext.setValueForSequenceRank(un1, name(), 1);
Poincare::Complex<T> e = Poincare::Complex<T>::Float(i);
subContext.setExpressionForSymbolName(&e, &nSymbol, subContext);
un = un1;
un1 = expression(&subContext)->template approximateToScalar<T>(subContext);
}
setBufferValue(un, 0);
setBufferIndexValue<T>(n-1, 0);
setBufferValue(un1, 1);
setBufferIndexValue<T>(n, 1);
return un1;
ctx.setValueForSymbol(unm1, &un1Symbol);
ctx.setValueForSymbol(unm2, &unSymbol);
ctx.setValueForSymbol(vnm1, &vn1Symbol);
ctx.setValueForSymbol(vnm2, &vnSymbol);
Poincare::Complex<T> e = Poincare::Complex<T>::Float(n-2);
ctx.setExpressionForSymbolName(&e, &nSymbol, *sqctx);
return expression(sqctx)->template approximateToScalar<T>(ctx);
}
}
}
@@ -402,11 +393,6 @@ void Sequence::tidy() {
}
}
void Sequence::resetBuffer() const {
m_indexBufferFloat[0] = -1;
m_indexBufferFloat[1] = -1;
m_indexBufferDouble[0] = -1;
m_indexBufferDouble[1] = -1;
}
template double Sequence::approximateToNextRank<double>(int, SequenceContext*) const;
template float Sequence::approximateToNextRank<float>(int, SequenceContext*) const;
}

View File

@@ -2,6 +2,7 @@
#define SEQUENCE_SEQUENCE_H
#include "../shared/function.h"
#include "sequence_context.h"
#include <assert.h>
namespace Sequence {
@@ -39,20 +40,21 @@ public:
bool isDefined() override;
bool isEmpty() override;
float evaluateAtAbscissa(float x, Poincare::Context * context) const override {
return templatedApproximateAtAbscissa(x, context);
return templatedApproximateAtAbscissa(x, static_cast<SequenceContext *>(context));
}
double evaluateAtAbscissa(double x, Poincare::Context * context) const override {
return templatedApproximateAtAbscissa(x, context);
return templatedApproximateAtAbscissa(x, static_cast<SequenceContext *>(context));
}
template<typename T> T approximateToNextRank(int n, SequenceContext * sqctx) const;
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 templatedApproximateAtAbscissa(T x, Poincare::Context * context) const;
template<typename T> T templatedApproximateAtAbscissa(T x, SequenceContext * sqctx) const;
Type m_type;
char m_firstInitialConditionText[TextField::maxBufferSize()];
char m_secondInitialConditionText[TextField::maxBufferSize()];
@@ -64,49 +66,6 @@ private:
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];
}
}
};
}

View File

@@ -0,0 +1,66 @@
#include "sequence_context.h"
#include "sequence_store.h"
#include <cmath>
using namespace Poincare;
namespace Sequence {
template<typename T>
TemplatedSequenceContext<T>::TemplatedSequenceContext() :
m_rank(-1),
m_values{{NAN, NAN, NAN},{NAN, NAN, NAN}}
{
}
template<typename T>
T TemplatedSequenceContext<T>::valueOfSequenceAtPreviousRank(int sequenceIndex, int rank) const {
return m_values[sequenceIndex][rank];
}
template<typename T>
void TemplatedSequenceContext<T>::resetCache() {
m_rank = -1;
}
template<typename T>
bool TemplatedSequenceContext<T>::iterateUntilRank(int n, SequenceStore * sequenceStore, SequenceContext * sqctx) {
if (m_rank > n) {
m_rank = -1;
}
if (n < 0 || n-m_rank > k_maxRecurrentRank) {
return false;
}
while (m_rank++ < n) {
step(sequenceStore, sqctx);
}
m_rank--;
return true;
}
template<typename T>
void TemplatedSequenceContext<T>::step(SequenceStore * sequenceStore, SequenceContext * sqctx) {
/* Shift values */
for (int i = 0; i < MaxNumberOfSequences; i++) {
for (int j = MaxRecurrenceDepth; j > 0; j--) {
m_values[i][j] = m_values[i][j-1];
}
m_values[i][0] = NAN;
}
/* Evaluate new u(n) and v(n) */
Sequence * u = sequenceStore->numberOfFunctions() > 0 ? sequenceStore->functionAtIndex(0) : nullptr;
u = u && u->isDefined() ? u : nullptr;
Sequence * v = sequenceStore->numberOfFunctions() > 1 ? sequenceStore->functionAtIndex(1) : nullptr;
v = v && v->isDefined() ? v : nullptr;
/* TODO: explain */
m_values[0][0] = u ? u->approximateToNextRank<T>(m_rank, sqctx) : NAN;
m_values[1][0] = v ? v->approximateToNextRank<T>(m_rank, sqctx) : NAN;
m_values[0][0] = u ? u->approximateToNextRank<T>(m_rank, sqctx) : NAN;
}
template class TemplatedSequenceContext<float>;
template class TemplatedSequenceContext<double>;
}

View File

@@ -0,0 +1,77 @@
#ifndef SEQUENCE_SEQUENCE_CONTEXT_H
#define SEQUENCE_SEQUENCE_CONTEXT_H
#include <poincare.h>
namespace Sequence {
constexpr static int MaxRecurrenceDepth = 2;
static constexpr int MaxNumberOfSequences = 2;
class SequenceStore;
class SequenceContext;
template<typename T>
class TemplatedSequenceContext {
public:
TemplatedSequenceContext();
T valueOfSequenceAtPreviousRank(int sequenceIndex, int rank) const;
void resetCache();
bool iterateUntilRank(int n, SequenceStore * sequenceStore, SequenceContext * sqctx);
private:
constexpr static int k_maxRecurrentRank = 10000;
/* Cache:
* 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. */
void step(SequenceStore * sequenceStore, SequenceContext * sqctx);
int m_rank;
T m_values[MaxNumberOfSequences][MaxRecurrenceDepth+1];
};
class SequenceContext : public Poincare::Context {
public:
SequenceContext(Poincare::Context * parentContext, SequenceStore * sequenceStore) :
Context(),
m_floatSequenceContext(),
m_doubleSequenceContext(),
m_sequenceStore(sequenceStore),
m_parentContext(parentContext) {}
/* expressionForSymbol & setExpressionForSymbolName directly call the parent
* context respective methods. Indeed, special chars like n, u(n), u(n+1),
* v(n), v(n+1) are taken into accound only when evaluating sequences which
* is done in another context. */
const Poincare::Expression * expressionForSymbol(const Poincare::Symbol * symbol) override {
return m_parentContext->expressionForSymbol(symbol);
}
void setExpressionForSymbolName(const Poincare::Expression * expression, const Poincare::Symbol * symbol, Poincare::Context & context) override {
m_parentContext->setExpressionForSymbolName(expression, symbol, context);
}
template<typename T> T valueOfSequenceAtPreviousRank(int sequenceIndex, int rank) const {
if (sizeof(T) == sizeof(float)) {
return m_floatSequenceContext.valueOfSequenceAtPreviousRank(sequenceIndex, rank);
}
return m_doubleSequenceContext.valueOfSequenceAtPreviousRank(sequenceIndex, rank);
}
void resetCache() {
m_floatSequenceContext.resetCache();
m_doubleSequenceContext.resetCache();
}
template<typename T> bool iterateUntilRank(int n) {
if (sizeof(T) == sizeof(float)) {
return m_floatSequenceContext.iterateUntilRank(n, m_sequenceStore, this);
}
return m_doubleSequenceContext.iterateUntilRank(n, m_sequenceStore, this);
}
private:
TemplatedSequenceContext<float> m_floatSequenceContext;
TemplatedSequenceContext<double> m_doubleSequenceContext;
SequenceStore * m_sequenceStore;
Poincare::Context * m_parentContext;
};
}
#endif

View File

@@ -7,14 +7,14 @@ extern "C" {
namespace Sequence {
constexpr KDColor SequenceStore::k_defaultColors[k_maxNumberOfSequences];
constexpr const char * SequenceStore::k_sequenceNames[k_maxNumberOfSequences];
constexpr KDColor SequenceStore::k_defaultColors[MaxNumberOfSequences];
constexpr const char * SequenceStore::k_sequenceNames[MaxNumberOfSequences];
uint32_t SequenceStore::storeChecksum() {
size_t dataLengthInBytes = k_maxNumberOfSequences*sizeof(uint32_t);
size_t dataLengthInBytes = MaxNumberOfSequences*sizeof(uint32_t);
assert((dataLengthInBytes & 0x3) == 0); // Assert that dataLengthInBytes is a multiple of 4
uint32_t checksums[k_maxNumberOfSequences];
for (int i = 0; i < k_maxNumberOfSequences; i++) {
uint32_t checksums[MaxNumberOfSequences];
for (int i = 0; i < MaxNumberOfSequences; i++) {
checksums[i] = m_sequences[i].checksum();
}
return Ion::crc32((uint32_t *)checksums, dataLengthInBytes/sizeof(uint32_t));
@@ -34,7 +34,7 @@ Sequence * SequenceStore::definedFunctionAtIndex(int i) {
}
Sequence * SequenceStore::addEmptyFunction() {
assert(m_numberOfFunctions < k_maxNumberOfSequences);
assert(m_numberOfFunctions < MaxNumberOfSequences);
const char * name = firstAvailableName();
KDColor color = firstAvailableColor();
Sequence addedSequence(name, color);
@@ -56,10 +56,11 @@ void SequenceStore::removeFunction(Shared::Function * f) {
}
Sequence emptySequence("", KDColorBlack);
m_sequences[m_numberOfFunctions] = emptySequence;
//sqctx->resetCache();
}
int SequenceStore::maxNumberOfFunctions() {
return k_maxNumberOfSequences;
return MaxNumberOfSequences;
}
char SequenceStore::symbol() const {
@@ -67,7 +68,7 @@ char SequenceStore::symbol() const {
}
const char * SequenceStore::firstAvailableName() {
for (int k = 0; k < k_maxNumberOfSequences; k++) {
for (int k = 0; k < MaxNumberOfSequences; k++) {
int j = 0;
while (j < m_numberOfFunctions) {
if (m_sequences[j].name() == k_sequenceNames[k]) {
@@ -83,7 +84,7 @@ const char * SequenceStore::firstAvailableName() {
}
const KDColor SequenceStore::firstAvailableColor() {
for (int k = 0; k < k_maxNumberOfSequences; k++) {
for (int k = 0; k < MaxNumberOfSequences; k++) {
int j = 0;
while (j < m_numberOfFunctions) {
if (m_sequences[j].color() == k_defaultColors[k]) {
@@ -104,6 +105,7 @@ void SequenceStore::removeAll() {
m_sequences[i] = emptySequence;
}
m_numberOfFunctions = 0;
//sqctx->resetCache();
}
}

View File

@@ -1,8 +1,8 @@
#ifndef SEQUENCE_SEQUENCE_STORE_H
#define SEQUENCE_SEQUENCE_STORE_H
#include "sequence.h"
#include "../shared/function_store.h"
#include "sequence.h"
#include <stdint.h>
#include <escher.h>
@@ -21,16 +21,15 @@ public:
const char * firstAvailableName() override;
char symbol() const override;
void removeAll() override;
static constexpr int k_maxNumberOfSequences = 2;
static constexpr const char * k_sequenceNames[k_maxNumberOfSequences] = {
static constexpr const char * k_sequenceNames[MaxNumberOfSequences] = {
"u", "v"//, "w"
};
private:
const KDColor firstAvailableColor() override;
static constexpr KDColor k_defaultColors[k_maxNumberOfSequences] = {
static constexpr KDColor k_defaultColors[MaxNumberOfSequences] = {
Palette::Red, Palette::Blue//, Palette::YellowDark
};
Sequence m_sequences[k_maxNumberOfSequences];
Sequence m_sequences[MaxNumberOfSequences];
};
}