mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
Merge branch 'cas_with_python' into python_console
Change-Id: I06e3e07b9fd8d52818d90110ed7517777b35b9f1
This commit is contained in:
@@ -54,4 +54,34 @@ Context * App::localContext() {
|
||||
return &m_localContext;
|
||||
}
|
||||
|
||||
bool App::textFieldDidReceiveEvent(::TextField * textField, Ion::Events::Event event) {
|
||||
if ((event == Ion::Events::Var || event == Ion::Events::XNT) && TextFieldDelegateApp::textFieldDidReceiveEvent(textField, event)) {
|
||||
return true;
|
||||
}
|
||||
/* Here, we check that the expression entered by the user can be printed with
|
||||
* less than k_printedExpressionLength characters. Otherwise, we prevent the
|
||||
* user from adding this expression to the calculation store. */
|
||||
if (textField->isEditing() && textField->textFieldShouldFinishEditing(event)) {
|
||||
Expression * exp = Expression::parse(textField->text());
|
||||
if (exp == nullptr) {
|
||||
textField->app()->displayWarning(I18n::Message::SyntaxError);
|
||||
return true;
|
||||
}
|
||||
char buffer[Calculation::k_printedExpressionSize];
|
||||
int length = exp->writeTextInBuffer(buffer, sizeof(buffer));
|
||||
delete exp;
|
||||
/* if the buffer is totally full, it is VERY likely that writeTextInBuffer
|
||||
* escaped before printing utterly the expression. */
|
||||
if (length >= Calculation::k_printedExpressionSize-1) {
|
||||
displayWarning(I18n::Message::SyntaxError);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const char * App::XNT() {
|
||||
return "x";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@ public:
|
||||
CalculationStore m_calculationStore;
|
||||
};
|
||||
Poincare::Context * localContext() override;
|
||||
bool textFieldDidReceiveEvent(::TextField * textField, Ion::Events::Event event) override;
|
||||
const char * XNT() override;
|
||||
private:
|
||||
App(Container * container, Snapshot * snapshot);
|
||||
LocalContext m_localContext;
|
||||
|
||||
@@ -66,11 +66,13 @@ void Calculation::reset() {
|
||||
void Calculation::setContent(const char * c, Context * context) {
|
||||
reset();
|
||||
m_input = Expression::parse(c);
|
||||
/* We do not store directly the text enter by the user but its serialization
|
||||
* to be able to compare it to the exact ouput text. */
|
||||
m_input->writeTextInBuffer(m_inputText, sizeof(m_inputText));
|
||||
m_exactOutput = input()->clone();
|
||||
Expression::Simplify(&m_exactOutput, *context);
|
||||
m_exactOutput->writeTextInBuffer(m_exactOutputText, sizeof(m_exactOutputText));
|
||||
m_approximateOutput = m_exactOutput->evaluate<double>(*context);
|
||||
m_approximateOutput = m_exactOutput->approximate<double>(*context);
|
||||
m_approximateOutput->writeTextInBuffer(m_approximateOutputText, sizeof(m_approximateOutputText));
|
||||
}
|
||||
|
||||
@@ -189,7 +191,7 @@ Expression * Calculation::approximateOutput(Context * context) {
|
||||
* call 'evaluate'. */
|
||||
Expression * exp = Expression::parse(m_approximateOutputText);
|
||||
if (exp != nullptr) {
|
||||
m_approximateOutput = exp->evaluate<double>(*context);
|
||||
m_approximateOutput = exp->approximate<double>(*context);
|
||||
delete exp;
|
||||
} else {
|
||||
m_approximateOutput = new Complex<double>(Complex<double>::Float(NAN));
|
||||
@@ -213,7 +215,7 @@ bool Calculation::shouldApproximateOutput() {
|
||||
return true;
|
||||
}
|
||||
return input()->recursivelyMatches([](const Expression * e) {
|
||||
return e->type() == Expression::Type::Decimal || Expression::IsMatrix(e);
|
||||
return e->type() == Expression::Type::Decimal || Expression::IsMatrix(e) || (e->type() == Expression::Type::Symbol && static_cast<const Symbol *>(e)->isScalarSymbol());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -31,11 +31,15 @@ public:
|
||||
bool isEmpty();
|
||||
void tidy();
|
||||
bool shouldApproximateOutput();
|
||||
constexpr static int k_printedExpressionSize = 2*::TextField::maxBufferSize();
|
||||
private:
|
||||
Poincare::Expression * exactOutput(Poincare::Context * context);
|
||||
char m_inputText[::TextField::maxBufferSize()];
|
||||
char m_exactOutputText[2*::TextField::maxBufferSize()];
|
||||
char m_approximateOutputText[2*::TextField::maxBufferSize()];
|
||||
/* Buffers holding text expressions have to be longer than the text written
|
||||
* by user (of maximum length TextField::maxBufferSize()) because when we
|
||||
* print an expression we add omitted signs (multiplications, parenthesis...) */
|
||||
char m_inputText[k_printedExpressionSize];
|
||||
char m_exactOutputText[k_printedExpressionSize];
|
||||
char m_approximateOutputText[k_printedExpressionSize];
|
||||
Poincare::Expression * m_input;
|
||||
Poincare::ExpressionLayout * m_inputLayout;
|
||||
Poincare::Expression * m_exactOutput;
|
||||
|
||||
@@ -160,9 +160,14 @@ KDCoordinate HistoryController::rowHeight(int j) {
|
||||
Calculation * calculation = m_calculationStore->calculationAtIndex(j);
|
||||
KDCoordinate inputHeight = calculation->inputLayout()->size().height();
|
||||
App * calculationApp = (App *)app();
|
||||
KDCoordinate exactOutputHeight = calculation->exactOutputLayout(calculationApp->localContext())->size().height();
|
||||
KDCoordinate approximateOutputHeight = calculation->approximateOutputLayout(calculationApp->localContext())->size().height();
|
||||
KDCoordinate outputHeight = calculation->shouldApproximateOutput() || approximateOutputHeight > exactOutputHeight ? approximateOutputHeight : exactOutputHeight;
|
||||
Poincare::ExpressionLayout * approximateLayout = calculation->approximateOutputLayout(calculationApp->localContext());
|
||||
KDCoordinate approximateOutputHeight = approximateLayout->size().height();
|
||||
if (calculation->shouldApproximateOutput()) {
|
||||
return inputHeight + approximateOutputHeight + 3*HistoryViewCell::k_digitVerticalMargin;
|
||||
}
|
||||
Poincare::ExpressionLayout * exactLayout = calculation->exactOutputLayout(calculationApp->localContext());
|
||||
KDCoordinate exactOutputHeight = exactLayout->size().height();
|
||||
KDCoordinate outputHeight = max(exactLayout->baseline(), approximateLayout->baseline()) + max(exactOutputHeight-exactLayout->baseline(), approximateOutputHeight-approximateLayout->baseline());
|
||||
return inputHeight + outputHeight + 3*HistoryViewCell::k_digitVerticalMargin;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Calculation {
|
||||
OutputExpressionsView::OutputExpressionsView(Responder * parentResponder) :
|
||||
Responder(parentResponder),
|
||||
m_approximateExpressionView(),
|
||||
m_approximateSign(KDText::FontSize::Large, I18n::Message::AlmostEqual, 0.5f, 0.5f, Palette::GreyDark),
|
||||
m_approximateSign(KDText::FontSize::Large, I18n::Message::AlmostEqual, 0.5f, 0.5f, Palette::GreyVeryDark),
|
||||
m_exactExpressionView(),
|
||||
m_selectedSubviewType(OutputExpressionsView::SubviewType::ExactOutput)
|
||||
{
|
||||
@@ -46,7 +46,7 @@ void OutputExpressionsView::reloadCell() {
|
||||
if (numberOfSubviews() == 1) {
|
||||
m_approximateExpressionView.setTextColor(KDColorBlack);
|
||||
} else {
|
||||
m_approximateExpressionView.setTextColor(Palette::GreyDark);
|
||||
m_approximateExpressionView.setTextColor(Palette::GreyVeryDark);
|
||||
}
|
||||
layoutSubviews();
|
||||
}
|
||||
@@ -57,8 +57,11 @@ KDSize OutputExpressionsView::minimalSizeForOptimalDisplay() const {
|
||||
return approximateExpressionSize;
|
||||
}
|
||||
KDSize exactExpressionSize = m_exactExpressionView.minimalSizeForOptimalDisplay();
|
||||
KDCoordinate exactBaseline = m_exactExpressionView.expressionLayout()->baseline();
|
||||
KDCoordinate approximateBaseline = m_approximateExpressionView.expressionLayout()->baseline();
|
||||
KDCoordinate height = max(exactBaseline, approximateBaseline) + max(exactExpressionSize.height()-exactBaseline, approximateExpressionSize.height()-approximateBaseline);
|
||||
KDSize approximateSignSize = m_approximateSign.minimalSizeForOptimalDisplay();
|
||||
return KDSize(exactExpressionSize.width()+approximateSignSize.width()+approximateExpressionSize.width()+2*k_digitHorizontalMargin, exactExpressionSize.height() > approximateExpressionSize.height() ? exactExpressionSize.height() : approximateExpressionSize.height());
|
||||
return KDSize(exactExpressionSize.width()+approximateSignSize.width()+approximateExpressionSize.width()+2*k_digitHorizontalMargin, height);
|
||||
}
|
||||
|
||||
void OutputExpressionsView::didBecomeFirstResponder() {
|
||||
@@ -115,11 +118,14 @@ void OutputExpressionsView::layoutSubviews() {
|
||||
m_approximateExpressionView.setFrame(KDRect(0, 0, approximateExpressionSize.width(), height));
|
||||
return;
|
||||
}
|
||||
KDCoordinate exactBaseline = m_exactExpressionView.expressionLayout()->baseline();
|
||||
KDCoordinate approximateBaseline = m_approximateExpressionView.expressionLayout()->baseline();
|
||||
KDCoordinate baseline = max(exactBaseline, approximateBaseline);
|
||||
KDSize exactExpressionSize = m_exactExpressionView.minimalSizeForOptimalDisplay();
|
||||
m_exactExpressionView.setFrame(KDRect(0, 0, exactExpressionSize.width(), height));
|
||||
KDSize approximateSignSize = m_approximateSign.minimalSizeForOptimalDisplay();
|
||||
m_approximateSign.setFrame(KDRect(k_digitHorizontalMargin+exactExpressionSize.width(), 0, approximateSignSize.width(), height));
|
||||
m_approximateExpressionView.setFrame(KDRect(2*k_digitHorizontalMargin+exactExpressionSize.width()+approximateSignSize.width(), 0, approximateExpressionSize.width(), height));
|
||||
m_exactExpressionView.setFrame(KDRect(0, baseline-exactBaseline, exactExpressionSize));
|
||||
m_approximateExpressionView.setFrame(KDRect(2*k_digitHorizontalMargin+exactExpressionSize.width()+approximateSignSize.width(), baseline-approximateBaseline, approximateExpressionSize));
|
||||
m_approximateSign.setFrame(KDRect(k_digitHorizontalMargin+exactExpressionSize.width(), baseline-approximateSignSize.height()/2, approximateSignSize));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,9 +18,12 @@ void CartesianFunction::setDisplayDerivative(bool display) {
|
||||
|
||||
double CartesianFunction::approximateDerivative(double x, Poincare::Context * context) const {
|
||||
Poincare::Complex<double> abscissa = Poincare::Complex<double>::Float(x);
|
||||
Poincare::Expression * args[2] = {expression(), &abscissa};
|
||||
Poincare::Expression * args[2] = {expression(context), &abscissa};
|
||||
Poincare::Derivative derivative(args, true);
|
||||
return derivative.approximate<double>(*context);
|
||||
/* TODO: when we will simplify derivative, we might want to simplify the
|
||||
* derivative here. However, we might want to do it once for all x (to avoid
|
||||
* lagging in the derivative table. */
|
||||
return derivative.approximateToScalar<double>(*context);
|
||||
}
|
||||
|
||||
char CartesianFunction::symbol() const {
|
||||
|
||||
@@ -218,7 +218,7 @@ bool CalculationController::textFieldShouldFinishEditing(TextField * textField,
|
||||
bool CalculationController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) {
|
||||
App * probaApp = (App *)app();
|
||||
Context * globalContext = probaApp->container()->globalContext();
|
||||
double floatBody = Expression::approximate<double>(text, *globalContext);
|
||||
double floatBody = Expression::approximateToScalar<double>(text, *globalContext);
|
||||
if (std::isnan(floatBody) || std::isinf(floatBody)) {
|
||||
app()->displayWarning(I18n::Message::UndefinedValue);
|
||||
return false;
|
||||
|
||||
@@ -102,7 +102,7 @@ double BinomialLaw::rightIntegralInverseForProbability(double * probability) {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T BinomialLaw::templatedEvaluateAtAbscissa(T x) const {
|
||||
T BinomialLaw::templatedApproximateAtAbscissa(T x) const {
|
||||
if (m_parameter1 == 0) {
|
||||
if (m_parameter2 == 0 || m_parameter2 == 1) {
|
||||
return NAN;
|
||||
@@ -134,5 +134,5 @@ T BinomialLaw::templatedEvaluateAtAbscissa(T x) const {
|
||||
|
||||
}
|
||||
|
||||
template float Probability::BinomialLaw::templatedEvaluateAtAbscissa(float x) const;
|
||||
template double Probability::BinomialLaw::templatedEvaluateAtAbscissa(double x) const;
|
||||
template float Probability::BinomialLaw::templatedApproximateAtAbscissa(float x) const;
|
||||
template double Probability::BinomialLaw::templatedApproximateAtAbscissa(double x) const;
|
||||
|
||||
@@ -18,16 +18,16 @@ public:
|
||||
I18n::Message parameterNameAtIndex(int index) override;
|
||||
I18n::Message parameterDefinitionAtIndex(int index) override;
|
||||
float evaluateAtAbscissa(float x) const override {
|
||||
return templatedEvaluateAtAbscissa(x);
|
||||
return templatedApproximateAtAbscissa(x);
|
||||
}
|
||||
bool authorizedValueAtIndex(float x, int index) const override;
|
||||
double cumulativeDistributiveInverseForProbability(double * probability) override;
|
||||
double rightIntegralInverseForProbability(double * probability) override;
|
||||
protected:
|
||||
double evaluateAtDiscreteAbscissa(int k) const override {
|
||||
return templatedEvaluateAtAbscissa((double)k);
|
||||
return templatedApproximateAtAbscissa((double)k);
|
||||
}
|
||||
template<typename T> T templatedEvaluateAtAbscissa(T x) const;
|
||||
template<typename T> T templatedApproximateAtAbscissa(T x) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ bool PoissonLaw::authorizedValueAtIndex(float x, int index) const {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T PoissonLaw::templatedEvaluateAtAbscissa(T x) const {
|
||||
T PoissonLaw::templatedApproximateAtAbscissa(T x) const {
|
||||
if (x < 0) {
|
||||
return NAN;
|
||||
}
|
||||
@@ -73,5 +73,5 @@ T PoissonLaw::templatedEvaluateAtAbscissa(T x) const {
|
||||
|
||||
}
|
||||
|
||||
template float Probability::PoissonLaw::templatedEvaluateAtAbscissa(float x) const;
|
||||
template double Probability::PoissonLaw::templatedEvaluateAtAbscissa(double x) const;
|
||||
template float Probability::PoissonLaw::templatedApproximateAtAbscissa(float x) const;
|
||||
template double Probability::PoissonLaw::templatedApproximateAtAbscissa(double x) const;
|
||||
|
||||
@@ -18,14 +18,14 @@ public:
|
||||
I18n::Message parameterNameAtIndex(int index) override;
|
||||
I18n::Message parameterDefinitionAtIndex(int index) override;
|
||||
float evaluateAtAbscissa(float x) const override {
|
||||
return templatedEvaluateAtAbscissa(x);
|
||||
return templatedApproximateAtAbscissa(x);
|
||||
}
|
||||
bool authorizedValueAtIndex(float x, int index) const override;
|
||||
private:
|
||||
double evaluateAtDiscreteAbscissa(int k) const override {
|
||||
return templatedEvaluateAtAbscissa((double)k);
|
||||
return templatedApproximateAtAbscissa((double)k);
|
||||
}
|
||||
template<typename T> T templatedEvaluateAtAbscissa(T x) const;
|
||||
template<typename T> T templatedApproximateAtAbscissa(T x) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -133,30 +133,44 @@ void Sequence::setType(Type type) {
|
||||
resetBuffer();
|
||||
}
|
||||
|
||||
Poincare::Expression * Sequence::firstInitialConditionExpression() const {
|
||||
Poincare::Expression * Sequence::firstInitialConditionExpression(Context * context) const {
|
||||
if (m_firstInitialConditionExpression == nullptr) {
|
||||
m_firstInitialConditionExpression = Poincare::Expression::parse(m_firstInitialConditionText);
|
||||
if (m_firstInitialConditionExpression) {
|
||||
Expression::Simplify(&m_firstInitialConditionExpression, *context);
|
||||
}
|
||||
}
|
||||
return m_firstInitialConditionExpression;
|
||||
}
|
||||
|
||||
Poincare::Expression * Sequence::secondInitialConditionExpression() const {
|
||||
Poincare::Expression * Sequence::secondInitialConditionExpression(Context * context) const {
|
||||
if (m_secondInitialConditionExpression == nullptr) {
|
||||
m_secondInitialConditionExpression = Poincare::Expression::parse(m_secondInitialConditionText);
|
||||
if (m_secondInitialConditionExpression) {
|
||||
Expression::Simplify(&m_secondInitialConditionExpression, *context);
|
||||
}
|
||||
}
|
||||
return m_secondInitialConditionExpression;
|
||||
}
|
||||
|
||||
Poincare::ExpressionLayout * Sequence::firstInitialConditionLayout() {
|
||||
if (m_firstInitialConditionLayout == nullptr && firstInitialConditionExpression() != nullptr) {
|
||||
m_firstInitialConditionLayout = firstInitialConditionExpression()->createLayout(Expression::FloatDisplayMode::Decimal);
|
||||
if (m_firstInitialConditionLayout == nullptr) {
|
||||
Expression * nonSimplifedExpression = Expression::parse(m_firstInitialConditionText);
|
||||
if (nonSimplifedExpression) {
|
||||
m_firstInitialConditionLayout = nonSimplifedExpression->createLayout(Expression::FloatDisplayMode::Decimal);
|
||||
delete nonSimplifedExpression;
|
||||
}
|
||||
}
|
||||
return m_firstInitialConditionLayout;
|
||||
}
|
||||
|
||||
Poincare::ExpressionLayout * Sequence::secondInitialConditionLayout() {
|
||||
if (m_secondInitialConditionLayout == nullptr && secondInitialConditionExpression()) {
|
||||
m_secondInitialConditionLayout = secondInitialConditionExpression()->createLayout(Expression::FloatDisplayMode::Decimal);
|
||||
if (m_secondInitialConditionLayout == nullptr) {
|
||||
Expression * nonSimplifedExpression = Expression::parse(m_secondInitialConditionText);
|
||||
if (nonSimplifedExpression) {
|
||||
m_secondInitialConditionLayout = nonSimplifedExpression->createLayout(Expression::FloatDisplayMode::Decimal);
|
||||
delete nonSimplifedExpression;
|
||||
}
|
||||
}
|
||||
return m_secondInitialConditionLayout;
|
||||
}
|
||||
@@ -267,7 +281,7 @@ bool Sequence::isEmpty() {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T Sequence::templatedEvaluateAtAbscissa(T x, Poincare::Context * context) const {
|
||||
T Sequence::templatedApproximateAtAbscissa(T x, Poincare::Context * context) const {
|
||||
T n = std::round(x);
|
||||
switch (m_type) {
|
||||
case Type::Explicite:
|
||||
@@ -282,18 +296,18 @@ T Sequence::templatedEvaluateAtAbscissa(T x, Poincare::Context * context) const
|
||||
}
|
||||
if (n == 0) {
|
||||
setBufferIndexValue<T>(0,0);
|
||||
setBufferValue(firstInitialConditionExpression()->approximate<T>(*context), 0);
|
||||
setBufferValue(firstInitialConditionExpression(context)->approximateToScalar<T>(*context), 0);
|
||||
return bufferValue<T>(0);
|
||||
}
|
||||
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()->approximate<T>(*context) : bufferValue<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()->approximate<T>(subContext);
|
||||
un = expression(&subContext)-> template approximateToScalar<T>(subContext);
|
||||
}
|
||||
setBufferValue(un, 0);
|
||||
setBufferIndexValue<T>(n, 0);
|
||||
@@ -305,27 +319,27 @@ T Sequence::templatedEvaluateAtAbscissa(T x, Poincare::Context * context) const
|
||||
return NAN;
|
||||
}
|
||||
if (n == 0) {
|
||||
return firstInitialConditionExpression()->approximate<T>(*context);
|
||||
return firstInitialConditionExpression(context)->approximateToScalar<T>(*context);
|
||||
}
|
||||
if (n == 1) {
|
||||
setBufferIndexValue<T>(0, 0);
|
||||
setBufferValue(firstInitialConditionExpression()->approximate<T>(*context), 0);
|
||||
setBufferValue(firstInitialConditionExpression(context)->approximateToScalar<T>(*context), 0);
|
||||
setBufferIndexValue<T>(1, 1);
|
||||
setBufferValue(secondInitialConditionExpression()->approximate<T>(*context), 1);
|
||||
setBufferValue(secondInitialConditionExpression(context)->approximateToScalar<T>(*context), 1);
|
||||
return bufferValue<T>(1);
|
||||
}
|
||||
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()->approximate<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()->approximate<T>(*context);
|
||||
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()->approximate<T>(subContext);
|
||||
un1 = expression(&subContext)->template approximateToScalar<T>(subContext);
|
||||
}
|
||||
setBufferValue(un, 0);
|
||||
setBufferIndexValue<T>(n-1, 0);
|
||||
|
||||
@@ -24,8 +24,8 @@ public:
|
||||
void setType(Type type);
|
||||
const char * firstInitialConditionText();
|
||||
const char * secondInitialConditionText();
|
||||
Poincare::Expression * firstInitialConditionExpression() const;
|
||||
Poincare::Expression * secondInitialConditionExpression() const;
|
||||
Poincare::Expression * firstInitialConditionExpression(Poincare::Context * context) const;
|
||||
Poincare::Expression * secondInitialConditionExpression(Poincare::Context * context) const;
|
||||
Poincare::ExpressionLayout * firstInitialConditionLayout();
|
||||
Poincare::ExpressionLayout * secondInitialConditionLayout();
|
||||
void setContent(const char * c) override;
|
||||
@@ -39,10 +39,10 @@ public:
|
||||
bool isDefined() override;
|
||||
bool isEmpty() override;
|
||||
float evaluateAtAbscissa(float x, Poincare::Context * context) const override {
|
||||
return templatedEvaluateAtAbscissa(x, context);
|
||||
return templatedApproximateAtAbscissa(x, context);
|
||||
}
|
||||
double evaluateAtAbscissa(double x, Poincare::Context * context) const override {
|
||||
return templatedEvaluateAtAbscissa(x, context);
|
||||
return templatedApproximateAtAbscissa(x, context);
|
||||
}
|
||||
double sumOfTermsBetweenAbscissa(double start, double end, Poincare::Context * context);
|
||||
void tidy() override;
|
||||
@@ -52,7 +52,7 @@ private:
|
||||
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;
|
||||
template<typename T> T templatedApproximateAtAbscissa(T x, Poincare::Context * context) const;
|
||||
Type m_type;
|
||||
char m_firstInitialConditionText[TextField::maxBufferSize()];
|
||||
char m_secondInitialConditionText[TextField::maxBufferSize()];
|
||||
|
||||
@@ -26,7 +26,7 @@ App::Descriptor * App::Snapshot::descriptor() {
|
||||
}
|
||||
|
||||
App::App(Container * container, Snapshot * snapshot) :
|
||||
::App(container, snapshot, &m_stackViewController, I18n::Message::Warning),
|
||||
Shared::TextFieldDelegateApp(container, snapshot, &m_stackViewController),
|
||||
m_mainController(&m_stackViewController),
|
||||
m_stackViewController(&m_modalViewController, &m_mainController)
|
||||
{
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#ifndef SETTINGS_APP_H
|
||||
#define SETTINGS_APP_H
|
||||
|
||||
#include <escher.h>
|
||||
#include "main_controller.h"
|
||||
#include "../shared/text_field_delegate_app.h"
|
||||
|
||||
namespace Settings {
|
||||
|
||||
class App : public ::App {
|
||||
class App : public Shared::TextFieldDelegateApp {
|
||||
public:
|
||||
class Descriptor : public ::App::Descriptor {
|
||||
public:
|
||||
|
||||
@@ -17,6 +17,7 @@ Degres = "Grad "
|
||||
Radian = "Bogenmass "
|
||||
Auto = "Auto "
|
||||
Scientific = "Wissenschaftlich "
|
||||
SignificantFigures = "Signifikante Stellen "
|
||||
Deg = "gra"
|
||||
Rad = "rad"
|
||||
Sci = "sci/"
|
||||
|
||||
@@ -17,6 +17,7 @@ Degres = "Degrees "
|
||||
Radian = "Radians "
|
||||
Auto = "Auto "
|
||||
Scientific = "Scientific "
|
||||
SignificantFigures = "Significant figures "
|
||||
Deg = "deg"
|
||||
Rad = "rad"
|
||||
Sci = "sci/"
|
||||
|
||||
@@ -17,6 +17,7 @@ Degres = "Grados "
|
||||
Radian = "Radianes "
|
||||
Auto = "Auto "
|
||||
Scientific = "Cientifico "
|
||||
SignificantFigures = "Cifras significativas "
|
||||
Deg = "gra"
|
||||
Rad = "rad"
|
||||
Sci = "sci/"
|
||||
|
||||
@@ -17,6 +17,7 @@ Degres = "Degres "
|
||||
Radian = "Radians "
|
||||
Auto = "Auto "
|
||||
Scientific = "Scientifique "
|
||||
SignificantFigures = "Chiffres significatifs "
|
||||
Deg = "deg"
|
||||
Rad = "rad"
|
||||
Sci = "sci/"
|
||||
|
||||
@@ -17,6 +17,7 @@ Degres = "Graus "
|
||||
Radian = "Radianos "
|
||||
Auto = "Auto "
|
||||
Scientific = "Cientifico "
|
||||
SignificantFigures = "Algarismo significativo "
|
||||
Deg = "gra"
|
||||
Rad = "rad"
|
||||
Sci = "sci/"
|
||||
|
||||
@@ -11,7 +11,7 @@ using namespace Poincare;
|
||||
namespace Settings {
|
||||
|
||||
const SettingsMessageTree angleChildren[2] = {SettingsMessageTree(I18n::Message::Degres), SettingsMessageTree(I18n::Message::Radian)};
|
||||
const SettingsMessageTree FloatDisplayModeChildren[2] = {SettingsMessageTree(I18n::Message::Auto), SettingsMessageTree(I18n::Message::Scientific)};
|
||||
const SettingsMessageTree FloatDisplayModeChildren[3] = {SettingsMessageTree(I18n::Message::Auto), SettingsMessageTree(I18n::Message::Scientific), SettingsMessageTree(I18n::Message::SignificantFigures)};
|
||||
const SettingsMessageTree complexFormatChildren[2] = {SettingsMessageTree(I18n::Message::Default), SettingsMessageTree(I18n::Message::Default)};
|
||||
const SettingsMessageTree examChildren[1] = {SettingsMessageTree(I18n::Message::ActivateExamMode)};
|
||||
const SettingsMessageTree aboutChildren[3] = {SettingsMessageTree(I18n::Message::SoftwareVersion), SettingsMessageTree(I18n::Message::SerialNumber), SettingsMessageTree(I18n::Message::FccId)};
|
||||
@@ -21,7 +21,7 @@ const SettingsMessageTree menu[8] =
|
||||
#else
|
||||
const SettingsMessageTree menu[7] =
|
||||
#endif
|
||||
{SettingsMessageTree(I18n::Message::AngleUnit, angleChildren, 2), SettingsMessageTree(I18n::Message::DisplayMode, FloatDisplayModeChildren, 2), SettingsMessageTree(I18n::Message::ComplexFormat, complexFormatChildren, 2),
|
||||
{SettingsMessageTree(I18n::Message::AngleUnit, angleChildren, 2), SettingsMessageTree(I18n::Message::DisplayMode, FloatDisplayModeChildren, 3), SettingsMessageTree(I18n::Message::ComplexFormat, complexFormatChildren, 2),
|
||||
SettingsMessageTree(I18n::Message::Brightness), SettingsMessageTree(I18n::Message::Language), SettingsMessageTree(I18n::Message::ExamMode, examChildren, 1),
|
||||
#if OS_WITH_SOFTWARE_UPDATE_PROMPT
|
||||
SettingsMessageTree(I18n::Message::UpdatePopUp),
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "../../poincare/src/layout/baseline_relative_layout.h"
|
||||
#include "../../poincare/src/layout/string_layout.h"
|
||||
#include <assert.h>
|
||||
#include <cmath>
|
||||
|
||||
using namespace Poincare;
|
||||
|
||||
@@ -11,8 +12,9 @@ namespace Settings {
|
||||
|
||||
SubController::SubController(Responder * parentResponder) :
|
||||
ViewController(parentResponder),
|
||||
m_editableCell(&m_selectableTableView, this, m_draftTextBuffer),
|
||||
m_selectableTableView(this, this, 0, 1, k_topBottomMargin, Metric::CommonRightMargin,
|
||||
k_topBottomMargin, Metric::CommonLeftMargin, this),
|
||||
k_topBottomMargin, Metric::CommonLeftMargin, this, this),
|
||||
m_messageTreeModel(nullptr)
|
||||
{
|
||||
for (int i = 0; i < k_totalNumberOfCell; i++) {
|
||||
@@ -28,6 +30,8 @@ SubController::SubController(Responder * parentResponder) :
|
||||
for (int i = 0; i < 2; i++) {
|
||||
m_complexFormatCells[i].setExpression(m_complexFormatLayout[i]);
|
||||
}
|
||||
m_editableCell.setMessage(I18n::Message::SignificantFigures);
|
||||
m_editableCell.setMessageFontSize(KDText::FontSize::Large);
|
||||
}
|
||||
|
||||
SubController::~SubController() {
|
||||
@@ -50,13 +54,8 @@ View * SubController::view() {
|
||||
return &m_selectableTableView;
|
||||
}
|
||||
|
||||
void SubController::didEnterResponderChain(Responder * previousResponder) {
|
||||
if (previousResponder->commonAncestorWith(this) == parentResponder()) {
|
||||
/* We want to select the prefered SettingMessageTree only when the previous page
|
||||
* was the main setting page. We do not to change the selection when
|
||||
* dismissing a pop-up for instance. */
|
||||
selectCellAtLocation(0, valueIndexForPreference(m_messageTreeModel->label()));
|
||||
}
|
||||
void SubController::didBecomeFirstResponder() {
|
||||
selectCellAtLocation(0, valueIndexForPreference(m_messageTreeModel->label()));
|
||||
if (m_messageTreeModel->label() == I18n::Message::ExamMode) {
|
||||
m_selectableTableView.reloadData();
|
||||
}
|
||||
@@ -94,6 +93,7 @@ bool SubController::handleEvent(Ion::Events::Event event) {
|
||||
return false;
|
||||
}
|
||||
/* Generic behaviour of preference menu*/
|
||||
assert(m_messageTreeModel->label() != I18n::Message::DisplayMode || selectedRow() != numberOfRows()-1); // In that case, events OK and EXE are handled by the cell
|
||||
setPreferenceWithValueIndex(m_messageTreeModel->label(), selectedRow());
|
||||
AppsContainer * myContainer = (AppsContainer * )app()->container();
|
||||
myContainer->refreshPreferences();
|
||||
@@ -115,30 +115,70 @@ int SubController::numberOfRows() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
HighlightCell * SubController::reusableCell(int index) {
|
||||
assert(index >= 0);
|
||||
assert(index < k_totalNumberOfCell);
|
||||
if (m_messageTreeModel->label() == I18n::Message::ComplexFormat) {
|
||||
HighlightCell * SubController::reusableCell(int index, int type) {
|
||||
if (type == 2) {
|
||||
assert(index == 0);
|
||||
return &m_editableCell;
|
||||
} else if (type == 1) {
|
||||
assert(index >= 0 && index < 2);
|
||||
return &m_complexFormatCells[index];
|
||||
}
|
||||
assert(index >= 0 && index < k_totalNumberOfCell);
|
||||
return &m_cells[index];
|
||||
}
|
||||
|
||||
int SubController::reusableCellCount() {
|
||||
if (m_messageTreeModel->label() == I18n::Message::ComplexFormat) {
|
||||
return 2;
|
||||
int SubController::reusableCellCount(int type) {
|
||||
switch (type) {
|
||||
case 0:
|
||||
return k_totalNumberOfCell;
|
||||
case 1:
|
||||
return 2;
|
||||
case 2:
|
||||
return 1;
|
||||
default:
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
return k_totalNumberOfCell;
|
||||
}
|
||||
|
||||
KDCoordinate SubController::cellHeight() {
|
||||
int SubController::typeAtLocation(int i, int j) {
|
||||
if (m_messageTreeModel->label() == I18n::Message::ComplexFormat) {
|
||||
return 1;
|
||||
}
|
||||
if (m_messageTreeModel->label() == I18n::Message::DisplayMode && j == numberOfRows()-1) {
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
KDCoordinate SubController::rowHeight(int j) {
|
||||
return Metric::ParameterCellHeight;
|
||||
}
|
||||
|
||||
KDCoordinate SubController::cumulatedHeightFromIndex(int j) {
|
||||
return rowHeight(0) * j;
|
||||
}
|
||||
|
||||
int SubController::indexFromCumulatedHeight(KDCoordinate offsetY) {
|
||||
KDCoordinate height = rowHeight(0);
|
||||
if (height == 0) {
|
||||
return 0;
|
||||
}
|
||||
return (offsetY - 1) / height;
|
||||
}
|
||||
|
||||
void SubController::willDisplayCellForIndex(HighlightCell * cell, int index) {
|
||||
if (m_messageTreeModel->label() == I18n::Message::ComplexFormat) {
|
||||
return;
|
||||
}
|
||||
/* Number of significants figure row */
|
||||
if (m_messageTreeModel->label() == I18n::Message::DisplayMode && index == numberOfRows()-1) {
|
||||
MessageTableCellWithEditableText * myCell = (MessageTableCellWithEditableText *)cell;
|
||||
char buffer[3];
|
||||
Integer(Preferences::sharedPreferences()->numberOfSignificantDigits()).writeTextInBuffer(buffer, 3);
|
||||
myCell->setAccessoryText(buffer);
|
||||
return;
|
||||
}
|
||||
MessageTableCellWithBuffer * myCell = (MessageTableCellWithBuffer *)cell;
|
||||
myCell->setMessage(m_messageTreeModel->children(index)->label());
|
||||
myCell->setMessageFontSize(KDText::FontSize::Large);
|
||||
@@ -179,6 +219,56 @@ void SubController::viewDidDisappear() {
|
||||
m_selectableTableView.deselectTable();
|
||||
}
|
||||
|
||||
bool SubController::textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) {
|
||||
return (event == Ion::Events::Up && selectedRow() > 0)
|
||||
|| TextFieldDelegate::textFieldShouldFinishEditing(textField, event);
|
||||
}
|
||||
|
||||
bool SubController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) {
|
||||
Context * globalContext = textFieldDelegateApp()->localContext();
|
||||
float floatBody = Expression::approximateToScalar<float>(text, *globalContext);
|
||||
if (std::isnan(floatBody) || std::isinf(floatBody)) {
|
||||
floatBody = PrintFloat::k_numberOfPrintedSignificantDigits;
|
||||
}
|
||||
if (floatBody < 1) {
|
||||
floatBody = 1;
|
||||
}
|
||||
if (floatBody > PrintFloat::k_numberOfStoredSignificantDigits) {
|
||||
floatBody = PrintFloat::k_numberOfStoredSignificantDigits;
|
||||
}
|
||||
Preferences::sharedPreferences()->setNumberOfSignificantDigits((char)std::round(floatBody));
|
||||
m_selectableTableView.reloadCellAtLocation(0, selectedRow());
|
||||
if (event == Ion::Events::Up || event == Ion::Events::OK) {
|
||||
m_selectableTableView.handleEvent(event);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SubController::textFieldDidReceiveEvent(::TextField * textField, Ion::Events::Event event) {
|
||||
if (event == Ion::Events::Backspace && !textField->isEditing()) {
|
||||
textField->setEditing(true);
|
||||
return true;
|
||||
}
|
||||
return TextFieldDelegate::textFieldDidReceiveEvent(textField, event);
|
||||
}
|
||||
|
||||
void SubController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) {
|
||||
if (m_messageTreeModel->label() != I18n::Message::DisplayMode) {
|
||||
return;
|
||||
}
|
||||
if (previousSelectedCellX == t->selectedColumn() && previousSelectedCellY == t->selectedRow()) {
|
||||
return;
|
||||
}
|
||||
if (previousSelectedCellY == numberOfRows()-1) {
|
||||
MessageTableCellWithEditableText * myCell = (MessageTableCellWithEditableText *)t->cellAtLocation(previousSelectedCellX, previousSelectedCellY);
|
||||
myCell->setEditing(false);
|
||||
}
|
||||
if (t->selectedRow() == numberOfRows() -1) {
|
||||
MessageTableCellWithEditableText * myNewCell = (MessageTableCellWithEditableText *)t->selectedCell();
|
||||
app()->setFirstResponder(myNewCell);
|
||||
}
|
||||
}
|
||||
|
||||
StackViewController * SubController::stackController() const {
|
||||
return (StackViewController *)parentResponder();
|
||||
}
|
||||
@@ -208,5 +298,8 @@ int SubController::valueIndexForPreference(I18n::Message message) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Shared::TextFieldDelegateApp * SubController::textFieldDelegateApp() {
|
||||
return (Shared::TextFieldDelegateApp *)app();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,10 +4,11 @@
|
||||
#include <escher.h>
|
||||
#include "settings_message_tree.h"
|
||||
#include "../hardware_test/pop_up_controller.h"
|
||||
#include "../shared/text_field_delegate.h"
|
||||
|
||||
namespace Settings {
|
||||
|
||||
class SubController : public ViewController, public SimpleListViewDataSource, public SelectableTableViewDataSource {
|
||||
class SubController : public ViewController, public ListViewDataSource, public SelectableTableViewDataSource, public SelectableTableViewDelegate, public Shared::TextFieldDelegate {
|
||||
public:
|
||||
SubController(Responder * parentResponder);
|
||||
~SubController();
|
||||
@@ -18,24 +19,34 @@ public:
|
||||
View * view() override;
|
||||
const char * title() override;
|
||||
bool handleEvent(Ion::Events::Event event) override;
|
||||
void didEnterResponderChain(Responder * previousFirstResponder) override;
|
||||
void didBecomeFirstResponder() override;
|
||||
int numberOfRows() override;
|
||||
KDCoordinate cellHeight() override;
|
||||
HighlightCell * reusableCell(int index) override;
|
||||
int reusableCellCount() override;
|
||||
KDCoordinate rowHeight(int j) override;
|
||||
KDCoordinate cumulatedHeightFromIndex(int j) override;
|
||||
int indexFromCumulatedHeight(KDCoordinate offsetY) override;
|
||||
HighlightCell * reusableCell(int index, int type) override;
|
||||
int reusableCellCount(int type) override;
|
||||
int typeAtLocation(int i, int j) override;
|
||||
void willDisplayCellForIndex(HighlightCell * cell, int index) override;
|
||||
void setMessageTreeModel(const MessageTree * messageTreeModel);
|
||||
void viewWillAppear() override;
|
||||
void viewDidDisappear() override;
|
||||
bool textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) override;
|
||||
bool textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) override;
|
||||
bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override;
|
||||
void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) override;
|
||||
private:
|
||||
StackViewController * stackController() const;
|
||||
void setPreferenceWithValueIndex(I18n::Message message, int valueIndex);
|
||||
int valueIndexForPreference(I18n::Message message);
|
||||
Shared::TextFieldDelegateApp * textFieldDelegateApp() override;
|
||||
constexpr static int k_totalNumberOfCell = I18n::NumberOfLanguages;
|
||||
constexpr static KDCoordinate k_topBottomMargin = 13;
|
||||
MessageTableCellWithBuffer m_cells[k_totalNumberOfCell];
|
||||
ExpressionTableCell m_complexFormatCells[2];
|
||||
Poincare::ExpressionLayout * m_complexFormatLayout[2];
|
||||
MessageTableCellWithEditableText m_editableCell;
|
||||
char m_draftTextBuffer[MessageTableCellWithEditableText::k_bufferLength];
|
||||
SelectableTableView m_selectableTableView;
|
||||
MessageTree * m_messageTreeModel;
|
||||
HardwareTest::PopUpController m_hardwareTestPopUpController;
|
||||
|
||||
@@ -24,7 +24,7 @@ bool EditableCellTableViewController::textFieldShouldFinishEditing(TextField * t
|
||||
bool EditableCellTableViewController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) {
|
||||
AppsContainer * appsContainer = ((TextFieldDelegateApp *)app())->container();
|
||||
Context * globalContext = appsContainer->globalContext();
|
||||
double floatBody = Expression::approximate<double>(text, *globalContext);
|
||||
double floatBody = Expression::approximateToScalar<double>(text, *globalContext);
|
||||
if (std::isnan(floatBody) || std::isinf(floatBody)) {
|
||||
app()->displayWarning(I18n::Message::UndefinedValue);
|
||||
return false;
|
||||
|
||||
@@ -119,7 +119,7 @@ bool FloatParameterController::textFieldShouldFinishEditing(TextField * textFiel
|
||||
bool FloatParameterController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) {
|
||||
AppsContainer * appsContainer = ((TextFieldDelegateApp *)app())->container();
|
||||
Context * globalContext = appsContainer->globalContext();
|
||||
double floatBody = Expression::approximate<double>(text, *globalContext);
|
||||
double floatBody = Expression::approximateToScalar<double>(text, *globalContext);
|
||||
if (std::isnan(floatBody) || std::isinf(floatBody)) {
|
||||
app()->displayWarning(I18n::Message::UndefinedValue);
|
||||
return false;
|
||||
|
||||
@@ -69,16 +69,23 @@ const char * Function::name() const {
|
||||
return m_name;
|
||||
}
|
||||
|
||||
Poincare::Expression * Function::expression() const {
|
||||
Poincare::Expression * Function::expression(Poincare::Context * context) const {
|
||||
if (m_expression == nullptr) {
|
||||
m_expression = Expression::parse(m_text);
|
||||
if (m_expression) {
|
||||
Expression::Simplify(&m_expression, *context);
|
||||
}
|
||||
}
|
||||
return m_expression;
|
||||
}
|
||||
|
||||
Poincare::ExpressionLayout * Function::layout() {
|
||||
if (m_layout == nullptr && expression() != nullptr) {
|
||||
m_layout = expression()->createLayout(Expression::FloatDisplayMode::Decimal);
|
||||
if (m_layout == nullptr) {
|
||||
Expression * nonSimplifiedExpression = Expression::parse(m_text);
|
||||
if (nonSimplifiedExpression != nullptr) {
|
||||
m_layout = nonSimplifiedExpression->createLayout(Expression::FloatDisplayMode::Decimal);
|
||||
delete nonSimplifiedExpression;
|
||||
}
|
||||
}
|
||||
return m_layout;
|
||||
}
|
||||
@@ -100,12 +107,12 @@ bool Function::isEmpty() {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T Function::templatedEvaluateAtAbscissa(T x, Poincare::Context * context) const {
|
||||
T Function::templatedApproximateAtAbscissa(T x, Poincare::Context * context) const {
|
||||
Poincare::VariableContext<T> variableContext = Poincare::VariableContext<T>(symbol(), context);
|
||||
Poincare::Symbol xSymbol(symbol());
|
||||
Poincare::Complex<T> e = Poincare::Complex<T>::Float(x);
|
||||
variableContext.setExpressionForSymbolName(&e, &xSymbol, variableContext);
|
||||
return expression()->approximate<T>(variableContext);
|
||||
return expression(context)->approximateToScalar<T>(variableContext);
|
||||
}
|
||||
|
||||
void Function::tidy() {
|
||||
@@ -121,5 +128,5 @@ void Function::tidy() {
|
||||
|
||||
}
|
||||
|
||||
template float Shared::Function::templatedEvaluateAtAbscissa<float>(float, Poincare::Context*) const;
|
||||
template double Shared::Function::templatedEvaluateAtAbscissa<double>(double, Poincare::Context*) const;
|
||||
template float Shared::Function::templatedApproximateAtAbscissa<float>(float, Poincare::Context*) const;
|
||||
template double Shared::Function::templatedApproximateAtAbscissa<double>(double, Poincare::Context*) const;
|
||||
|
||||
@@ -19,7 +19,7 @@ public:
|
||||
const char * text() const;
|
||||
const char * name() const;
|
||||
KDColor color() const { return m_color; }
|
||||
Poincare::Expression * expression() const;
|
||||
Poincare::Expression * expression(Poincare::Context * context) const;
|
||||
Poincare::ExpressionLayout * layout();
|
||||
virtual bool isDefined();
|
||||
bool isActive();
|
||||
@@ -28,16 +28,16 @@ public:
|
||||
virtual void setContent(const char * c);
|
||||
void setColor(KDColor m_color);
|
||||
virtual float evaluateAtAbscissa(float x, Poincare::Context * context) const {
|
||||
return templatedEvaluateAtAbscissa(x, context);
|
||||
return templatedApproximateAtAbscissa(x, context);
|
||||
}
|
||||
virtual double evaluateAtAbscissa(double x, Poincare::Context * context) const {
|
||||
return templatedEvaluateAtAbscissa(x, context);
|
||||
return templatedApproximateAtAbscissa(x, context);
|
||||
}
|
||||
virtual void tidy();
|
||||
private:
|
||||
constexpr static size_t k_dataLengthInBytes = (TextField::maxBufferSize()+2)*sizeof(char)+2;
|
||||
static_assert((k_dataLengthInBytes & 0x3) == 0, "The function data size is not a multiple of 4 bytes (cannot compute crc)"); // Assert that dataLengthInBytes is a multiple of 4
|
||||
template<typename T> T templatedEvaluateAtAbscissa(T x, Poincare::Context * context) const;
|
||||
template<typename T> T templatedApproximateAtAbscissa(T x, Poincare::Context * context) const;
|
||||
virtual char symbol() const = 0;
|
||||
mutable Poincare::Expression * m_expression;
|
||||
char m_text[TextField::maxBufferSize()];
|
||||
|
||||
@@ -16,7 +16,7 @@ public:
|
||||
AppsContainer * container();
|
||||
virtual const char * XNT();
|
||||
bool textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) override;
|
||||
bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override;
|
||||
virtual bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override;
|
||||
Toolbox * toolboxForTextField(TextField * textField) override;
|
||||
protected:
|
||||
TextFieldDelegateApp(Container * container, Snapshot * snapshot, ViewController * rootViewController);
|
||||
|
||||
@@ -13,6 +13,7 @@ public:
|
||||
constexpr static KDColor GreyBright = KDColor::RGB24(0xececec);
|
||||
constexpr static KDColor GreyMiddle = KDColor::RGB24(0xd9d9d9);
|
||||
constexpr static KDColor GreyDark = KDColor::RGB24(0xa7a7a7);
|
||||
constexpr static KDColor GreyVeryDark = KDColor::RGB24(0x8c8c8c);
|
||||
constexpr static KDColor Select = KDColor::RGB24(0xd4d7e0);
|
||||
constexpr static KDColor SelectDark = KDColor::RGB24(0xb0b8d8);
|
||||
constexpr static KDColor WallScreen = KDColor::RGB24(0xf7f9fa);
|
||||
|
||||
@@ -8,6 +8,7 @@ constexpr KDColor Palette::GreyWhite;
|
||||
constexpr KDColor Palette::GreyBright;
|
||||
constexpr KDColor Palette::GreyMiddle;
|
||||
constexpr KDColor Palette::GreyDark;
|
||||
constexpr KDColor Palette::GreyVeryDark;
|
||||
constexpr KDColor Palette::Select;
|
||||
constexpr KDColor Palette::SelectDark;
|
||||
constexpr KDColor Palette::WallScreen;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
extern "C" {
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
}
|
||||
|
||||
namespace Ion {
|
||||
@@ -37,10 +38,14 @@ public:
|
||||
constexpr State(uint64_t s = 0) :
|
||||
m_bitField(s)
|
||||
{}
|
||||
/* "Shift behavior is undefined if the right operand is negative, or greater
|
||||
* than or equal to the length in bits of the promoted left operand" according
|
||||
* to C++ spec but k is always in [0:52]. */
|
||||
explicit constexpr State(Key k) :
|
||||
m_bitField((uint64_t)1 << (uint8_t)k)
|
||||
{}
|
||||
inline bool keyDown(Key k) const {
|
||||
assert((uint8_t)k < 64);
|
||||
return (m_bitField>>(uint8_t)k) & 1;
|
||||
}
|
||||
operator uint64_t() const { return m_bitField; }
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define REGS_REGISTER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
template <typename T>
|
||||
class Register {
|
||||
@@ -21,13 +22,19 @@ public:
|
||||
m_value = bit_range_set_value(high, low, m_value, value);
|
||||
}
|
||||
T getBitRange(uint8_t high, uint8_t low) volatile {
|
||||
/* "Shift behavior is undefined if the right operand is negative, or greater
|
||||
* than or equal to the length in bits of the promoted left operand" according
|
||||
* to C++ spec. */
|
||||
assert(low < 8*sizeof(T));
|
||||
return (m_value & bit_range_mask(high,low)) >> low;
|
||||
}
|
||||
protected:
|
||||
static constexpr T bit_range_mask(uint8_t high, uint8_t low) {
|
||||
// Same comment as for getBitRange: we should assert (high-low+1) < 8*sizeof(T)
|
||||
return ((((T)1)<<(high-low+1))-1)<<low;
|
||||
}
|
||||
static constexpr T bit_range_value(T value, uint8_t high, uint8_t low) {
|
||||
// Same comment as for getBitRange: we should assert low < 8*sizeof(T))
|
||||
return (value<<low) & bit_range_mask(high,low);
|
||||
}
|
||||
static constexpr T bit_range_set_value(uint8_t high, uint8_t low, T originalValue, T targetValue) {
|
||||
|
||||
Binary file not shown.
@@ -1,10 +1,17 @@
|
||||
/* See the "Run-time ABI for the ARM Architecture", Section 4.2 */
|
||||
#include <assert.h>
|
||||
|
||||
typedef unsigned int uint32_t;
|
||||
|
||||
long long __aeabi_llsl(long long value, int shift) {
|
||||
uint32_t low = (uint32_t)value << shift;
|
||||
/* "Shift behavior is undefined if the right operand is negative, or greater
|
||||
* than or equal to the length in bits of the promoted left operand" according
|
||||
* to C++ spec. However, arm compiler fill the vacated bits with 0 */
|
||||
assert(shift < 32 || low == 0);
|
||||
uint32_t high = ((uint32_t)(value >> 32) << shift);
|
||||
// Same comment
|
||||
assert(shift < 32 || high == 0);
|
||||
if (shift < 32) {
|
||||
high |= ((uint32_t)value >> (32 - shift));
|
||||
} else {
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
/* See the "Run-time ABI for the ARM Architecture", Section 4.2 */
|
||||
#include <assert.h>
|
||||
|
||||
typedef unsigned int uint32_t;
|
||||
|
||||
long long __aeabi_llsr(long long value, int shift) {
|
||||
uint32_t low = ((uint32_t)value >> shift);
|
||||
/* "Shift behavior is undefined if the right operand is negative, or greater
|
||||
* than or equal to the length in bits of the promoted left operand" according
|
||||
* to C++ spec. However, arm compiler fill the vacated bits with 0 */
|
||||
assert(shift < 32 || low == 0);
|
||||
if (shift < 32) {
|
||||
low |= ((uint32_t)(value >> 32) << (32 - shift));
|
||||
} else {
|
||||
low |= ((uint32_t)(value >> 32) >> (shift - 32));
|
||||
}
|
||||
uint32_t high = (uint32_t)(value >> 32) >> shift;
|
||||
// Same comment
|
||||
assert(shift < 32 || high == 0);
|
||||
return ((long long)high << 32) | low;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ objs += $(addprefix poincare/src/,\
|
||||
division_quotient.o\
|
||||
division_remainder.o\
|
||||
dynamic_hierarchy.o\
|
||||
evaluation_engine.o\
|
||||
approximation_engine.o\
|
||||
expression.o\
|
||||
expression_lexer.o\
|
||||
expression_parser.o\
|
||||
@@ -34,7 +34,6 @@ objs += $(addprefix poincare/src/,\
|
||||
frac_part.o\
|
||||
global_context.o\
|
||||
great_common_divisor.o\
|
||||
hierarchy.o\
|
||||
hyperbolic_arc_cosine.o\
|
||||
hyperbolic_arc_sine.o\
|
||||
hyperbolic_arc_tangent.o\
|
||||
@@ -101,33 +100,31 @@ objs += $(addprefix poincare/src/layout/,\
|
||||
)
|
||||
|
||||
tests += $(addprefix poincare/test/,\
|
||||
arithmetic.cpp\
|
||||
convert_expression_to_text.cpp\
|
||||
helper.cpp\
|
||||
integer.cpp\
|
||||
simplify_easy.cpp\
|
||||
)
|
||||
|
||||
testsi += $(addprefix poincare/test/,\
|
||||
addition.cpp\
|
||||
arithmetic.cpp\
|
||||
complex.cpp\
|
||||
convert_expression_to_text.cpp\
|
||||
division.cpp\
|
||||
factorial.cpp\
|
||||
function.cpp\
|
||||
helper.cpp\
|
||||
integer.cpp\
|
||||
logarithm.cpp\
|
||||
matrix.cpp\
|
||||
multiplication.cpp\
|
||||
parser.cpp\
|
||||
product.cpp\
|
||||
power.cpp\
|
||||
rational.cpp\
|
||||
simplify_mix.cpp\
|
||||
subtraction.cpp\
|
||||
simplify_utils.cpp\
|
||||
symbol.cpp\
|
||||
trigo.cpp\
|
||||
)
|
||||
# simplify_utils.cpp\
|
||||
|
||||
ifdef POINCARE_TESTS_PRINT_EXPRESSIONS
|
||||
tests += poincare/src/expression_debug.o
|
||||
objs += poincare/src/expression_debug.o
|
||||
SFLAGS += -DPOINCARE_TESTS_PRINT_EXPRESSIONS=1
|
||||
endif
|
||||
|
||||
|
||||
@@ -1,20 +1,95 @@
|
||||
Things we will want to simplify:
|
||||
# Poincare
|
||||
|
||||
2.y.3 -> 6.y
|
||||
y.x.3 + x^2 +1 -> x^2 + 3*x*y + 1
|
||||
Zeroes and ones
|
||||
x + 0 -> x
|
||||
1*x -> x
|
||||
x^1 -> x
|
||||
x^0 -> 1
|
||||
Simplify fractions
|
||||
(x^2+5.x+6)/(x+2) -> x+3
|
||||
Polynomials
|
||||
(x+1)^2-x^2 -> 2*x+1
|
||||
Divisions
|
||||
(2*x)/(x^2-1) - 1/(x-1) -> 1/(x+1)
|
||||
Functional identities
|
||||
ln(2x) - ln(x) -> ln(2)
|
||||
y*sin^2(x) + y*cos^2(x) -> y
|
||||
Expressions have a structure of tree, storing:
|
||||
- Pointers to the operand expressions (ie children)
|
||||
- A pointer to the parent expression
|
||||
Expressions are typed (ie Type::Addition, Type::Multiplication...) and some expressions also hold values (ie Type::Rational).
|
||||
Multiplication and Addition are the only type that can hold an infinite number of operands. Other expressions have a fixed number of operands (ie AbsoluteValue).
|
||||
|
||||
Note : The simplification process can be interrupted! -> It probably browses a graph
|
||||
## Simplification
|
||||
|
||||
Expression simplification is done in-place and modify directly the expression.
|
||||
Simplify is a two-phase method:
|
||||
- It first reduces the expression
|
||||
- Then, it beautify the expression
|
||||
So far, we excluded matrices from the simplificaiton process to avoid increasing complexity due to non commutativity in multiplications.
|
||||
|
||||
### Order
|
||||
|
||||
We define an simplification order on expressions with the following features:
|
||||
- The order is total on types and values:
|
||||
Rational(-2/3) < Rational(0) < ... < Multiplication < Power < Addition < ...
|
||||
- The order relationship is depth-first recursive: if two expressions are equal in type (and values), we compare their operands starting with the last.
|
||||
To compare two expressions, we first sort their commutative children to ensure the unicity of expression representations. This guarantee that the order is total on expressions.
|
||||
|
||||
Moreover, the simplification order have some other specificities for some types:
|
||||
- for addition and multiplication, any rational operand is always the first operands after sorting (by commutativity).
|
||||
- Comparing an addition expression with an expression of different type called e is equivalent to comparing the addition with an addition with a single operand e.
|
||||
- Idem for multiplications.
|
||||
- To compare a power expression with an expression of different type called e, we compare the power with e^1.
|
||||
The order groups like terms together to avoid quadratic complexity when factorizing addition or multiplication. For example, it groups terms with same bases together (ie Pi, Pi^3) and with same non-rational factors together (ie Pi, 2*Pi).
|
||||
|
||||
Last comment; as the order is total, we can easily check if two expressions are identical by using this order.
|
||||
|
||||
|
||||
### Reduce
|
||||
|
||||
The reducing phase is the most important part of simplification.
|
||||
It happens recursively and bottom-up: we first reduce the operands of an expression before reducing the expression itself. That way, when reducing itself, an expression can assert that its operands are reduced (and thus have some properties explained in the following).
|
||||
Every type of expression has its own rules of reducing.
|
||||
|
||||
To decrease the pool of possible expression types in reduced expressions, we converte subtraction to addition, division to power etc ... at reduction:
|
||||
a-b -> a+(-1)*b
|
||||
a/b -> a*b^(-1)
|
||||
-a -> (-1)*a
|
||||
sqrt(x) -> x^(1/2)
|
||||
root(x,y) -> x^(1/y)
|
||||
ln(x) -> log(x,e)
|
||||
|
||||
Here is a short tour of shallow reduction for the main types:
|
||||
|
||||
1. Additions are reduced by applying mathematics rules, ie:
|
||||
- Associativity: (a+b)+c -> a+b+c
|
||||
- Commutativity: a+b -> b+c which enables to sort operands and group like-terms together
|
||||
- Factorization: a+5a -> 6a
|
||||
- a+0->a
|
||||
- We also reduce addition to same denominator.
|
||||
|
||||
2. Multiplications apply the following rules:
|
||||
- Associativity
|
||||
- Commutativity (which is true because we do no reduce matrices yet)
|
||||
- a*0 -> 0
|
||||
- Factorization
|
||||
- sin/cos -> tan
|
||||
- Distribution: a*(b+c) -> ab+ac
|
||||
|
||||
3. Powers apply the following rules:
|
||||
- We get rid of square roots at denominator and of sum of 2 square roots at denominator
|
||||
- x^0-> 1 if x != 0
|
||||
- x^1 -> x
|
||||
- 0^x -> 0 if x>0, undefined otherwise
|
||||
- 1^x
|
||||
- (a^b)^c -> a^(b+c) if a > 0 or c is integer
|
||||
- (a*b*c*...)^n = a^n*b^n*c^n*... if n integer
|
||||
- (a*b*...)^r -> |a|^r*(sign(a)*b*...)^r if a rational
|
||||
- a^(b+c) -> (a^b)*a^c with a and b rational
|
||||
- r^s with r, s rationals can be simplified using the factorisation in primes of r (ie, 8^(1/2) -> 2*2^(1/2))
|
||||
- i^(p/q)-> exp^(i*Pi*p/(2q)) with p, q integers
|
||||
- exp^(i*Pi*p/q) -> cos(Pi*p/q)+i*sin(Pi*p/q) with p, q integers
|
||||
- x^log(y,x)->y if y > 0
|
||||
- 10^log(y)
|
||||
|
||||
To avoid infinite loop, reduction is contextualized on the parent expression (ie, reducing addition to same denominator). This forces to reduce an expression only once it is included in a expression.
|
||||
|
||||
### Beautify
|
||||
|
||||
This phase turns expressions in a more readable way. Division, subtraction, Naperian logarithm reappear at this step. Parenthesis are also added to be able to print the tree in infix notation without any ambiguity.
|
||||
This phase is also recursive and top-down: we first beautify the node expression and the beautify its operands.
|
||||
|
||||
## Approximation
|
||||
|
||||
Expressions can be approximate which return another (dynamically allocated) expression that can be either:
|
||||
- a complex
|
||||
- a matrix of complex
|
||||
|
||||
To approximate an expression, we first approximate its operands (which are ensured to be either complex or matrix of complex) and then approximate the expression using the operand approximations depending on its type.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define POINCARE_ABSOLUTE_VALUE_H
|
||||
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
@@ -24,11 +24,11 @@ private:
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<float>(this, context, angleUnit, computeOnComplex<float>);
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit, computeOnComplex<float>);
|
||||
}
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <poincare/dynamic_hierarchy.h>
|
||||
#include <poincare/rational.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -19,10 +19,10 @@ public:
|
||||
/* Evaluation */
|
||||
template<typename T> static Complex<T> compute(const Complex<T> c, const Complex<T> d);
|
||||
template<typename T> static Matrix * computeOnMatrices(const Matrix * m, const Matrix * n) {
|
||||
return EvaluationEngine::elementWiseOnComplexMatrices(m, n, compute<T>);
|
||||
return ApproximationEngine::elementWiseOnComplexMatrices(m, n, compute<T>);
|
||||
}
|
||||
template<typename T> static Matrix * computeOnComplexAndMatrix(const Complex<T> * c, const Matrix * m) {
|
||||
return EvaluationEngine::elementWiseOnComplexAndComplexMatrix(c, m, compute<T>);
|
||||
return ApproximationEngine::elementWiseOnComplexAndComplexMatrix(c, m, compute<T>);
|
||||
}
|
||||
private:
|
||||
/* Layout */
|
||||
@@ -43,13 +43,13 @@ private:
|
||||
static bool TermsHaveIdenticalNonRationalFactors(const Expression * e1, const Expression * e2);
|
||||
/* Evaluation */
|
||||
template<typename T> static Matrix * computeOnMatrixAndComplex(const Matrix * m, const Complex<T> * c) {
|
||||
return EvaluationEngine::elementWiseOnComplexAndComplexMatrix(c, m, compute<T>);
|
||||
return ApproximationEngine::elementWiseOnComplexAndComplexMatrix(c, m, compute<T>);
|
||||
}
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::mapReduce<float>(this, context, angleUnit, compute<float>, computeOnComplexAndMatrix<float>, computeOnMatrixAndComplex<float>, computeOnMatrices<float>);
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::mapReduce<float>(this, context, angleUnit, compute<float>, computeOnComplexAndMatrix<float>, computeOnMatrixAndComplex<float>, computeOnMatrices<float>);
|
||||
}
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::mapReduce<double>(this, context, angleUnit, compute<double>, computeOnComplexAndMatrix<double>, computeOnMatrixAndComplex<double>, computeOnMatrices<double>);
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::mapReduce<double>(this, context, angleUnit, compute<double>, computeOnComplexAndMatrix<double>, computeOnMatrixAndComplex<double>, computeOnMatrices<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef POINCARE_EVALUATION_ENGINE_H
|
||||
#define POINCARE_EVALUATION_ENGINE_H
|
||||
#ifndef POINCARE_APPROXIMATION_ENGINE_H
|
||||
#define POINCARE_APPROXIMATION_ENGINE_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/complex.h>
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class EvaluationEngine {
|
||||
class ApproximationEngine {
|
||||
public:
|
||||
template <typename T> using ComplexCompute = Complex<T>(*)(const Complex<T>, Expression::AngleUnit angleUnit);
|
||||
template<typename T> static Expression * map(const Expression * expression, Context& context, Expression::AngleUnit angleUnit, ComplexCompute<T> compute);
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -27,11 +27,11 @@ private:
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -25,11 +25,11 @@ private:
|
||||
Expression * shallowReduce(Context & context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -25,11 +25,11 @@ private:
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -12,6 +12,10 @@ public:
|
||||
constexpr static int k_numberOfPrimeFactors = 1000;
|
||||
constexpr static int k_maxNumberOfPrimeFactors = 32;
|
||||
static const Integer k_primorial32;
|
||||
private:
|
||||
/* When decomposing an integer into primes factors, we look for its prime
|
||||
* factors among integer from 2 to 10000. */
|
||||
constexpr static int k_biggestPrimeFactor = 10000;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -21,9 +21,9 @@ private:
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedApproximate(Context& context, AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -23,11 +23,11 @@ private:
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<float>(this, context, angleUnit, computeOnComplex<float>);
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit, computeOnComplex<float>);
|
||||
}
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <poincare/preferences.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/integer.h>
|
||||
#include <assert.h>
|
||||
|
||||
namespace Poincare {
|
||||
@@ -12,14 +13,29 @@ namespace PrintFloat {
|
||||
// The wors case is -1.234E-38
|
||||
return numberOfSignificantDigits + 7;
|
||||
}
|
||||
/* This function prints the int i in the buffer with a '.' at the position
|
||||
/* This function prints the integer i in the buffer with a '.' at the position
|
||||
* specified by the decimalMarkerPosition. It starts printing at the end of the
|
||||
* buffer and print from right to left. The integer given should be of the right
|
||||
* length to be written in bufferLength chars. If the integer is to small, the
|
||||
* empty chars on the left side are completed with '0'. If the integer is too
|
||||
* big, the printing stops when no more empty chars are available without
|
||||
* returning any warning. */
|
||||
void printBase10IntegerWithDecimalMarker(char * buffer, int bufferSize, int i, int decimalMarkerPosition);
|
||||
* returning any warning.
|
||||
* Warning: the buffer is not null terminated but is ensured to hold
|
||||
* bufferLength chars. */
|
||||
void printBase10IntegerWithDecimalMarker(char * buffer, int bufferLength, Integer i, int decimalMarkerPosition);
|
||||
|
||||
constexpr static int k_numberOfPrintedSignificantDigits = 7;
|
||||
constexpr static int k_numberOfStoredSignificantDigits = 14;
|
||||
|
||||
/* We here define the buffer size to write the lengthest float possible.
|
||||
* At maximum, the number has 15 significant digits so, in the worst case it
|
||||
* has the form -1.99999999999999e-308 (15+7+1 char) (the auto mode is always
|
||||
* shorter. */
|
||||
constexpr static int k_maxFloatBufferLength = k_numberOfStoredSignificantDigits+7+1;
|
||||
/* We here define the buffer size to write the lengthest complex possible.
|
||||
* The worst case has the form
|
||||
* -1.99999999999999e-308*e^(-1.99999999999999e-308*i) (14+14+7+1 char) */
|
||||
constexpr static int k_maxComplexBufferLength = k_maxFloatBufferLength-1+k_maxFloatBufferLength-1+7+1;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -47,6 +63,10 @@ public:
|
||||
Complex<T> * clone() const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override;
|
||||
|
||||
/* Simplification: complex does not implement simplificationOrderSameType
|
||||
* because Complex expressions do not appear before evaluation. The sorting
|
||||
* step is part of simplificaiton process which thus handles no complex. */
|
||||
|
||||
/* The parameter 'DisplayMode' refers to the way to display float 'scientific'
|
||||
* or 'auto'. The scientific mode returns float with style -1.2E2 whereas
|
||||
* the auto mode tries to return 'natural' float like (0.021) and switches
|
||||
@@ -61,23 +81,13 @@ public:
|
||||
static int convertFloatToText(T d, char * buffer, int bufferSize, int numberOfSignificantDigits, Expression::FloatDisplayMode mode = Expression::FloatDisplayMode::Default);
|
||||
private:
|
||||
Complex(T a, T b);
|
||||
constexpr static int k_numberOfSignificantDigits = 7;
|
||||
ExpressionLayout * privateCreateLayout(Expression::FloatDisplayMode floatDisplayMode, Expression::ComplexFormat complexFormat) const override;
|
||||
Expression * privateEvaluate(Expression::SinglePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Expression * privateEvaluate(Expression::DoublePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename U> Complex<U> * templatedEvaluate(Context& context, Expression::AngleUnit angleUnit) const;
|
||||
/* We here define the buffer size to write the lengthest float possible.
|
||||
* At maximum, the number has 7 significant digits so, in the worst case it
|
||||
* has the form -1.999999e-308 (7+7+1 char) (the auto mode is always
|
||||
* shorter. */
|
||||
constexpr static int k_maxFloatBufferLength = 7+7+1;
|
||||
/* We here define the buffer size to write the lengthest complex possible.
|
||||
* The worst case has the form -1.999999E-308*e^(-1.999999E-308*i) (14+14+7+1
|
||||
* char) */
|
||||
constexpr static int k_maxComplexBufferLength = 14+14+7+1;
|
||||
Expression * privateApproximate(Expression::SinglePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Expression * privateApproximate(Expression::DoublePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename U> Complex<U> * templatedApproximate(Context& context, Expression::AngleUnit angleUnit) const;
|
||||
/* convertComplexToText and convertFloatToTextPrivate return the string length
|
||||
* of the buffer (does not count the 0 last char)*/
|
||||
int convertComplexToText(char * buffer, int bufferSize, Expression::FloatDisplayMode floatDisplayMode, Expression::ComplexFormat complexFormat) const;
|
||||
int convertComplexToText(char * buffer, int bufferSize, int numberOfSignificantDigits, Expression::FloatDisplayMode floatDisplayMode, Expression::ComplexFormat complexFormat, char multiplicationSign) const;
|
||||
static int convertFloatToTextPrivate(T f, char * buffer, int numberOfSignificantDigits, Expression::FloatDisplayMode mode);
|
||||
ExpressionLayout * createPolarLayout(Expression::FloatDisplayMode floatDisplayMode) const;
|
||||
ExpressionLayout * createCartesianLayout(Expression::FloatDisplayMode floatDisplayMode) const;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -25,11 +25,11 @@ private:
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -23,9 +23,9 @@ private:
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Expression * privateEvaluate(Expression::SinglePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Expression * privateEvaluate(Expression::DoublePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
Expression * privateApproximate(Expression::SinglePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Expression * privateApproximate(Expression::DoublePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedApproximate(Context& context, AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define POINCARE_CONJUGATE_H
|
||||
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
@@ -16,17 +16,17 @@ private:
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, "conjugate");
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, "conj");
|
||||
}
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
#include <poincare/trigonometry.h>
|
||||
|
||||
namespace Poincare {
|
||||
@@ -27,11 +27,11 @@ private:
|
||||
/* Simplication */
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -37,11 +37,11 @@ private:
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
Expression * shallowBeautify(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedEvaluate(Context& context, Expression::AngleUnit angleUnit) const;
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedApproximate(Context& context, Expression::AngleUnit angleUnit) const;
|
||||
|
||||
constexpr static int k_maxLength = 10;
|
||||
constexpr static int k_maxLength = 15;
|
||||
Integer m_mantissa;
|
||||
int m_exponent;
|
||||
};
|
||||
|
||||
@@ -24,9 +24,9 @@ private:
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedApproximate(Context& context, AngleUnit angleUnit) const;
|
||||
template<typename T> T growthRateAroundAbscissa(T x, T h, VariableContext<T> variableContext, AngleUnit angleUnit) const;
|
||||
template<typename T> T approximateDerivate2(T x, T h, VariableContext<T> xContext, AngleUnit angleUnit) const;
|
||||
// TODO: Change coefficients?
|
||||
|
||||
@@ -24,9 +24,9 @@ private:
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context & context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedApproximate(Context& context, AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define POINCARE_DIVISION_H
|
||||
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
@@ -20,23 +20,23 @@ private:
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writeInfixExpressionTextInBuffer(this, buffer, bufferSize, "/", [](const Expression * e) {
|
||||
return e->type() == Type::Multiplication || e->type() == Type::Addition || e->type() == Type::Subtraction || e->type() == Type::Opposite;
|
||||
return e->type() == Type::Division || e->type() == Type::Multiplication || e->type() == Type::Addition || e->type() == Type::Subtraction || e->type() == Type::Opposite || (e->type() == Type::Rational && !static_cast<const Rational *>(e)->denominator().isOne());
|
||||
});
|
||||
}
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static Matrix * computeOnMatrixAndComplex(const Matrix * m, const Complex<T> * c) {
|
||||
return EvaluationEngine::elementWiseOnComplexAndComplexMatrix(c, m, compute<T>);
|
||||
return ApproximationEngine::elementWiseOnComplexAndComplexMatrix(c, m, compute<T>);
|
||||
}
|
||||
template<typename T> static Matrix * computeOnComplexAndMatrix(const Complex<T> * c, const Matrix * n);
|
||||
template<typename T> static Matrix * computeOnMatrices(const Matrix * m, const Matrix * n);
|
||||
|
||||
virtual Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::mapReduce<float>(this, context, angleUnit, compute<float>, computeOnComplexAndMatrix<float>, computeOnMatrixAndComplex<float>, computeOnMatrices<float>);
|
||||
virtual Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::mapReduce<float>(this, context, angleUnit, compute<float>, computeOnComplexAndMatrix<float>, computeOnMatrixAndComplex<float>, computeOnMatrices<float>);
|
||||
}
|
||||
virtual Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::mapReduce<double>(this, context, angleUnit, compute<double>, computeOnComplexAndMatrix<double>, computeOnMatrixAndComplex<double>, computeOnMatrices<double>);
|
||||
virtual Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::mapReduce<double>(this, context, angleUnit, compute<double>, computeOnComplexAndMatrix<double>, computeOnMatrixAndComplex<double>, computeOnMatrices<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -24,9 +24,9 @@ private:
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context & context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Complex<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Complex<T> * templatedApproximate(Context& context, AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -24,9 +24,9 @@ private:
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context & context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Complex<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Complex<T> * templatedApproximate(Context& context, AngleUnit angleUnit) const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#ifndef POINCARE_DYNAMIC_HIERARCHY_H
|
||||
#define POINCARE_DYNAMIC_HIERARCHY_H
|
||||
|
||||
#include <poincare/hierarchy.h>
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/rational.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class DynamicHierarchy : public Hierarchy {
|
||||
class DynamicHierarchy : public Expression {
|
||||
public:
|
||||
DynamicHierarchy();
|
||||
DynamicHierarchy(const Expression * const * operands, int numberOfOperands, bool cloneOperands = true);
|
||||
|
||||
@@ -72,7 +72,7 @@ class Expression {
|
||||
friend class SimplificationRoot;
|
||||
friend class Sequence;
|
||||
friend class Trigonometry;
|
||||
friend class EvaluationEngine;
|
||||
friend class ApproximationEngine;
|
||||
friend class SimplificationEngine;
|
||||
|
||||
public:
|
||||
@@ -167,15 +167,20 @@ public:
|
||||
static bool shouldStopProcessing();
|
||||
|
||||
/* Hierarchy */
|
||||
virtual const Expression * operand(int i) const = 0;
|
||||
virtual const Expression * const * operands() const = 0;
|
||||
const Expression * operand(int i) const;
|
||||
Expression * editableOperand(int i) { return const_cast<Expression *>(operand(i)); }
|
||||
virtual int numberOfOperands() const = 0;
|
||||
|
||||
Expression * replaceWith(Expression * newOperand, bool deleteAfterReplace = true);
|
||||
void replaceOperand(const Expression * oldOperand, Expression * newOperand, bool deleteOldOperand = true);
|
||||
void detachOperand(const Expression * e); // Removes an operand WITHOUT deleting it
|
||||
void detachOperands(); // Removes all operands WITHOUT deleting them
|
||||
void swapOperands(int i, int j);
|
||||
|
||||
Expression * parent() const { return m_parent; }
|
||||
void setParent(Expression * parent) { m_parent = parent; }
|
||||
bool hasAncestor(const Expression * e) const;
|
||||
virtual void replaceOperand(const Expression * oldOperand, Expression * newOperand, bool deleteOldOperand = true) = 0;
|
||||
Expression * replaceWith(Expression * newOperand, bool deleteAfterReplace = true);
|
||||
virtual void swapOperands(int i, int j) = 0;
|
||||
|
||||
/* Properties */
|
||||
enum class Sign {
|
||||
@@ -208,12 +213,15 @@ public:
|
||||
/* Evaluation Engine
|
||||
* The function evaluate creates a new expression and thus mallocs memory.
|
||||
* Do not forget to delete the new expression to avoid leaking. */
|
||||
template<typename T> Expression * evaluate(Context& context, AngleUnit angleUnit = AngleUnit::Default) const;
|
||||
template<typename T> T approximate(Context& context, AngleUnit angleUnit = AngleUnit::Default) const;
|
||||
template<typename T> static T approximate(const char * text, Context& context, AngleUnit angleUnit = AngleUnit::Default);
|
||||
template<typename T> Expression * approximate(Context& context, AngleUnit angleUnit = AngleUnit::Default) const;
|
||||
template<typename T> T approximateToScalar(Context& context, AngleUnit angleUnit = AngleUnit::Default) const;
|
||||
template<typename T> static T approximateToScalar(const char * text, Context& context, AngleUnit angleUnit = AngleUnit::Default);
|
||||
protected:
|
||||
/* Constructor */
|
||||
Expression() : m_parent(nullptr) {}
|
||||
static const Expression * const * ExpressionArray(const Expression * e1, const Expression * e2);
|
||||
/* Hierarchy */
|
||||
void detachOperandAtIndex(int i);
|
||||
/* Evaluation Engine */
|
||||
typedef float SinglePrecision;
|
||||
typedef double DoublePrecision;
|
||||
@@ -259,8 +267,8 @@ private:
|
||||
return nullptr;
|
||||
}
|
||||
/* Evaluation Engine */
|
||||
virtual Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const = 0;
|
||||
virtual Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const = 0;
|
||||
virtual Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const = 0;
|
||||
virtual Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const = 0;
|
||||
|
||||
Expression * m_parent;
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define POINCARE_FACTORIAL_H
|
||||
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -14,17 +14,19 @@ public:
|
||||
private:
|
||||
constexpr static int k_maxOperandValue = 100;
|
||||
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override;
|
||||
#if 0
|
||||
int simplificationOrderGreaterType(const Expression * e) const override;
|
||||
int simplificationOrderSameType(const Expression * e) const override;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -23,11 +23,11 @@ private:
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<float>(this, context, angleUnit, computeOnComplex<float>);
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit, computeOnComplex<float>);
|
||||
}
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -25,11 +25,11 @@ private:
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<float>(this, context, angleUnit, computeOnComplex<float>);
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit, computeOnComplex<float>);
|
||||
}
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -24,9 +24,9 @@ private:
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Complex<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Complex<T> * templatedApproximate(Context& context, AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
#ifndef POINCARE_HIERARCHY_H
|
||||
#define POINCARE_HIERARCHY_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Hierarchy : public Expression {
|
||||
public:
|
||||
using Expression::Expression;
|
||||
const Expression * operand(int i) const override;
|
||||
void swapOperands(int i, int j) override;
|
||||
void replaceOperand(const Expression * oldOperand, Expression * newOperand, bool deleteOldOperand = true) override;
|
||||
void detachOperand(const Expression * e); // Removes an operand WITHOUT deleting it
|
||||
void detachOperands(); // Removes all operands WITHOUT deleting them
|
||||
virtual const Expression * const * operands() const = 0;
|
||||
protected:
|
||||
static const Expression * const * ExpressionArray(const Expression * e1, const Expression * e2);
|
||||
private:
|
||||
void detachOperandAtIndex(int i);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -25,11 +25,11 @@ private:
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -25,11 +25,11 @@ private:
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -25,11 +25,11 @@ private:
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -25,11 +25,11 @@ private:
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -25,11 +25,11 @@ private:
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -25,11 +25,11 @@ private:
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -25,11 +25,11 @@ private:
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -22,16 +22,16 @@ private:
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Complex<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Complex<T> * templatedApproximate(Context& context, AngleUnit angleUnit) const;
|
||||
template<typename T>
|
||||
struct DetailedResult
|
||||
{
|
||||
T integral;
|
||||
T absoluteError;
|
||||
};
|
||||
constexpr static int k_maxNumberOfIterations = 100;
|
||||
constexpr static int k_maxNumberOfIterations = 10;
|
||||
#ifdef LAGRANGE_METHOD
|
||||
template<typename T> T lagrangeGaussQuadrature(T a, T b, VariableContext<T> xContext, AngleUnit angleUnit) const;
|
||||
#else
|
||||
|
||||
@@ -24,9 +24,9 @@ private:
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Complex<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Complex<T> * templatedApproximate(Context& context, AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -26,9 +26,9 @@ private:
|
||||
Expression * splitInteger(Integer i, bool isDenominator, Context & context, AngleUnit angleUnit);
|
||||
/* Evaluation */
|
||||
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedApproximate(Context& context, AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -33,9 +33,9 @@ private:
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
|
||||
/* Evaluation */
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedApproximate(Context& context, AngleUnit angleUnit) const;
|
||||
int m_numberOfRows;
|
||||
};
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ private:
|
||||
int m_numberOfRows;
|
||||
int m_numberOfColumns;
|
||||
const Expression ** m_operands;
|
||||
static Complex<double> * defaultExpression();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -20,13 +20,13 @@ private:
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
const char * name() const { return "dimension"; }
|
||||
const char * name() const { return "dim"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedApproximate(Context& context, AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -24,9 +24,9 @@ private:
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context & context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedApproximate(Context& context, AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -24,9 +24,9 @@ private:
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context & context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedApproximate(Context& context, AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -24,9 +24,9 @@ private:
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context & context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedApproximate(Context& context, AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <poincare/dynamic_hierarchy.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -22,7 +22,7 @@ public:
|
||||
/* Evaluation */
|
||||
template<typename T> static Complex<T> compute(const Complex<T> c, const Complex<T> d);
|
||||
template<typename T> static Matrix * computeOnComplexAndMatrix(const Complex<T> * c, const Matrix * m) {
|
||||
return EvaluationEngine::elementWiseOnComplexAndComplexMatrix(c, m, compute<T>);
|
||||
return ApproximationEngine::elementWiseOnComplexAndComplexMatrix(c, m, compute<T>);
|
||||
}
|
||||
template<typename T> static Matrix * computeOnMatrices(const Matrix * m, const Matrix * n);
|
||||
private:
|
||||
@@ -34,6 +34,7 @@ private:
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
Expression * privateShallowReduce(Context& context, AngleUnit angleUnit, bool expand);
|
||||
void mergeMultiplicationOperands();
|
||||
void factorizeBase(Expression * e1, Expression * e2, Context & context, AngleUnit angleUnit);
|
||||
void factorizeExponent(Expression * e1, Expression * e2, Context & context, AngleUnit angleUnit);
|
||||
Expression * distributeOnOperandAtIndex(int index, Context & context, AngleUnit angleUnit);
|
||||
@@ -44,7 +45,6 @@ private:
|
||||
static bool TermsHaveIdenticalBase(const Expression * e1, const Expression * e2);
|
||||
static bool TermsHaveIdenticalExponent(const Expression * e1, const Expression * e2);
|
||||
static bool TermHasRationalBase(const Expression * e);
|
||||
static bool TermHasIntegerExponent(const Expression * e);
|
||||
static bool TermHasRationalExponent(const Expression * e);
|
||||
static const Expression * CreateExponent(Expression * e);
|
||||
Expression * shallowBeautify(Context & context, AngleUnit angleUnit) override;
|
||||
@@ -53,13 +53,13 @@ private:
|
||||
/* Evaluation */
|
||||
|
||||
template<typename T> static Matrix * computeOnMatrixAndComplex(const Matrix * m, const Complex<T> * c) {
|
||||
return EvaluationEngine::elementWiseOnComplexAndComplexMatrix(c, m, compute<T>);
|
||||
return ApproximationEngine::elementWiseOnComplexAndComplexMatrix(c, m, compute<T>);
|
||||
}
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::mapReduce<float>(this, context, angleUnit, compute<float>, computeOnComplexAndMatrix<float>, computeOnMatrixAndComplex<float>, computeOnMatrices<float>);
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::mapReduce<float>(this, context, angleUnit, compute<float>, computeOnComplexAndMatrix<float>, computeOnMatrixAndComplex<float>, computeOnMatrices<float>);
|
||||
}
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::mapReduce<double>(this, context, angleUnit, compute<double>, computeOnComplexAndMatrix<double>, computeOnMatrixAndComplex<double>, computeOnMatrices<double>);
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::mapReduce<double>(this, context, angleUnit, compute<double>, computeOnComplexAndMatrix<double>, computeOnMatrixAndComplex<double>, computeOnMatrices<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -25,11 +25,11 @@ private:
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -22,9 +22,9 @@ private:
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static Complex<T> compute(const Complex<T> c, const Complex<T> d);
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedApproximate(Context& context, AngleUnit angleUnit) const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -20,11 +20,11 @@ private:
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<float>(this, context, angleUnit, compute<float>);
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit, compute<float>);
|
||||
}
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, compute<double>);
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, compute<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -21,9 +21,9 @@ private:
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedApproximate(Context& context, AngleUnit angleUnit) const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -25,9 +25,9 @@ private:
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Complex<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Complex<T> * templatedApproximate(Context& context, AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define POINCARE_POWER_H
|
||||
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
#include <poincare/rational.h>
|
||||
#include <poincare/multiplication.h>
|
||||
|
||||
@@ -14,19 +14,22 @@ class Power : public StaticHierarchy<2> {
|
||||
friend class NthRoot;
|
||||
friend class SquareRoot;
|
||||
friend class Addition;
|
||||
friend class Division;
|
||||
friend class Round;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
Sign sign() const override;
|
||||
template<typename T> static Complex<T> compute(const Complex<T> c, const Complex<T> d);
|
||||
private:
|
||||
constexpr static int k_maxIntegerPower = 100;
|
||||
/* Property */
|
||||
Expression * setSign(Sign s, Context & context, AngleUnit angleUnit) override;
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writeInfixExpressionTextInBuffer(this, buffer, bufferSize, name(), [](const Expression * e) {
|
||||
return e->type() == Type::Division || e->type() == Type::Multiplication || e->type() == Type::Addition || e->type() == Type::Subtraction || e->type() == Type::Opposite;
|
||||
return e->type() == Type::Power || e->type() == Type::Division || e->type() == Type::Multiplication || e->type() == Type::Addition || e->type() == Type::Subtraction || e->type() == Type::Opposite || (e->type() == Type::Rational && !static_cast<const Rational *>(e)->denominator().isOne());
|
||||
});
|
||||
}
|
||||
static const char * name() { return "^"; }
|
||||
@@ -47,17 +50,18 @@ private:
|
||||
static bool TermIsARationalSquareRootOrRational(const Expression * e);
|
||||
static const Rational * RadicandInExpression(const Expression * e);
|
||||
static const Rational * RationalFactorInExpression(const Expression * e);
|
||||
static bool RationalExponentShouldNotBeReduced(const Rational * r);
|
||||
/* Evaluation */
|
||||
constexpr static int k_maxApproximatePowerMatrix = 1000;
|
||||
constexpr static int k_maxExactPowerMatrix = 100;
|
||||
template<typename T> static Matrix * computeOnComplexAndMatrix(const Complex<T> * c, const Matrix * n) { return nullptr; }
|
||||
template<typename T> static Matrix * computeOnMatrixAndComplex(const Matrix * m, const Complex<T> * d);
|
||||
template<typename T> static Matrix * computeOnMatrices(const Matrix * m, const Matrix * n) { return nullptr; }
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::mapReduce<float>(this, context, angleUnit, compute<float>, computeOnComplexAndMatrix<float>, computeOnMatrixAndComplex<float>, computeOnMatrices<float>);
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::mapReduce<float>(this, context, angleUnit, compute<float>, computeOnComplexAndMatrix<float>, computeOnMatrixAndComplex<float>, computeOnMatrices<float>);
|
||||
}
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::mapReduce<double>(this, context, angleUnit, compute<double>, computeOnComplexAndMatrix<double>, computeOnMatrixAndComplex<double>, computeOnMatrices<double>);
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::mapReduce<double>(this, context, angleUnit, compute<double>, computeOnComplexAndMatrix<double>, computeOnMatrixAndComplex<double>, computeOnMatrices<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -23,9 +23,9 @@ private:
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Expression * privateEvaluate(Expression::SinglePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Expression * privateEvaluate(Expression::DoublePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
Expression * privateApproximate(Expression::SinglePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Expression * privateApproximate(Expression::DoublePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedApproximate(Context& context, AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -15,10 +15,13 @@ public:
|
||||
void setDisplayMode(Expression::FloatDisplayMode FloatDisplayMode);
|
||||
Expression::ComplexFormat complexFormat() const;
|
||||
void setComplexFormat(Expression::ComplexFormat complexFormat);
|
||||
char numberOfSignificantDigits() const;
|
||||
void setNumberOfSignificantDigits(char numberOfSignificantDigits);
|
||||
private:
|
||||
Expression::AngleUnit m_angleUnit;
|
||||
Expression::FloatDisplayMode m_displayMode;
|
||||
Expression::ComplexFormat m_complexFormat;
|
||||
char m_numberOfSignificantDigits;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -15,12 +15,12 @@ private:
|
||||
int emptySequenceValue() const override;
|
||||
ExpressionLayout * createSequenceLayoutWithArgumentLayouts(ExpressionLayout * subscriptLayout, ExpressionLayout * superscriptLayout, ExpressionLayout * argumentLayout) const override;
|
||||
Expression * evaluateWithNextTerm(DoublePrecision p, Expression * a, Expression * b) const override {
|
||||
return templatedEvaluateWithNextTerm<double>(a, b);
|
||||
return templatedApproximateWithNextTerm<double>(a, b);
|
||||
}
|
||||
Expression * evaluateWithNextTerm(SinglePrecision p, Expression * a, Expression * b) const override {
|
||||
return templatedEvaluateWithNextTerm<float>(a, b);
|
||||
return templatedApproximateWithNextTerm<float>(a, b);
|
||||
}
|
||||
template<typename T> Expression * templatedEvaluateWithNextTerm(Expression * a, Expression * b) const;
|
||||
template<typename T> Expression * templatedApproximateWithNextTerm(Expression * a, Expression * b) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -44,9 +44,9 @@ public:
|
||||
private:
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override;
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename U> Complex<U> * templatedEvaluate(Context& context, Expression::AngleUnit angleUnit) const;
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename U> Complex<U> * templatedApproximate(Context& context, Expression::AngleUnit angleUnit) const;
|
||||
Expression * shallowBeautify(Context & context, AngleUnit angleUnit) override;
|
||||
Expression * setSign(Sign s);
|
||||
Expression * setSign(Sign s, Context & context, AngleUnit angleUnit) override {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -25,11 +25,11 @@ private:
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -24,9 +24,9 @@ private:
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Complex */
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Complex<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Complex<T> * templatedApproximate(Context& context, AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -17,9 +17,9 @@ private:
|
||||
virtual ExpressionLayout * createSequenceLayoutWithArgumentLayouts(ExpressionLayout * subscriptLayout, ExpressionLayout * superscriptLayout, ExpressionLayout * argumentLayout) const = 0;
|
||||
virtual const char * name() const = 0;
|
||||
/* Evaluation */
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedApproximate(Context& context, AngleUnit angleUnit) const;
|
||||
virtual int emptySequenceValue() const = 0;
|
||||
virtual Expression * evaluateWithNextTerm(SinglePrecision p, Expression * a, Expression * b) const = 0;
|
||||
virtual Expression * evaluateWithNextTerm(DoublePrecision p, Expression * a, Expression * b) const = 0;
|
||||
|
||||
@@ -23,11 +23,11 @@ public:
|
||||
return nullptr;
|
||||
}
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override { return 0; }
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
assert(false);
|
||||
return nullptr;
|
||||
}
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
assert(false);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
#include <poincare/trigonometry.h>
|
||||
|
||||
namespace Poincare {
|
||||
@@ -27,11 +27,11 @@ private:
|
||||
/* Simplication */
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -20,11 +20,11 @@ private:
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#ifndef POINCARE_STATIC_HIERARCHY_H
|
||||
#define POINCARE_STATIC_HIERARCHY_H
|
||||
|
||||
#include <poincare/hierarchy.h>
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/list_data.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
template<int T>
|
||||
class StaticHierarchy : public Hierarchy {
|
||||
class StaticHierarchy : public Expression {
|
||||
public:
|
||||
StaticHierarchy();
|
||||
StaticHierarchy(const Expression * const * operands, bool cloneOperands = true);
|
||||
|
||||
@@ -18,9 +18,9 @@ private:
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override;
|
||||
/* Evalutation */
|
||||
Expression * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Expression * templatedApproximate(Context& context, AngleUnit angleUnit) const;
|
||||
|
||||
const Symbol * symbol() const { return static_cast<const Symbol *>(operand(1)); }
|
||||
const Expression * value() const { return operand(0); }
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user