mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
Merge branch 'cas_with_app_copy' into python_console
This commit is contained in:
10
.gitignore
vendored
10
.gitignore
vendored
@@ -12,11 +12,11 @@ poincare/src/expression_parser.cpp
|
||||
poincare/src/expression_parser.hpp
|
||||
|
||||
# No rulegen generated files
|
||||
poincare/src/simplify/rules_generation/rules_tokens.h
|
||||
poincare/src/simplify/rules_generation/rules_lexer.cpp
|
||||
poincare/src/simplify/rules_generation/rules_parser.cpp
|
||||
poincare/src/simplify/rules_generation/rulegen
|
||||
poincare/src/simplify/rules.cpp
|
||||
poincare/src/simplification/rulegen/rules_tokens.h
|
||||
poincare/src/simplification/rulegen/rules_lexer.cpp
|
||||
poincare/src/simplification/rulegen/rules_parser.cpp
|
||||
poincare/src/simplification/rulegen/rulegen
|
||||
poincare/src/simplification/demo_ruleset.h
|
||||
|
||||
# Font related generated files.
|
||||
kandinsky/fonts/rasterizer
|
||||
|
||||
@@ -29,7 +29,7 @@ AppsContainer::AppsContainer() :
|
||||
Poincare::Expression::setCircuitBreaker(AppsContainer::poincareCircuitBreaker);
|
||||
}
|
||||
|
||||
bool AppsContainer::poincareCircuitBreaker(const Poincare::Expression * e) {
|
||||
bool AppsContainer::poincareCircuitBreaker() {
|
||||
Ion::Keyboard::State state = Ion::Keyboard::scan();
|
||||
return state.keyDown(Ion::Keyboard::Key::A6);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
class AppsContainer : public Container {
|
||||
public:
|
||||
AppsContainer();
|
||||
static bool poincareCircuitBreaker(const Poincare::Expression * e);
|
||||
static bool poincareCircuitBreaker();
|
||||
virtual int numberOfApps() = 0;
|
||||
virtual App::Snapshot * appSnapshotAtIndex(int index) = 0;
|
||||
App::Snapshot * hardwareTestAppSnapshot();
|
||||
|
||||
@@ -9,7 +9,9 @@ app_objs += $(addprefix apps/calculation/,\
|
||||
history_view_cell.o\
|
||||
history_controller.o\
|
||||
local_context.o\
|
||||
output_expressions_view.o\
|
||||
scrollable_expression_view.o\
|
||||
scrollable_output_expressions_view.o\
|
||||
selectable_table_view.o\
|
||||
text_field.o\
|
||||
)
|
||||
|
||||
@@ -7,11 +7,14 @@ namespace Calculation {
|
||||
|
||||
Calculation::Calculation() :
|
||||
m_inputText(),
|
||||
m_outputText(),
|
||||
m_exactOutputText(),
|
||||
m_approximateOutputText(),
|
||||
m_input(nullptr),
|
||||
m_inputLayout(nullptr),
|
||||
m_output(nullptr),
|
||||
m_outputLayout(nullptr)
|
||||
m_exactOutput(nullptr),
|
||||
m_exactOutputLayout(nullptr),
|
||||
m_approximateOutput(nullptr),
|
||||
m_approximateOutputLayout(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -24,37 +27,51 @@ Calculation::~Calculation() {
|
||||
delete m_input;
|
||||
m_input = nullptr;
|
||||
}
|
||||
if (m_output != nullptr) {
|
||||
delete m_output;
|
||||
m_output = nullptr;
|
||||
if (m_exactOutput != nullptr) {
|
||||
delete m_exactOutput;
|
||||
m_exactOutput = nullptr;
|
||||
}
|
||||
if (m_outputLayout != nullptr) {
|
||||
delete m_outputLayout;
|
||||
m_outputLayout = nullptr;
|
||||
if (m_exactOutputLayout != nullptr) {
|
||||
delete m_exactOutputLayout;
|
||||
m_exactOutputLayout = nullptr;
|
||||
}
|
||||
if (m_approximateOutput != nullptr) {
|
||||
delete m_approximateOutput;
|
||||
m_approximateOutput = nullptr;
|
||||
}
|
||||
if (m_approximateOutputLayout != nullptr) {
|
||||
delete m_approximateOutputLayout;
|
||||
m_approximateOutputLayout = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Calculation& Calculation::operator=(const Calculation& other) {
|
||||
const char * otherInputText = other.m_inputText;
|
||||
const char * otherOutputText = other.m_outputText;
|
||||
const char * otherExactOutputText = other.m_exactOutputText;
|
||||
const char * otherApproximateOutputText = other.m_approximateOutputText;
|
||||
reset();
|
||||
strlcpy(m_inputText, otherInputText, sizeof(m_inputText));
|
||||
strlcpy(m_outputText, otherOutputText, sizeof(m_outputText));
|
||||
strlcpy(m_exactOutputText, otherExactOutputText, sizeof(m_exactOutputText));
|
||||
strlcpy(m_approximateOutputText, otherApproximateOutputText, sizeof(m_approximateOutputText));
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Calculation::reset() {
|
||||
m_inputText[0] = 0;
|
||||
m_outputText[0] = 0;
|
||||
m_exactOutputText[0] = 0;
|
||||
m_approximateOutputText[0] = 0;
|
||||
tidy();
|
||||
}
|
||||
|
||||
void Calculation::setContent(const char * c, Context * context) {
|
||||
reset();
|
||||
strlcpy(m_inputText, c, sizeof(m_inputText));
|
||||
Evaluation<double> * evaluation = input()->evaluate<double>(*context);
|
||||
evaluation->writeTextInBuffer(m_outputText, sizeof(m_outputText));
|
||||
delete evaluation;
|
||||
m_input = Expression::parse(c);
|
||||
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->writeTextInBuffer(m_approximateOutputText, sizeof(m_approximateOutputText));
|
||||
}
|
||||
|
||||
const char * Calculation::inputText() {
|
||||
@@ -62,7 +79,18 @@ const char * Calculation::inputText() {
|
||||
}
|
||||
|
||||
const char * Calculation::outputText() {
|
||||
return m_outputText;
|
||||
if (shouldApproximateOutput()) {
|
||||
return m_approximateOutputText;
|
||||
}
|
||||
return m_exactOutputText;
|
||||
}
|
||||
|
||||
const char * Calculation::exactOutputText() {
|
||||
return m_exactOutputText;
|
||||
}
|
||||
|
||||
const char * Calculation::approximateOutputText() {
|
||||
return m_approximateOutputText;
|
||||
}
|
||||
|
||||
Expression * Calculation::input() {
|
||||
@@ -79,36 +107,29 @@ ExpressionLayout * Calculation::inputLayout() {
|
||||
return m_inputLayout;
|
||||
}
|
||||
|
||||
Evaluation<double> * Calculation::output(Context * context) {
|
||||
if (m_output == nullptr) {
|
||||
/* To ensure that the expression 'm_output' is a matrix or a complex, we
|
||||
* call 'evaluate'. */
|
||||
Expression * exp = Expression::parse(m_outputText);
|
||||
if (exp != nullptr) {
|
||||
m_output = exp->evaluate<double>(*context);
|
||||
delete exp;
|
||||
} else {
|
||||
m_output = new Complex<double>(Complex<double>::Float(NAN));
|
||||
}
|
||||
Expression * Calculation::output(Context * context) {
|
||||
if (shouldApproximateOutput()) {
|
||||
return approximateOutput(context);
|
||||
}
|
||||
return m_output;
|
||||
return exactOutput(context);
|
||||
}
|
||||
|
||||
ExpressionLayout * Calculation::outputLayout(Context * context) {
|
||||
if (m_outputLayout == nullptr && output(context) != nullptr) {
|
||||
m_outputLayout = output(context)->createLayout();
|
||||
if (shouldApproximateOutput()) {
|
||||
return approximateOutputLayout(context);
|
||||
}
|
||||
return m_outputLayout;
|
||||
return exactOutputLayout(context);
|
||||
}
|
||||
|
||||
bool Calculation::isEmpty() {
|
||||
/* To test if a calculation is empty, we need to test either m_inputText or
|
||||
* m_outputText, the only two fields that are not lazy-loaded. We choose
|
||||
* m_outputText to consider that a calculation being added is still empty
|
||||
* until the end of the method 'setContent'. Indeed, during 'setContent'
|
||||
* method, 'ans' evaluation calls the evaluation of the last calculation
|
||||
* only if the calculation being filled is not taken into account.*/
|
||||
if (strlen(m_outputText) == 0) {
|
||||
* m_exactOutputText or m_approximateOutputText, the only three fields that
|
||||
* are not lazy-loaded. We choose m_exactOutputText to consider that a
|
||||
* calculation being added is still empty until the end of the method
|
||||
* 'setContent'. Indeed, during 'setContent' method, 'ans' evaluation calls
|
||||
* the evaluation of the last calculation only if the calculation being
|
||||
* filled is not taken into account.*/
|
||||
if (strlen(m_approximateOutputText) == 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -123,14 +144,77 @@ void Calculation::tidy() {
|
||||
delete m_inputLayout;
|
||||
}
|
||||
m_inputLayout = nullptr;
|
||||
if (m_output != nullptr) {
|
||||
delete m_output;
|
||||
if (m_exactOutput != nullptr) {
|
||||
delete m_exactOutput;
|
||||
}
|
||||
m_output = nullptr;
|
||||
if (m_outputLayout != nullptr) {
|
||||
delete m_outputLayout;
|
||||
m_exactOutput = nullptr;
|
||||
if (m_exactOutputLayout != nullptr) {
|
||||
delete m_exactOutputLayout;
|
||||
}
|
||||
m_outputLayout = nullptr;
|
||||
m_exactOutputLayout = nullptr;
|
||||
if (m_approximateOutput != nullptr) {
|
||||
delete m_approximateOutput;
|
||||
}
|
||||
m_approximateOutput = nullptr;
|
||||
if (m_approximateOutputLayout != nullptr) {
|
||||
delete m_approximateOutputLayout;
|
||||
}
|
||||
m_approximateOutputLayout = nullptr;
|
||||
}
|
||||
|
||||
Expression * Calculation::exactOutput(Context * context) {
|
||||
if (m_exactOutput == nullptr) {
|
||||
/* To ensure that the expression 'm_exactOutput' is a simplified, we
|
||||
* call 'simplifyAndBeautify'. */
|
||||
m_exactOutput = Expression::parse(m_exactOutputText);
|
||||
if (m_exactOutput != nullptr) {
|
||||
Expression::Simplify(&m_exactOutput, *context);
|
||||
} else {
|
||||
m_exactOutput = new Undefined();
|
||||
}
|
||||
}
|
||||
return m_exactOutput;
|
||||
}
|
||||
|
||||
ExpressionLayout * Calculation::exactOutputLayout(Context * context) {
|
||||
if (m_exactOutputLayout == nullptr && exactOutput(context) != nullptr) {
|
||||
m_exactOutputLayout = exactOutput(context)->createLayout();
|
||||
}
|
||||
return m_exactOutputLayout;
|
||||
}
|
||||
|
||||
Expression * Calculation::approximateOutput(Context * context) {
|
||||
if (m_approximateOutput == nullptr) {
|
||||
/* To ensure that the expression 'm_output' is a matrix or a complex, we
|
||||
* call 'evaluate'. */
|
||||
Expression * exp = Expression::parse(m_approximateOutputText);
|
||||
if (exp != nullptr) {
|
||||
m_approximateOutput = exp->evaluate<double>(*context);
|
||||
delete exp;
|
||||
} else {
|
||||
m_approximateOutput = new Complex<double>(Complex<double>::Float(NAN));
|
||||
}
|
||||
}
|
||||
return m_approximateOutput;
|
||||
}
|
||||
|
||||
ExpressionLayout * Calculation::approximateOutputLayout(Context * context) {
|
||||
if (m_approximateOutputLayout == nullptr && approximateOutput(context) != nullptr) {
|
||||
m_approximateOutputLayout = approximateOutput(context)->createLayout();
|
||||
}
|
||||
return m_approximateOutputLayout;
|
||||
}
|
||||
|
||||
bool Calculation::shouldApproximateOutput() {
|
||||
if (strcmp(m_exactOutputText, m_approximateOutputText) == 0) {
|
||||
return true;
|
||||
}
|
||||
if (strcmp(m_exactOutputText, m_inputText) == 0) {
|
||||
return true;
|
||||
}
|
||||
return input()->recursivelyMatches([](const Expression * e) {
|
||||
return e->type() == Expression::Type::Decimal || Expression::IsMatrix(e);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,22 +16,32 @@ public:
|
||||
Calculation& operator=(Calculation&& other) = delete;
|
||||
/* c.reset() is the equivalent of c = Calculation() without copy assingment. */
|
||||
void reset();
|
||||
void setContent(const char * c, Poincare::Context * context);
|
||||
const char * inputText();
|
||||
const char * outputText();
|
||||
const char * exactOutputText();
|
||||
const char * approximateOutputText();
|
||||
Poincare::Expression * input();
|
||||
Poincare::ExpressionLayout * inputLayout();
|
||||
Poincare::Evaluation<double> * output(Poincare::Context * context);
|
||||
Poincare::Expression * output(Poincare::Context * context);
|
||||
Poincare::Expression * approximateOutput(Poincare::Context * context);
|
||||
Poincare::ExpressionLayout * outputLayout(Poincare::Context * context);
|
||||
void setContent(const char * c, Poincare::Context * context);
|
||||
Poincare::ExpressionLayout * exactOutputLayout(Poincare::Context * context);
|
||||
Poincare::ExpressionLayout * approximateOutputLayout(Poincare::Context * context);
|
||||
bool isEmpty();
|
||||
void tidy();
|
||||
bool shouldApproximateOutput();
|
||||
private:
|
||||
Poincare::Expression * exactOutput(Poincare::Context * context);
|
||||
char m_inputText[::TextField::maxBufferSize()];
|
||||
char m_outputText[2*::TextField::maxBufferSize()];
|
||||
char m_exactOutputText[2*::TextField::maxBufferSize()];
|
||||
char m_approximateOutputText[2*::TextField::maxBufferSize()];
|
||||
Poincare::Expression * m_input;
|
||||
Poincare::ExpressionLayout * m_inputLayout;
|
||||
Poincare::Evaluation<double> * m_output;
|
||||
Poincare::ExpressionLayout * m_outputLayout;
|
||||
Poincare::Expression * m_exactOutput;
|
||||
Poincare::ExpressionLayout * m_exactOutputLayout;
|
||||
Poincare::Expression * m_approximateOutput;
|
||||
Poincare::ExpressionLayout * m_approximateOutputLayout;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -47,7 +47,12 @@ bool HistoryController::handleEvent(Ion::Events::Event event) {
|
||||
if (subviewType == HistoryViewCell::SubviewType::Input) {
|
||||
editController->insertTextBody(calculation->inputText());
|
||||
} else {
|
||||
editController->insertTextBody(calculation->outputText());
|
||||
OutputExpressionsView::SubviewType outputSubviewType = selectedCell->outputView()->selectedSubviewType();
|
||||
if (outputSubviewType == OutputExpressionsView::SubviewType::ExactOutput) {
|
||||
editController->insertTextBody(calculation->exactOutputText());
|
||||
} else {
|
||||
editController->insertTextBody(calculation->approximateOutputText());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -97,7 +102,12 @@ bool HistoryController::handleEvent(Ion::Events::Event event) {
|
||||
if (subviewType == HistoryViewCell::SubviewType::Input) {
|
||||
Clipboard::sharedClipboard()->store(calculation->inputText());
|
||||
} else {
|
||||
Clipboard::sharedClipboard()->store(calculation->outputText());
|
||||
OutputExpressionsView::SubviewType outputSubviewType = selectedCell->outputView()->selectedSubviewType();
|
||||
if (outputSubviewType == OutputExpressionsView::SubviewType::ExactOutput) {
|
||||
Clipboard::sharedClipboard()->store(calculation->exactOutputText());
|
||||
} else {
|
||||
Clipboard::sharedClipboard()->store(calculation->approximateOutputText());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -109,14 +119,12 @@ void HistoryController::tableViewDidChangeSelection(SelectableTableView * t, int
|
||||
if (selectedCell == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (selectedRow() < previousSelectedCellY) {
|
||||
selectedCell->setSelectedSubviewType(HistoryViewCell::SubviewType::Output);
|
||||
}
|
||||
if (selectedRow() >= previousSelectedCellY) {
|
||||
selectedCell->setSelectedSubviewType(HistoryViewCell::SubviewType::Input);
|
||||
}
|
||||
if (previousSelectedCellY == -1) {
|
||||
selectedCell->setSelectedSubviewType(HistoryViewCell::SubviewType::Output);
|
||||
} else if (selectedRow() < previousSelectedCellY) {
|
||||
selectedCell->setSelectedSubviewType(HistoryViewCell::SubviewType::Output);
|
||||
} else if (selectedRow() > previousSelectedCellY) {
|
||||
selectedCell->setSelectedSubviewType(HistoryViewCell::SubviewType::Input);
|
||||
}
|
||||
app()->setFirstResponder(selectedCell);
|
||||
selectedCell->reloadCell();
|
||||
@@ -142,6 +150,7 @@ void HistoryController::willDisplayCellForIndex(HighlightCell * cell, int index)
|
||||
HistoryViewCell * myCell = (HistoryViewCell *)cell;
|
||||
myCell->setCalculation(m_calculationStore->calculationAtIndex(index));
|
||||
myCell->setEven(index%2 == 0);
|
||||
myCell->reloadCell();
|
||||
}
|
||||
|
||||
KDCoordinate HistoryController::rowHeight(int j) {
|
||||
@@ -151,7 +160,9 @@ KDCoordinate HistoryController::rowHeight(int j) {
|
||||
Calculation * calculation = m_calculationStore->calculationAtIndex(j);
|
||||
KDCoordinate inputHeight = calculation->inputLayout()->size().height();
|
||||
App * calculationApp = (App *)app();
|
||||
KDCoordinate outputHeight = calculation->outputLayout(calculationApp->localContext())->size().height();
|
||||
KDCoordinate exactOutputHeight = calculation->exactOutputLayout(calculationApp->localContext())->size().height();
|
||||
KDCoordinate approximateOutputHeight = calculation->approximateOutputLayout(calculationApp->localContext())->size().height();
|
||||
KDCoordinate outputHeight = calculation->shouldApproximateOutput() || approximateOutputHeight > exactOutputHeight ? approximateOutputHeight : exactOutputHeight;
|
||||
return inputHeight + outputHeight + 3*HistoryViewCell::k_digitVerticalMargin;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,11 +10,46 @@ namespace Calculation {
|
||||
HistoryViewCell::HistoryViewCell(Responder * parentResponder) :
|
||||
Responder(parentResponder),
|
||||
m_inputView(this),
|
||||
m_outputView(this),
|
||||
m_scrollableOutputView(this),
|
||||
m_selectedSubviewType(HistoryViewCell::SubviewType::Output)
|
||||
{
|
||||
}
|
||||
|
||||
OutputExpressionsView * HistoryViewCell::outputView() {
|
||||
return m_scrollableOutputView.outputView();
|
||||
|
||||
}
|
||||
void HistoryViewCell::setEven(bool even) {
|
||||
EvenOddCell::setEven(even);
|
||||
m_inputView.setBackgroundColor(backgroundColor());
|
||||
m_scrollableOutputView.outputView()->setEven(even);
|
||||
}
|
||||
|
||||
void HistoryViewCell::setHighlighted(bool highlight) {
|
||||
m_highlighted = highlight;
|
||||
m_inputView.setBackgroundColor(backgroundColor());
|
||||
m_scrollableOutputView.outputView()->setHighlighted(false);
|
||||
if (isHighlighted()) {
|
||||
if (m_selectedSubviewType == SubviewType::Input) {
|
||||
m_inputView.setBackgroundColor(Palette::Select);
|
||||
} else {
|
||||
m_scrollableOutputView.outputView()->setHighlighted(true);
|
||||
}
|
||||
}
|
||||
reloadScroll();
|
||||
}
|
||||
|
||||
void HistoryViewCell::reloadCell() {
|
||||
m_scrollableOutputView.outputView()->reloadCell();
|
||||
layoutSubviews();
|
||||
reloadScroll();
|
||||
}
|
||||
|
||||
void HistoryViewCell::reloadScroll() {
|
||||
m_inputView.reloadScroll();
|
||||
m_scrollableOutputView.reloadScroll();
|
||||
}
|
||||
|
||||
KDColor HistoryViewCell::backgroundColor() const {
|
||||
KDColor background = m_even ? Palette::WallScreen : KDColorWhite;
|
||||
return background;
|
||||
@@ -26,7 +61,7 @@ int HistoryViewCell::numberOfSubviews() const {
|
||||
}
|
||||
|
||||
View * HistoryViewCell::subviewAtIndex(int index) {
|
||||
View * views[2] = {&m_inputView, &m_outputView};
|
||||
View * views[2] = {&m_inputView, &m_scrollableOutputView};
|
||||
return views[index];
|
||||
}
|
||||
|
||||
@@ -39,41 +74,29 @@ void HistoryViewCell::layoutSubviews() {
|
||||
} else {
|
||||
m_inputView.setFrame(KDRect(Metric::HistoryHorizontalMargin, k_digitVerticalMargin, inputSize.width(), inputSize.height()));
|
||||
}
|
||||
KDSize outputSize = m_outputView.minimalSizeForOptimalDisplay();
|
||||
KDSize outputSize = m_scrollableOutputView.minimalSizeForOptimalDisplay();
|
||||
if (outputSize.width() + Metric::HistoryHorizontalMargin > width) {
|
||||
m_outputView.setFrame(KDRect(Metric::HistoryHorizontalMargin, inputSize.height() + 2*k_digitVerticalMargin, width - Metric::HistoryHorizontalMargin, height - inputSize.height() - 3*k_digitVerticalMargin));
|
||||
m_scrollableOutputView.setFrame(KDRect(Metric::HistoryHorizontalMargin, inputSize.height() + 2*k_digitVerticalMargin, width - Metric::HistoryHorizontalMargin, height - inputSize.height() - 3*k_digitVerticalMargin));
|
||||
} else {
|
||||
m_outputView.setFrame(KDRect(width - outputSize.width() - Metric::HistoryHorizontalMargin, inputSize.height() + 2*k_digitVerticalMargin, outputSize.width(), height - inputSize.height() - 3*k_digitVerticalMargin));
|
||||
m_scrollableOutputView.setFrame(KDRect(width - outputSize.width() - Metric::HistoryHorizontalMargin, inputSize.height() + 2*k_digitVerticalMargin, outputSize.width(), height - inputSize.height() - 3*k_digitVerticalMargin));
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryViewCell::setCalculation(Calculation * calculation) {
|
||||
m_inputView.setExpression(calculation->inputLayout());
|
||||
App * calculationApp = (App *)app();
|
||||
m_outputView.setExpression(calculation->outputLayout(calculationApp->localContext()));
|
||||
}
|
||||
|
||||
void HistoryViewCell::reloadCell() {
|
||||
m_outputView.setBackgroundColor(backgroundColor());
|
||||
m_inputView.setBackgroundColor(backgroundColor());
|
||||
if (isHighlighted()) {
|
||||
if (m_selectedSubviewType == SubviewType::Output) {
|
||||
m_outputView.setBackgroundColor(Palette::Select);
|
||||
} else {
|
||||
m_inputView.setBackgroundColor(Palette::Select);
|
||||
}
|
||||
}
|
||||
layoutSubviews();
|
||||
EvenOddCell::reloadCell();
|
||||
m_inputView.reloadScroll();
|
||||
m_outputView.reloadScroll();
|
||||
/* Both output expressions have to be updated at the same time. The
|
||||
* outputView points to deleted layouts and a call to
|
||||
* outputView()->layoutSubviews() is going to fail. */
|
||||
Poincare::ExpressionLayout * outputExpressions[2] = {calculation->approximateOutputLayout(calculationApp->localContext()), calculation->shouldApproximateOutput() ? nullptr : calculation->exactOutputLayout(calculationApp->localContext())};
|
||||
m_scrollableOutputView.outputView()->setExpressions(outputExpressions);
|
||||
}
|
||||
|
||||
void HistoryViewCell::didBecomeFirstResponder() {
|
||||
if (m_selectedSubviewType == SubviewType::Input) {
|
||||
app()->setFirstResponder(&m_inputView);
|
||||
} else {
|
||||
app()->setFirstResponder(&m_outputView);
|
||||
app()->setFirstResponder(&m_scrollableOutputView);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,6 +106,7 @@ HistoryViewCell::SubviewType HistoryViewCell::selectedSubviewType() {
|
||||
|
||||
void HistoryViewCell::setSelectedSubviewType(HistoryViewCell::SubviewType subviewType) {
|
||||
m_selectedSubviewType = subviewType;
|
||||
setHighlighted(isHighlighted());
|
||||
}
|
||||
|
||||
bool HistoryViewCell::handleEvent(Ion::Events::Event event) {
|
||||
@@ -94,7 +118,6 @@ bool HistoryViewCell::handleEvent(Ion::Events::Event event) {
|
||||
HistoryViewCell * selectedCell = (HistoryViewCell *)(tableView->selectedCell());
|
||||
selectedCell->setSelectedSubviewType(otherSubviewType);
|
||||
app()->setFirstResponder(selectedCell);
|
||||
selectedCell->reloadCell();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <escher.h>
|
||||
#include "calculation.h"
|
||||
#include "scrollable_expression_view.h"
|
||||
#include "scrollable_output_expressions_view.h"
|
||||
|
||||
namespace Calculation {
|
||||
|
||||
@@ -15,6 +16,9 @@ public:
|
||||
};
|
||||
HistoryViewCell(Responder * parentResponder);
|
||||
void reloadCell() override;
|
||||
void reloadScroll();
|
||||
void setEven(bool even) override;
|
||||
void setHighlighted(bool highlight) override;
|
||||
KDColor backgroundColor() const override;
|
||||
void setCalculation(Calculation * calculation);
|
||||
int numberOfSubviews() const override;
|
||||
@@ -25,10 +29,11 @@ public:
|
||||
constexpr static KDCoordinate k_digitVerticalMargin = 5;
|
||||
SubviewType selectedSubviewType();
|
||||
void setSelectedSubviewType(HistoryViewCell::SubviewType subviewType);
|
||||
OutputExpressionsView * outputView();
|
||||
private:
|
||||
constexpr static KDCoordinate k_resultWidth = 80;
|
||||
ScrollableExpressionView m_inputView;
|
||||
ScrollableExpressionView m_outputView;
|
||||
ScrollableOutputExpressionsView m_scrollableOutputView;
|
||||
SubviewType m_selectedSubviewType;
|
||||
};
|
||||
|
||||
|
||||
@@ -10,17 +10,17 @@ LocalContext::LocalContext(GlobalContext * parentContext, CalculationStore * cal
|
||||
{
|
||||
}
|
||||
|
||||
Evaluation<double> * LocalContext::ansValue() {
|
||||
Expression * LocalContext::ansValue() {
|
||||
if (m_calculationStore->numberOfCalculations() == 0) {
|
||||
return m_parentContext->defaultExpression();
|
||||
}
|
||||
Calculation * lastCalculation = m_calculationStore->calculationAtIndex(m_calculationStore->numberOfCalculations()-1);
|
||||
return lastCalculation->output(m_parentContext);
|
||||
return lastCalculation->approximateOutput(m_parentContext);
|
||||
}
|
||||
|
||||
void LocalContext::setExpressionForSymbolName(Expression * expression, const Symbol * symbol) {
|
||||
void LocalContext::setExpressionForSymbolName(const Expression * expression, const Symbol * symbol, Context & context) {
|
||||
if (symbol->name() != Symbol::SpecialSymbols::Ans) {
|
||||
m_parentContext->setExpressionForSymbolName(expression, symbol);
|
||||
m_parentContext->setExpressionForSymbolName(expression, symbol, context);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,10 +9,10 @@ namespace Calculation {
|
||||
class LocalContext : public Poincare::Context {
|
||||
public:
|
||||
LocalContext(Poincare::GlobalContext * parentContext, CalculationStore * calculationStore);
|
||||
void setExpressionForSymbolName(Poincare::Expression * expression, const Poincare::Symbol * symbol) override;
|
||||
void setExpressionForSymbolName(const Poincare::Expression * expression, const Poincare::Symbol * symbol, Context & context) override;
|
||||
const Poincare::Expression * expressionForSymbol(const Poincare::Symbol * symbol) override;
|
||||
private:
|
||||
Poincare::Evaluation<double> * ansValue();
|
||||
Poincare::Expression * ansValue();
|
||||
CalculationStore * m_calculationStore;
|
||||
Poincare::GlobalContext * m_parentContext;
|
||||
};
|
||||
|
||||
125
apps/calculation/output_expressions_view.cpp
Normal file
125
apps/calculation/output_expressions_view.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
#include "output_expressions_view.h"
|
||||
#include "scrollable_output_expressions_view.h"
|
||||
#include "../i18n.h"
|
||||
#include <assert.h>
|
||||
using namespace Poincare;
|
||||
|
||||
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_exactExpressionView(),
|
||||
m_selectedSubviewType(OutputExpressionsView::SubviewType::ExactOutput)
|
||||
{
|
||||
}
|
||||
|
||||
void OutputExpressionsView::setExpressions(ExpressionLayout ** expressionsLayout) {
|
||||
m_approximateExpressionView.setExpression(expressionsLayout[0]);
|
||||
m_exactExpressionView.setExpression(expressionsLayout[1]);
|
||||
layoutSubviews();
|
||||
}
|
||||
|
||||
void OutputExpressionsView::setHighlighted(bool highlight) {
|
||||
// Do not call HighlightCell::setHighlighted to avoid marking all cell as dirty
|
||||
m_highlighted = highlight;
|
||||
m_exactExpressionView.setBackgroundColor(backgroundColor());
|
||||
m_approximateExpressionView.setBackgroundColor(backgroundColor());
|
||||
if (highlight) {
|
||||
if (m_selectedSubviewType == SubviewType::ExactOutput) {
|
||||
m_exactExpressionView.setBackgroundColor(Palette::Select);
|
||||
} else {
|
||||
m_approximateExpressionView.setBackgroundColor(Palette::Select);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KDColor OutputExpressionsView::backgroundColor() const {
|
||||
KDColor background = m_even ? Palette::WallScreen : KDColorWhite;
|
||||
return background;
|
||||
}
|
||||
|
||||
void OutputExpressionsView::reloadCell() {
|
||||
setHighlighted(isHighlighted());
|
||||
m_approximateSign.setBackgroundColor(backgroundColor());
|
||||
if (numberOfSubviews() == 1) {
|
||||
m_approximateExpressionView.setTextColor(KDColorBlack);
|
||||
} else {
|
||||
m_approximateExpressionView.setTextColor(Palette::GreyDark);
|
||||
}
|
||||
layoutSubviews();
|
||||
}
|
||||
|
||||
KDSize OutputExpressionsView::minimalSizeForOptimalDisplay() const {
|
||||
KDSize approximateExpressionSize = m_approximateExpressionView.minimalSizeForOptimalDisplay();
|
||||
if (numberOfSubviews() == 1) {
|
||||
return approximateExpressionSize;
|
||||
}
|
||||
KDSize exactExpressionSize = m_exactExpressionView.minimalSizeForOptimalDisplay();
|
||||
KDSize approximateSignSize = m_approximateSign.minimalSizeForOptimalDisplay();
|
||||
return KDSize(exactExpressionSize.width()+approximateSignSize.width()+approximateExpressionSize.width()+2*k_digitHorizontalMargin, exactExpressionSize.height() > approximateExpressionSize.height() ? exactExpressionSize.height() : approximateExpressionSize.height());
|
||||
}
|
||||
|
||||
void OutputExpressionsView::didBecomeFirstResponder() {
|
||||
if (numberOfSubviews() == 1) {
|
||||
setSelectedSubviewType(SubviewType::ApproximativeOutput);
|
||||
} else {
|
||||
setSelectedSubviewType(SubviewType::ExactOutput);
|
||||
}
|
||||
}
|
||||
|
||||
bool OutputExpressionsView::handleEvent(Ion::Events::Event event) {
|
||||
if (numberOfSubviews() == 1) {
|
||||
return false;
|
||||
}
|
||||
ScrollableOutputExpressionsView * scrollResponder = static_cast<ScrollableOutputExpressionsView *>(parentResponder());
|
||||
KDCoordinate offset = scrollResponder->manualScrollingOffset().x();
|
||||
bool rightExpressionIsVisible = minimalSizeForOptimalDisplay().width() - m_approximateExpressionView.minimalSizeForOptimalDisplay().width() - offset < scrollResponder->bounds().width()
|
||||
;
|
||||
bool leftExpressionIsVisible = m_exactExpressionView.minimalSizeForOptimalDisplay().width() - offset < scrollResponder->bounds().width();
|
||||
if ((event == Ion::Events::Right && m_selectedSubviewType == SubviewType::ExactOutput && rightExpressionIsVisible) ||
|
||||
(event == Ion::Events::Left && m_selectedSubviewType == SubviewType::ApproximativeOutput && leftExpressionIsVisible)) {
|
||||
SubviewType otherSubviewType = m_selectedSubviewType == SubviewType::ExactOutput ? SubviewType::ApproximativeOutput : SubviewType::ExactOutput;
|
||||
setSelectedSubviewType(otherSubviewType);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
OutputExpressionsView::SubviewType OutputExpressionsView::selectedSubviewType() {
|
||||
return m_selectedSubviewType;
|
||||
}
|
||||
|
||||
void OutputExpressionsView::setSelectedSubviewType(OutputExpressionsView::SubviewType subviewType) {
|
||||
m_selectedSubviewType = subviewType;
|
||||
setHighlighted(isHighlighted());
|
||||
}
|
||||
|
||||
int OutputExpressionsView::numberOfSubviews() const {
|
||||
if (m_exactExpressionView.expressionLayout() != nullptr) {
|
||||
return 3;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
View * OutputExpressionsView::subviewAtIndex(int index) {
|
||||
View * views[3] = {&m_approximateExpressionView, &m_approximateSign, &m_exactExpressionView};
|
||||
return views[index];
|
||||
}
|
||||
|
||||
void OutputExpressionsView::layoutSubviews() {
|
||||
KDCoordinate height = bounds().height();
|
||||
KDSize approximateExpressionSize = m_approximateExpressionView.minimalSizeForOptimalDisplay();
|
||||
if (numberOfSubviews() == 1) {
|
||||
m_approximateExpressionView.setFrame(KDRect(0, 0, approximateExpressionSize.width(), height));
|
||||
return;
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
}
|
||||
37
apps/calculation/output_expressions_view.h
Normal file
37
apps/calculation/output_expressions_view.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef CALCULATION_OUTPUT_EXPRESSIONS_VIEW_H
|
||||
#define CALCULATION_OUTPUT_EXPRESSIONS_VIEW_H
|
||||
|
||||
#include <escher.h>
|
||||
|
||||
namespace Calculation {
|
||||
|
||||
class OutputExpressionsView : public EvenOddCell, public Responder {
|
||||
public:
|
||||
enum class SubviewType {
|
||||
ExactOutput,
|
||||
ApproximativeOutput
|
||||
};
|
||||
OutputExpressionsView(Responder * parentResponder);
|
||||
void setExpressions(Poincare::ExpressionLayout ** expressionsLayout);
|
||||
KDColor backgroundColor() const override;
|
||||
void setHighlighted(bool highlight) override;
|
||||
void reloadCell() override;
|
||||
KDSize minimalSizeForOptimalDisplay() const override;
|
||||
void didBecomeFirstResponder() override;
|
||||
bool handleEvent(Ion::Events::Event event) override;
|
||||
SubviewType selectedSubviewType();
|
||||
void setSelectedSubviewType(SubviewType subviewType);
|
||||
private:
|
||||
int numberOfSubviews() const override;
|
||||
View * subviewAtIndex(int index) override;
|
||||
void layoutSubviews() override;
|
||||
constexpr static KDCoordinate k_digitHorizontalMargin = 10;
|
||||
ExpressionView m_approximateExpressionView;
|
||||
MessageTextView m_approximateSign;
|
||||
ExpressionView m_exactExpressionView;
|
||||
SubviewType m_selectedSubviewType;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
29
apps/calculation/scrollable_output_expressions_view.cpp
Normal file
29
apps/calculation/scrollable_output_expressions_view.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#include "scrollable_output_expressions_view.h"
|
||||
#include <assert.h>
|
||||
using namespace Poincare;
|
||||
|
||||
namespace Calculation {
|
||||
|
||||
ScrollableOutputExpressionsView::ScrollableOutputExpressionsView(Responder * parentResponder) :
|
||||
ScrollableView(parentResponder, &m_outputView, this),
|
||||
m_outputView(this)
|
||||
{
|
||||
}
|
||||
|
||||
OutputExpressionsView * ScrollableOutputExpressionsView::outputView() {
|
||||
return &m_outputView;
|
||||
}
|
||||
|
||||
void ScrollableOutputExpressionsView::didBecomeFirstResponder() {
|
||||
app()->setFirstResponder(&m_outputView);
|
||||
}
|
||||
|
||||
KDSize ScrollableOutputExpressionsView::minimalSizeForOptimalDisplay() const {
|
||||
return m_outputView.minimalSizeForOptimalDisplay();
|
||||
}
|
||||
|
||||
KDPoint ScrollableOutputExpressionsView::manualScrollingOffset() const {
|
||||
return m_manualScrollingOffset;
|
||||
}
|
||||
|
||||
}
|
||||
22
apps/calculation/scrollable_output_expressions_view.h
Normal file
22
apps/calculation/scrollable_output_expressions_view.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef CALCULATION_SCROLLABLE_OUTPUT_EXPRESSIONS_VIEW_H
|
||||
#define CALCULATION_SCROLLABLE_OUTPUT_EXPRESSIONS_VIEW_H
|
||||
|
||||
#include <escher.h>
|
||||
#include "output_expressions_view.h"
|
||||
|
||||
namespace Calculation {
|
||||
|
||||
class ScrollableOutputExpressionsView : public ScrollableView, public ScrollViewDataSource {
|
||||
public:
|
||||
ScrollableOutputExpressionsView(Responder * parentResponder);
|
||||
OutputExpressionsView * outputView();
|
||||
void didBecomeFirstResponder() override;
|
||||
KDSize minimalSizeForOptimalDisplay() const override;
|
||||
KDPoint manualScrollingOffset() const;
|
||||
private:
|
||||
OutputExpressionsView m_outputView;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -19,8 +19,7 @@ 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::Derivative derivative;
|
||||
derivative.setArgument(args, 2, true);
|
||||
Poincare::Derivative derivative(args, true);
|
||||
return derivative.approximate<double>(*context);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@ ion_special_characters = {
|
||||
u'λ': "Ion::Charset::SmallLambda",
|
||||
u'μ': "Ion::Charset::SmallMu",
|
||||
u'σ': "Ion::Charset::SmallSigma",
|
||||
u'≤': "Ion::Charset::LessEqual"
|
||||
u'≤': "Ion::Charset::LessEqual",
|
||||
u'≈': "Ion::Charset::AlmostEqual"
|
||||
}
|
||||
|
||||
def ion_char(i18n_letter):
|
||||
|
||||
@@ -286,13 +286,13 @@ T Sequence::templatedEvaluateAtAbscissa(T x, Poincare::Context * context) const
|
||||
return bufferValue<T>(0);
|
||||
}
|
||||
LocalContext<T> subContext = LocalContext<T>(context);
|
||||
Poincare::Symbol nSymbol = Poincare::Symbol(symbol());
|
||||
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);
|
||||
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.setExpressionForSymbolName(&e, &nSymbol, subContext);
|
||||
un = expression()->approximate<T>(subContext);
|
||||
}
|
||||
setBufferValue(un, 0);
|
||||
@@ -315,7 +315,7 @@ T Sequence::templatedEvaluateAtAbscissa(T x, Poincare::Context * context) const
|
||||
return bufferValue<T>(1);
|
||||
}
|
||||
LocalContext<T> subContext = LocalContext<T>(context);
|
||||
Poincare::Symbol nSymbol = Poincare::Symbol(symbol());
|
||||
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);
|
||||
@@ -323,7 +323,7 @@ T Sequence::templatedEvaluateAtAbscissa(T x, Poincare::Context * context) const
|
||||
subContext.setValueForSequenceRank(un, name(), 0);
|
||||
subContext.setValueForSequenceRank(un1, name(), 1);
|
||||
Poincare::Complex<T> e = Poincare::Complex<T>::Float(i);
|
||||
subContext.setExpressionForSymbolName(&e, &nSymbol);
|
||||
subContext.setExpressionForSymbolName(&e, &nSymbol, subContext);
|
||||
un = un1;
|
||||
un1 = expression()->approximate<T>(subContext);
|
||||
}
|
||||
|
||||
@@ -65,3 +65,4 @@ AtanhCommandWithArg = "atanh(x)"
|
||||
Prediction95CommandWithArg = "prediction95(p,n)"
|
||||
PredictionCommandWithArg = "prediction(p,n)"
|
||||
ConfidenceCommandWithArg = "confidence(f,n)"
|
||||
AlmostEqual = "≈"
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "../constant.h"
|
||||
#include "text_field_delegate_app.h"
|
||||
#include <assert.h>
|
||||
#include <cmath>
|
||||
|
||||
using namespace Poincare;
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "../apps_container.h"
|
||||
#include "text_field_delegate_app.h"
|
||||
#include <assert.h>
|
||||
#include <cmath>
|
||||
|
||||
using namespace Poincare;
|
||||
|
||||
|
||||
@@ -102,9 +102,9 @@ bool Function::isEmpty() {
|
||||
template<typename T>
|
||||
T Function::templatedEvaluateAtAbscissa(T x, Poincare::Context * context) const {
|
||||
Poincare::VariableContext<T> variableContext = Poincare::VariableContext<T>(symbol(), context);
|
||||
Poincare::Symbol xSymbol = Poincare::Symbol(symbol());
|
||||
Poincare::Symbol xSymbol(symbol());
|
||||
Poincare::Complex<T> e = Poincare::Complex<T>::Float(x);
|
||||
variableContext.setExpressionForSymbolName(&e, &xSymbol);
|
||||
variableContext.setExpressionForSymbolName(&e, &xSymbol, variableContext);
|
||||
return expression()->approximate<T>(variableContext);
|
||||
}
|
||||
|
||||
|
||||
@@ -126,6 +126,7 @@ void ListController::willDisplayCellAtLocation(HighlightCell * cell, int i, int
|
||||
EvenOddCell * myCell = (EvenOddCell *)cell;
|
||||
myCell->setEven(j%2 == 0);
|
||||
myCell->setHighlighted(i == selectedColumn() && j == selectedRow());
|
||||
myCell->reloadCell();
|
||||
}
|
||||
|
||||
int ListController::numberOfButtons(ButtonRowController::Position position) const {
|
||||
|
||||
@@ -9,8 +9,13 @@ NewFunctionCell::NewFunctionCell(I18n::Message text) :
|
||||
{
|
||||
}
|
||||
|
||||
void NewFunctionCell::reloadCell() {
|
||||
EvenOddCell::reloadCell();
|
||||
void NewFunctionCell::setEven(bool even) {
|
||||
EvenOddCell::setEven(even);
|
||||
m_messageTextView.setBackgroundColor(backgroundColor());
|
||||
}
|
||||
|
||||
void NewFunctionCell::setHighlighted(bool highlight) {
|
||||
EvenOddCell::setHighlighted(highlight);
|
||||
m_messageTextView.setBackgroundColor(backgroundColor());
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@ namespace Shared {
|
||||
class NewFunctionCell : public EvenOddCell {
|
||||
public:
|
||||
NewFunctionCell(I18n::Message text);
|
||||
void reloadCell() override;
|
||||
void setEven(bool even) override;
|
||||
void setHighlighted(bool highlight) override;
|
||||
int numberOfSubviews() const override;
|
||||
View * subviewAtIndex(int index) override;
|
||||
void layoutSubviews() override;
|
||||
|
||||
@@ -79,11 +79,10 @@ bool TextFieldDelegateApp::textFieldShouldFinishEditing(TextField * textField, I
|
||||
bool TextFieldDelegateApp::textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) {
|
||||
if (textField->textFieldShouldFinishEditing(event) && textField->isEditing()) {
|
||||
Expression * exp = Expression::parse(textField->text());
|
||||
bool invalidText = (exp == nullptr || !exp->hasValidNumberOfArguments());
|
||||
if (exp != nullptr) {
|
||||
delete exp;
|
||||
}
|
||||
if (invalidText) {
|
||||
if (exp == nullptr) {
|
||||
textField->app()->displayWarning(I18n::Message::SyntaxError);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -77,12 +77,12 @@ bool VariableBoxController::ContentViewController::handleEvent(Ion::Events::Even
|
||||
}
|
||||
if (event == Ion::Events::Backspace && m_currentPage != Page::RootMenu) {
|
||||
if (m_currentPage == Page::Scalar) {
|
||||
const Symbol symbol = Symbol('A'+selectedRow());
|
||||
m_context->setExpressionForSymbolName(nullptr, &symbol);
|
||||
const Symbol symbol('A'+selectedRow());
|
||||
m_context->setExpressionForSymbolName(nullptr, &symbol, *m_context);
|
||||
}
|
||||
if (m_currentPage == Page::Matrix) {
|
||||
const Symbol symbol = Symbol::matrixSymbol('0'+(char)selectedRow());
|
||||
m_context->setExpressionForSymbolName(nullptr, &symbol);
|
||||
m_context->setExpressionForSymbolName(nullptr, &symbol, *m_context);
|
||||
}
|
||||
m_selectableTableView.reloadData();
|
||||
return true;
|
||||
@@ -137,7 +137,7 @@ void VariableBoxController::ContentViewController::willDisplayCellForIndex(Highl
|
||||
char label[3];
|
||||
putLabelAtIndexInBuffer(index, label);
|
||||
myCell->setLabel(label);
|
||||
const Evaluation<double> * evaluation = expressionForIndex(index);
|
||||
const Expression * evaluation = expressionForIndex(index);
|
||||
if (m_currentPage == Page::Scalar) {
|
||||
myCell->displayExpression(false);
|
||||
char buffer[PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)];
|
||||
@@ -148,11 +148,13 @@ void VariableBoxController::ContentViewController::willDisplayCellForIndex(Highl
|
||||
myCell->displayExpression(true);
|
||||
if (evaluation) {
|
||||
/* TODO: implement list contexts */
|
||||
myCell->setExpression(evaluation);
|
||||
// TODO: handle matrix and scalar!
|
||||
const Matrix * matrixEvaluation = static_cast<const Matrix *>(evaluation);
|
||||
myCell->setExpression(matrixEvaluation);
|
||||
char buffer[2*PrintFloat::bufferSizeForFloatsWithPrecision(2)+1];
|
||||
int numberOfChars = Complex<float>::convertFloatToText(evaluation->numberOfRows(), buffer, PrintFloat::bufferSizeForFloatsWithPrecision(2), 2, Expression::FloatDisplayMode::Decimal);
|
||||
int numberOfChars = Complex<float>::convertFloatToText(matrixEvaluation->numberOfRows(), buffer, PrintFloat::bufferSizeForFloatsWithPrecision(2), 2, Expression::FloatDisplayMode::Decimal);
|
||||
buffer[numberOfChars++] = 'x';
|
||||
Complex<float>::convertFloatToText(evaluation->numberOfColumns(), buffer+numberOfChars, PrintFloat::bufferSizeForFloatsWithPrecision(2), 2, Expression::FloatDisplayMode::Decimal);
|
||||
Complex<float>::convertFloatToText(matrixEvaluation->numberOfColumns(), buffer+numberOfChars, PrintFloat::bufferSizeForFloatsWithPrecision(2), 2, Expression::FloatDisplayMode::Decimal);
|
||||
myCell->setSubtitle(buffer);
|
||||
} else {
|
||||
myCell->setExpression(nullptr);
|
||||
@@ -167,7 +169,7 @@ KDCoordinate VariableBoxController::ContentViewController::rowHeight(int index)
|
||||
if (m_currentPage == Page::Scalar) {
|
||||
return k_leafRowHeight;
|
||||
}
|
||||
const Evaluation<double> * expression = expressionForIndex(index);
|
||||
const Expression * expression = expressionForIndex(index);
|
||||
if (expression) {
|
||||
ExpressionLayout * layout = expression->createLayout();
|
||||
KDCoordinate expressionHeight = layout->size().height();
|
||||
@@ -201,14 +203,14 @@ int VariableBoxController::ContentViewController::typeAtLocation(int i, int j) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const Evaluation<double> * VariableBoxController::ContentViewController::expressionForIndex(int index) {
|
||||
const Expression * VariableBoxController::ContentViewController::expressionForIndex(int index) {
|
||||
if (m_currentPage == Page::Scalar) {
|
||||
const Symbol symbol = Symbol('A'+index);
|
||||
return m_context->evaluationForSymbol(&symbol);
|
||||
return m_context->expressionForSymbol(&symbol);
|
||||
}
|
||||
if (m_currentPage == Page::Matrix) {
|
||||
const Symbol symbol = Symbol::matrixSymbol('0'+(char)index);
|
||||
return m_context->evaluationForSymbol(&symbol);
|
||||
return m_context->expressionForSymbol(&symbol);
|
||||
}
|
||||
#if LIST_VARIABLES
|
||||
if (m_currentPage == Page::List) {
|
||||
|
||||
@@ -56,7 +56,7 @@ private:
|
||||
Page pageAtIndex(int index);
|
||||
void putLabelAtIndexInBuffer(int index, char * buffer);
|
||||
I18n::Message nodeLabelAtIndex(int index);
|
||||
const Poincare::Evaluation<double> * expressionForIndex(int index);
|
||||
const Poincare::Expression * expressionForIndex(int index);
|
||||
|
||||
Poincare::GlobalContext * m_context;
|
||||
TextField * m_textFieldCaller;
|
||||
|
||||
@@ -15,6 +15,7 @@ class ExpressionView : public View {
|
||||
public:
|
||||
ExpressionView(float horizontalAlignment = 0.0f, float verticalAlignment = 0.5f,
|
||||
KDColor textColor = KDColorBlack, KDColor backgroundColor = KDColorWhite);
|
||||
Poincare::ExpressionLayout * expressionLayout() const;
|
||||
void setExpression(Poincare::ExpressionLayout * expressionLayout);
|
||||
void drawRect(KDContext * ctx, KDRect rect) const override;
|
||||
void setBackgroundColor(KDColor backgroundColor);
|
||||
|
||||
@@ -71,7 +71,7 @@ protected:
|
||||
* [[1.234567e-123*e^(1.234567e-123*i), 1.234567e-123*e^(1.234567e-123*i)]]).
|
||||
* In order to be able to record those output text, k_maxBufferSize must be
|
||||
* over 70. */
|
||||
constexpr static int k_maxBufferSize = 100;
|
||||
constexpr static int k_maxBufferSize = 152;
|
||||
private:
|
||||
int numberOfSubviews() const override { return 1; }
|
||||
void layoutSubviews() override;
|
||||
|
||||
@@ -8,8 +8,10 @@ EvenOddCell::EvenOddCell() :
|
||||
}
|
||||
|
||||
void EvenOddCell::setEven(bool even) {
|
||||
if (even != m_even) {
|
||||
m_even = even;
|
||||
reloadCell();
|
||||
}
|
||||
}
|
||||
|
||||
KDColor EvenOddCell::backgroundColor() const {
|
||||
|
||||
@@ -11,19 +11,27 @@ ExpressionView::ExpressionView(float horizontalAlignment, float verticalAlignmen
|
||||
{
|
||||
}
|
||||
|
||||
ExpressionLayout * ExpressionView::expressionLayout() const {
|
||||
return m_expressionLayout;
|
||||
}
|
||||
|
||||
void ExpressionView::setExpression(ExpressionLayout * expressionLayout) {
|
||||
m_expressionLayout = expressionLayout;
|
||||
markRectAsDirty(bounds());
|
||||
}
|
||||
|
||||
void ExpressionView::setBackgroundColor(KDColor backgroundColor) {
|
||||
m_backgroundColor = backgroundColor;
|
||||
markRectAsDirty(bounds());
|
||||
if (m_backgroundColor != backgroundColor) {
|
||||
m_backgroundColor = backgroundColor;
|
||||
markRectAsDirty(bounds());
|
||||
}
|
||||
}
|
||||
|
||||
void ExpressionView::setTextColor(KDColor textColor) {
|
||||
m_textColor = textColor;
|
||||
markRectAsDirty(bounds());
|
||||
if (textColor != m_textColor) {
|
||||
m_textColor = textColor;
|
||||
markRectAsDirty(bounds());
|
||||
}
|
||||
}
|
||||
|
||||
void ExpressionView::setAlignment(float horizontalAlignment, float verticalAlignment) {
|
||||
|
||||
@@ -22,6 +22,9 @@ enum Charset : char {
|
||||
Root = (char)144,
|
||||
LessEqual = (char)145,
|
||||
GreaterEqual = (char)146,
|
||||
MultiplicationSign = (char)147,
|
||||
MiddleDot = (char)148,
|
||||
AlmostEqual = (char)149
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ static constexpr const char k_complexI[2] = {Ion::Charset::IComplex, 0};
|
||||
static constexpr const char k_exponential[5] = {Ion::Charset::Exponential, '^', '(', ')', 0};
|
||||
static constexpr const char k_sto[2] = {Ion::Charset::Sto, 0};
|
||||
static constexpr const char k_exponent[2] = {Ion::Charset::Exponent, 0};
|
||||
static constexpr const char k_multiplicationSign[2] = {Ion::Charset::MultiplicationSign, 0};
|
||||
|
||||
static constexpr EventData s_dataForEvent[4*Event::PageSize] = {
|
||||
// Plain
|
||||
@@ -40,7 +41,7 @@ static constexpr EventData s_dataForEvent[4*Event::PageSize] = {
|
||||
T(k_exponential), T("ln()"), T("log()"), T(k_complexI), T(","), T("^"),
|
||||
T("sin()"), T("cos()"), T("tan()"), T(k_pi), T(k_root), T("^2"),
|
||||
T("7"), T("8"), T("9"), T("("), T(")"), U(),
|
||||
T("4"), T("5"), T("6"), T("*"), T("/"), U(),
|
||||
T("4"), T("5"), T("6"), T(k_multiplicationSign), T("/"), U(),
|
||||
T("1"), T("2"), T("3"), T("+"), T("-"), U(),
|
||||
T("0"), T("."), T(k_exponent), TL(), TL(), U(),
|
||||
// Shift
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
wchar_t codePointForSymbol[NUMBER_OF_SYMBOLS] = {0x222b, 0x0078, 0x0305,
|
||||
0x0079, 0x0305, 0x0393, 0x03a3, 0x03b8, 0x03bb, 0x03bc, 0x03c0, 0x03c3, 0x0456,
|
||||
0x1D07, 0x2032, 0x212e, 0x2192, 0x221A, 0x2264, 0x2265};
|
||||
0x1D07, 0x2032, 0x212e, 0x2192, 0x221A, 0x2264, 0x2265, 0x00D7, 0x00B7, 0x2248};
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#define NUMBER_OF_SYMBOLS 20
|
||||
#define NUMBER_OF_SYMBOLS 23
|
||||
|
||||
extern wchar_t codePointForSymbol[NUMBER_OF_SYMBOLS];
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@ template <class T> struct remove_reference {typedef T type;};
|
||||
template <class T> struct remove_reference<T&> {typedef T type;};
|
||||
template <class T> struct remove_reference<T&&> {typedef T type;};
|
||||
|
||||
template <class T> typename remove_reference<T>::type&& move(T&&) {
|
||||
return a;
|
||||
template <class T> typename remove_reference<T>::type&& move(T&& a) {
|
||||
return (typename remove_reference<T>::type&&)a;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
SFLAGS += -Ipoincare/include
|
||||
|
||||
#include poincare/src/simplify/Makefile
|
||||
#include poincare/src/simplification/Makefile
|
||||
|
||||
objs += $(addprefix poincare/src/,\
|
||||
absolute_value.o\
|
||||
@@ -8,31 +9,32 @@ objs += $(addprefix poincare/src/,\
|
||||
arc_cosine.o\
|
||||
arc_sine.o\
|
||||
arc_tangent.o\
|
||||
binary_operation.o\
|
||||
arithmetic.o\
|
||||
binomial_coefficient.o\
|
||||
bounded_static_hierarchy.o\
|
||||
ceiling.o\
|
||||
complex.o\
|
||||
complex_argument.o\
|
||||
complex_matrix.o\
|
||||
confidence_interval.o\
|
||||
conjugate.o\
|
||||
cosine.o\
|
||||
decimal.o\
|
||||
derivative.o\
|
||||
determinant.o\
|
||||
division.o\
|
||||
division_quotient.o\
|
||||
division_remainder.o\
|
||||
evaluation.o\
|
||||
dynamic_hierarchy.o\
|
||||
evaluation_engine.o\
|
||||
expression.o\
|
||||
expression_lexer.o\
|
||||
expression_parser.o\
|
||||
factorial.o\
|
||||
floor.o\
|
||||
frac_part.o\
|
||||
fraction.o\
|
||||
function.o\
|
||||
expression_matrix.o\
|
||||
global_context.o\
|
||||
great_common_divisor.o\
|
||||
hierarchy.o\
|
||||
hyperbolic_arc_cosine.o\
|
||||
hyperbolic_arc_sine.o\
|
||||
hyperbolic_arc_tangent.o\
|
||||
@@ -42,8 +44,8 @@ objs += $(addprefix poincare/src/,\
|
||||
imaginary_part.o\
|
||||
integer.o\
|
||||
integral.o\
|
||||
layout_engine.o\
|
||||
list_data.o\
|
||||
leaf_expression.o\
|
||||
least_common_multiple.o\
|
||||
logarithm.o\
|
||||
matrix.o\
|
||||
@@ -62,18 +64,24 @@ objs += $(addprefix poincare/src/,\
|
||||
prediction_interval.o\
|
||||
preferences.o\
|
||||
product.o\
|
||||
rational.o\
|
||||
real_part.o\
|
||||
round.o\
|
||||
sequence.o\
|
||||
simplification_engine.o\
|
||||
sine.o\
|
||||
square_root.o\
|
||||
static_hierarchy.o\
|
||||
store.o\
|
||||
subtraction.o\
|
||||
sum.o\
|
||||
symbol.o\
|
||||
tangent.o\
|
||||
trigonometry.o\
|
||||
undefined.o\
|
||||
variable_context.o\
|
||||
)
|
||||
|
||||
objs += $(addprefix poincare/src/layout/,\
|
||||
baseline_relative_layout.o\
|
||||
bracket_layout.o\
|
||||
@@ -93,9 +101,18 @@ 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\
|
||||
fraction.cpp\
|
||||
division.cpp\
|
||||
function.cpp\
|
||||
helper.cpp\
|
||||
integer.cpp\
|
||||
@@ -104,23 +121,8 @@ tests += $(addprefix poincare/test/,\
|
||||
product.cpp\
|
||||
power.cpp\
|
||||
subtraction.cpp\
|
||||
symbol.cpp\
|
||||
trigo.cpp\
|
||||
)
|
||||
|
||||
# tests += $(addprefix poincare/test/,\
|
||||
addition.cpp\
|
||||
float.cpp\
|
||||
fraction.cpp\
|
||||
identity.cpp\
|
||||
integer.cpp\
|
||||
matrix.cpp\
|
||||
product.cpp\
|
||||
power.cpp\
|
||||
simplify_utils.cpp\
|
||||
simplify_addition.cpp\
|
||||
simplify_product.cpp\
|
||||
subtraction.cpp\
|
||||
symbol.cpp\
|
||||
trigo.cpp\
|
||||
)
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ Simplify fractions
|
||||
(x^2+5.x+6)/(x+2) -> x+3
|
||||
Polynomials
|
||||
(x+1)^2-x^2 -> 2*x+1
|
||||
Fractions
|
||||
Divisions
|
||||
(2*x)/(x^2-1) - 1/(x-1) -> 1/(x+1)
|
||||
Functional identities
|
||||
ln(2x) - ln(x) -> ln(2)
|
||||
|
||||
@@ -12,24 +12,21 @@
|
||||
#include <poincare/ceiling.h>
|
||||
#include <poincare/complex.h>
|
||||
#include <poincare/complex_argument.h>
|
||||
#include <poincare/complex_matrix.h>
|
||||
#include <poincare/confidence_interval.h>
|
||||
#include <poincare/conjugate.h>
|
||||
#include <poincare/context.h>
|
||||
#include <poincare/cosine.h>
|
||||
#include <poincare/decimal.h>
|
||||
#include <poincare/derivative.h>
|
||||
#include <poincare/determinant.h>
|
||||
#include <poincare/division.h>
|
||||
#include <poincare/division_quotient.h>
|
||||
#include <poincare/division_remainder.h>
|
||||
#include <poincare/evaluation.h>
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/expression_layout.h>
|
||||
#include <poincare/factorial.h>
|
||||
#include <poincare/floor.h>
|
||||
#include <poincare/frac_part.h>
|
||||
#include <poincare/fraction.h>
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/expression_matrix.h>
|
||||
#include <poincare/global_context.h>
|
||||
#include <poincare/great_common_divisor.h>
|
||||
#include <poincare/hyperbolic_arc_cosine.h>
|
||||
@@ -38,7 +35,6 @@
|
||||
#include <poincare/hyperbolic_cosine.h>
|
||||
#include <poincare/hyperbolic_sine.h>
|
||||
#include <poincare/hyperbolic_tangent.h>
|
||||
#include <poincare/integer.h>
|
||||
#include <poincare/imaginary_part.h>
|
||||
#include <poincare/integral.h>
|
||||
#include <poincare/least_common_multiple.h>
|
||||
@@ -58,6 +54,7 @@
|
||||
#include <poincare/prediction_interval.h>
|
||||
#include <poincare/preferences.h>
|
||||
#include <poincare/product.h>
|
||||
#include <poincare/rational.h>
|
||||
#include <poincare/real_part.h>
|
||||
#include <poincare/round.h>
|
||||
#include <poincare/sine.h>
|
||||
@@ -67,6 +64,7 @@
|
||||
#include <poincare/sum.h>
|
||||
#include <poincare/symbol.h>
|
||||
#include <poincare/tangent.h>
|
||||
#include <poincare/undefined.h>
|
||||
#include <poincare/variable_context.h>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,25 +1,35 @@
|
||||
#ifndef POINCARE_ABSOLUTE_VALUE_H
|
||||
#define POINCARE_ABSOLUTE_VALUE_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class AbsoluteValue : public Function {
|
||||
class AbsoluteValue : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
AbsoluteValue();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
Sign sign() const override { return Sign::Positive; }
|
||||
private:
|
||||
Complex<float> computeComplex(const Complex<float> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c);
|
||||
}
|
||||
Complex<double> computeComplex(const Complex<double> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c);
|
||||
}
|
||||
template<typename T> Complex<T> templatedComputeComplex(const Complex<T> c) const;
|
||||
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::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, "abs");
|
||||
}
|
||||
/* 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 * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,28 +1,56 @@
|
||||
#ifndef POINCARE_ADDITION_H
|
||||
#define POINCARE_ADDITION_H
|
||||
|
||||
#include <poincare/binary_operation.h>
|
||||
#include <poincare/dynamic_hierarchy.h>
|
||||
#include <poincare/rational.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Addition : public BinaryOperation {
|
||||
using BinaryOperation::BinaryOperation;
|
||||
class Addition : public DynamicHierarchy {
|
||||
using DynamicHierarchy::DynamicHierarchy;
|
||||
friend class Logarithm;
|
||||
friend class Multiplication;
|
||||
friend class Subtraction;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression** newOperands,
|
||||
int numnerOfOperands, bool cloneOperands = true) const override;
|
||||
bool isCommutative() const override;
|
||||
Expression * clone() const override;
|
||||
/* Evaluation */
|
||||
template<typename T> static Complex<T> compute(const Complex<T> c, const Complex<T> d);
|
||||
template<typename T> static Evaluation<T> * computeOnMatrices(Evaluation<T> * m, Evaluation<T> * n);
|
||||
template<typename T> static Evaluation<T> * computeOnComplexAndMatrix(const Complex<T> * c, Evaluation<T> * m);
|
||||
template<typename T> static Matrix * computeOnMatrices(const Matrix * m, const Matrix * n) {
|
||||
return EvaluationEngine::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>);
|
||||
}
|
||||
private:
|
||||
Complex<float> privateCompute(const Complex<float> c, const Complex<float> d) const override {
|
||||
return compute(c, d);
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
|
||||
return LayoutEngine::createInfixLayout(this, floatDisplayMode, complexFormat, name());
|
||||
}
|
||||
Complex<double> privateCompute(const Complex<double> c, const Complex<double> d) const override {
|
||||
return compute(c, d);
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writeInfixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
|
||||
static const char * name() { return "+"; }
|
||||
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
Expression * shallowBeautify(Context & context, AngleUnit angleUnit) override;
|
||||
Expression * factorizeOnCommonDenominator(Context & context, AngleUnit angleUnit);
|
||||
void factorizeOperands(Expression * e1, Expression * e2, Context & context, AngleUnit angleUnit);
|
||||
static const Rational RationalFactor(Expression * e);
|
||||
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>);
|
||||
}
|
||||
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 * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::mapReduce<double>(this, context, angleUnit, compute<double>, computeOnComplexAndMatrix<double>, computeOnMatrixAndComplex<double>, computeOnMatrices<double>);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,24 +1,38 @@
|
||||
#ifndef POINCARE_ARC_COSINE_H
|
||||
#define POINCARE_ARC_COSINE_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class ArcCosine : public Function {
|
||||
class ArcCosine : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
ArcCosine();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Complex<float> computeComplex(const Complex<float> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c, angleUnit);
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
|
||||
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
|
||||
}
|
||||
Complex<double> computeComplex(const Complex<double> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c, angleUnit);
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
const char * name() const {
|
||||
return "acos";
|
||||
}
|
||||
/* 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 * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
template<typename T> Complex<T> templatedComputeComplex(const Complex<T> c, AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,24 +1,36 @@
|
||||
#ifndef POINCARE_ARC_SINE_H
|
||||
#define POINCARE_ARC_SINE_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class ArcSine : public Function {
|
||||
class ArcSine : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
ArcSine();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Complex<float> computeComplex(const Complex<float> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c, angleUnit);
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
|
||||
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
|
||||
}
|
||||
Complex<double> computeComplex(const Complex<double> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c, angleUnit);
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
const char * name() const { return "asin"; }
|
||||
/* 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 * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
template<typename T> Complex<T> templatedComputeComplex(const Complex<T> c, AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,24 +1,36 @@
|
||||
#ifndef POINCARE_ARC_TANGENT_H
|
||||
#define POINCARE_ARC_TANGENT_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class ArcTangent: public Function {
|
||||
class ArcTangent : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
ArcTangent();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Complex<float> computeComplex(const Complex<float> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c, angleUnit);
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
|
||||
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
|
||||
}
|
||||
Complex<double> computeComplex(const Complex<double> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c, angleUnit);
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
const char * name() const { return "atan"; }
|
||||
/* 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 * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
template<typename T> Complex<T> templatedComputeComplex(const Complex<T> c, AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
19
poincare/include/poincare/arithmetic.h
Normal file
19
poincare/include/poincare/arithmetic.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef POINCARE_ARITHMETIC_H
|
||||
#define POINCARE_ARITHMETIC_H
|
||||
|
||||
#include <poincare/integer.h>
|
||||
namespace Poincare {
|
||||
|
||||
class Arithmetic {
|
||||
public:
|
||||
static Integer LCM(const Integer * i, const Integer * j);
|
||||
static Integer GCD(const Integer * i, const Integer * j);
|
||||
static void PrimeFactorization(const Integer * i, Integer * outputFactors, Integer * outputCoefficients, int outputLength);
|
||||
constexpr static int k_numberOfPrimeFactors = 1000;
|
||||
constexpr static int k_maxNumberOfPrimeFactors = 32;
|
||||
static const Integer k_primorial32;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,60 +0,0 @@
|
||||
#ifndef POINCARE_BINARY_OPERATION_H
|
||||
#define POINCARE_BINARY_OPERATION_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/matrix.h>
|
||||
#include <poincare/complex.h>
|
||||
#include <poincare/complex_matrix.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class BinaryOperation : public Expression {
|
||||
public:
|
||||
BinaryOperation();
|
||||
BinaryOperation(Expression ** operands, bool cloneOperands = true);
|
||||
~BinaryOperation();
|
||||
BinaryOperation(const BinaryOperation& other) = delete;
|
||||
BinaryOperation(BinaryOperation&& other) = delete;
|
||||
BinaryOperation& operator=(const BinaryOperation& other) = delete;
|
||||
BinaryOperation& operator=(BinaryOperation&& other) = delete;
|
||||
bool hasValidNumberOfArguments() const override;
|
||||
const Expression * operand(int i) const override;
|
||||
int numberOfOperands() const override;
|
||||
Expression * clone() const override;
|
||||
protected:
|
||||
Expression * m_operands[2];
|
||||
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
|
||||
virtual Evaluation<float> * computeOnComplexAndComplexMatrix(const Complex<float> * c, Evaluation<float> * n) const {
|
||||
return templatedComputeOnComplexAndComplexMatrix(c, n);
|
||||
}
|
||||
virtual Evaluation<double> * computeOnComplexAndComplexMatrix(const Complex<double> * c, Evaluation<double> * n) const {
|
||||
return templatedComputeOnComplexAndComplexMatrix(c, n);
|
||||
}
|
||||
template<typename T> Evaluation<T> * templatedComputeOnComplexAndComplexMatrix(const Complex<T> * c, Evaluation<T> * n) const;
|
||||
|
||||
virtual Evaluation<float> * computeOnComplexMatrixAndComplex(Evaluation<float> * m, const Complex<float> * d) const {
|
||||
return templatedComputeOnComplexMatrixAndComplex(m, d);
|
||||
}
|
||||
virtual Evaluation<double> * computeOnComplexMatrixAndComplex(Evaluation<double> * m, const Complex<double> * d) const {
|
||||
return templatedComputeOnComplexMatrixAndComplex(m, d);
|
||||
}
|
||||
template<typename T> Evaluation<T> * templatedComputeOnComplexMatrixAndComplex(Evaluation<T> * m, const Complex<T> * d) const;
|
||||
|
||||
virtual Evaluation<float> * computeOnComplexMatrices(Evaluation<float> * m, Evaluation<float> * n) const {
|
||||
return templatedComputeOnComplexMatrices(m, n);
|
||||
}
|
||||
virtual Evaluation<double> * computeOnComplexMatrices(Evaluation<double> * m, Evaluation<double> * n) const {
|
||||
return templatedComputeOnComplexMatrices(m, n);
|
||||
}
|
||||
template<typename T> Evaluation<T> * templatedComputeOnComplexMatrices(Evaluation<T> * m, Evaluation<T> * n) const;
|
||||
|
||||
virtual Complex<float> privateCompute(const Complex<float> c, const Complex<float> d) const = 0;
|
||||
virtual Complex<double> privateCompute(const Complex<double> c, const Complex<double> d) const = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,21 +1,29 @@
|
||||
#ifndef POINCARE_BINOMIAL_COEFFICIENT_H
|
||||
#define POINCARE_BINOMIAL_COEFFICIENT_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class BinomialCoefficient : public Function {
|
||||
class BinomialCoefficient : public StaticHierarchy<2> {
|
||||
using StaticHierarchy<2>::StaticHierarchy;
|
||||
public:
|
||||
BinomialCoefficient();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
constexpr static int k_maxNValue = 300;
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, "binomial");
|
||||
}
|
||||
/* 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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
24
poincare/include/poincare/bounded_static_hierarchy.h
Normal file
24
poincare/include/poincare/bounded_static_hierarchy.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef POINCARE_BOUNDED_STATIC_HIERARCHY_H
|
||||
#define POINCARE_BOUNDED_STATIC_HIERARCHY_H
|
||||
|
||||
#include <poincare/static_hierarchy.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
template<int T>
|
||||
class BoundedStaticHierarchy : public StaticHierarchy<T> {
|
||||
public:
|
||||
BoundedStaticHierarchy();
|
||||
BoundedStaticHierarchy(const Expression * expression, bool cloneOperands = true); // Specialized constructor for StaticHierarchy<2>
|
||||
BoundedStaticHierarchy(const Expression * expression1, const Expression * expression2, bool cloneOperands = true); // Specialized constructor for StaticHierarchy<2>
|
||||
BoundedStaticHierarchy(const Expression * const * operands, int numberOfOperands, bool cloneOperands = true);
|
||||
void setArgument(ListData * listData, int numberOfEntries, bool clone) override;
|
||||
int numberOfOperands() const override { return m_numberOfOperands; }
|
||||
bool hasValidNumberOfOperands(int numberOfOperands) const override;
|
||||
private:
|
||||
int m_numberOfOperands;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,25 +1,34 @@
|
||||
#ifndef POINCARE_CEILING_H
|
||||
#define POINCARE_CEILING_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Ceiling : public Function {
|
||||
class Ceiling : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Ceiling();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Complex<float> computeComplex(const Complex<float> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c);
|
||||
}
|
||||
Complex<double> computeComplex(const Complex<double> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c);
|
||||
}
|
||||
template<typename T> Complex<T> templatedComputeComplex(const Complex<T> c) const;
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
const char * name() const { return "ceil"; }
|
||||
/* 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 * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#ifndef POINCARE_COMPLEX_H
|
||||
#define POINCARE_COMPLEX_H
|
||||
|
||||
#include <poincare/evaluation.h>
|
||||
#include <poincare/preferences.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <assert.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -22,7 +23,7 @@ namespace PrintFloat {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
class Complex : public Evaluation<T> {
|
||||
class Complex : public StaticHierarchy<0> {
|
||||
public:
|
||||
Complex() : m_a(0), m_b(0) {}
|
||||
static Complex<T> Float(T x);
|
||||
@@ -31,29 +32,21 @@ public:
|
||||
Complex(const char * integralPart, int integralPartLength, bool integralNegative,
|
||||
const char * fractionalPart, int fractionalPartLength,
|
||||
const char * exponent, int exponentLength, bool exponentNegative);
|
||||
T toScalar() const override;
|
||||
const Complex<T> * operand(int i) const override {
|
||||
return complexOperand(i);
|
||||
}
|
||||
int numberOfRows() const override;
|
||||
int numberOfColumns() const override;
|
||||
Expression::Type type() const override;
|
||||
Complex<T> * clone() const override;
|
||||
Evaluation<T> * cloneWithDifferentOperands(Expression** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override;
|
||||
Evaluation<T> * createDeterminant() const override {
|
||||
return clone();
|
||||
}
|
||||
Evaluation<T> * createInverse() const override;
|
||||
Evaluation<T> * createTrace() const override {
|
||||
return clone();
|
||||
}
|
||||
Complex(const Complex & other);
|
||||
Complex& operator=(const Complex& other);
|
||||
|
||||
T a() const;
|
||||
T b() const;
|
||||
T r() const;
|
||||
T th() const;
|
||||
Complex<T> conjugate() const;
|
||||
T toScalar() const;
|
||||
|
||||
/* Expression */
|
||||
Expression::Type type() const override;
|
||||
Complex<T> * clone() const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override;
|
||||
|
||||
/* 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
|
||||
@@ -68,12 +61,11 @@ public:
|
||||
static int convertFloatToText(T d, char * buffer, int bufferSize, int numberOfSignificantDigits, Expression::FloatDisplayMode mode = Expression::FloatDisplayMode::Default);
|
||||
private:
|
||||
Complex(T a, T b);
|
||||
const Complex<T> * complexOperand(int i) const override;
|
||||
constexpr static int k_numberOfSignificantDigits = 7;
|
||||
ExpressionLayout * privateCreateLayout(Expression::FloatDisplayMode floatDisplayMode, Expression::ComplexFormat complexFormat) const override;
|
||||
Evaluation<float> * privateEvaluate(Expression::SinglePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateEvaluate(Expression::DoublePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename U> Evaluation<U> * templatedEvaluate(Context& context, Expression::AngleUnit angleUnit) const;
|
||||
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
|
||||
|
||||
@@ -1,24 +1,36 @@
|
||||
#ifndef POINCARE_COMPLEX_ARGUMENT_H
|
||||
#define POINCARE_COMPLEX_ARGUMENT_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class ComplexArgument : public Function {
|
||||
class ComplexArgument : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
ComplexArgument();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Complex<float> computeComplex(const Complex<float> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c);
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
|
||||
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
|
||||
}
|
||||
Complex<double> computeComplex(const Complex<double> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c);
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
const char * name() const { return "arg"; }
|
||||
/* 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 * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
template<typename T> Complex<T> templatedComputeComplex(const Complex<T> c) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
#ifndef POINCARE_COMPLEX_MATRIX_H
|
||||
#define POINCARE_COMPLEX_MATRIX_H
|
||||
|
||||
#include <poincare/evaluation.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
template<typename T>
|
||||
class ComplexMatrix : public Evaluation<T> {
|
||||
public:
|
||||
ComplexMatrix(const Complex<T> * complexes, int numberOfRows, int numberOfColumns);
|
||||
~ComplexMatrix();
|
||||
ComplexMatrix(const ComplexMatrix& other) = delete;
|
||||
ComplexMatrix(ComplexMatrix&& other) = delete;
|
||||
ComplexMatrix& operator=(const ComplexMatrix& other) = delete;
|
||||
ComplexMatrix& operator=(ComplexMatrix&& other) = delete;
|
||||
T toScalar() const override;
|
||||
const Complex<T> * complexOperand(int i) const override;
|
||||
int numberOfRows() const override;
|
||||
int numberOfColumns() const override;
|
||||
ComplexMatrix<T> * clone() const override;
|
||||
ComplexMatrix<T> * cloneWithDifferentOperands(Expression** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
static Evaluation<T> * createIdentity(int dim);
|
||||
private:
|
||||
Evaluation<float> * privateEvaluate(Expression::SinglePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateEvaluate(Expression::DoublePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename U> Evaluation<U> * templatedEvaluate(Context& context, Expression::AngleUnit angleUnit) const;
|
||||
Complex<T> * m_values;
|
||||
int m_numberOfRows;
|
||||
int m_numberOfColumns;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,20 +1,31 @@
|
||||
#ifndef POINCARE_CONFIDENCE_INTERVAL_H
|
||||
#define POINCARE_CONFIDENCE_INTERVAL_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class ConfidenceInterval : public Function {
|
||||
class ConfidenceInterval : public StaticHierarchy<2> {
|
||||
using StaticHierarchy<2>::StaticHierarchy;
|
||||
public:
|
||||
ConfidenceInterval();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
|
||||
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
|
||||
}
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
const char * name() const { return "confidence"; }
|
||||
/* 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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,25 +1,33 @@
|
||||
#ifndef POINCARE_CONJUGATE_H
|
||||
#define POINCARE_CONJUGATE_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Conjugate : public Function {
|
||||
class Conjugate : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Conjugate();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Complex<float> computeComplex(const Complex<float> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c);
|
||||
}
|
||||
Complex<double> computeComplex(const Complex<double> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c);
|
||||
}
|
||||
template<typename T> Complex<T> templatedComputeComplex(const Complex<T> c) const;
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, "conjugate");
|
||||
}
|
||||
/* 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 * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Poincare {
|
||||
class Context {
|
||||
public:
|
||||
virtual const Expression * expressionForSymbol(const Symbol * symbol) = 0;
|
||||
virtual void setExpressionForSymbolName(Expression * expression, const Symbol * symbol) = 0;
|
||||
virtual void setExpressionForSymbolName(const Expression * expression, const Symbol * symbol, Context & context) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,23 +1,37 @@
|
||||
#ifndef POINCARE_COSINE_H
|
||||
#define POINCARE_COSINE_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/trigonometry.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Cosine : public Function {
|
||||
class Cosine : public StaticHierarchy<1>::StaticHierarchy {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
friend class Tangent;
|
||||
public:
|
||||
Cosine();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
template<typename T> static Complex<T> compute(const Complex<T> c, AngleUnit angleUnit = AngleUnit::Radian);
|
||||
Expression * clone() const override;
|
||||
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit = AngleUnit::Radian);
|
||||
private:
|
||||
Complex<float> computeComplex(const Complex<float> c, AngleUnit angleUnit) const override {
|
||||
return compute(c, angleUnit);
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
|
||||
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
|
||||
}
|
||||
Complex<double> computeComplex(const Complex<double> c, AngleUnit angleUnit) const override {
|
||||
return compute(c, angleUnit);
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
const char * name() const { return "cos"; }
|
||||
/* 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 * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
51
poincare/include/poincare/decimal.h
Normal file
51
poincare/include/poincare/decimal.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#ifndef POINCARE_DECIMAL_H
|
||||
#define POINCARE_DECIMAL_H
|
||||
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/integer.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
/* A decimal as 0.01234 is stored that way:
|
||||
* - m_mantissa = 1234
|
||||
* - m_exponent = -2
|
||||
*/
|
||||
|
||||
class Decimal : public StaticHierarchy<0> {
|
||||
public:
|
||||
static int exponent(const char * integralPart, int integralPartLength, const char * fractionalPart, int fractionalPartLength, const char * exponent, int exponentLength, bool exponentNegative);
|
||||
static Integer mantissa(const char * integralPart, int integralPartLength, const char * fractionalPart, int fractionalPartLength, bool negative);
|
||||
Decimal(Integer mantissa, int exponent);
|
||||
Decimal(double f);
|
||||
int exponent() const { return m_exponent; }
|
||||
Integer mantissa() const { return m_mantissa; }
|
||||
// Expression subclassing
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override;
|
||||
Sign sign() const override { return m_mantissa.isNegative() ? Sign::Negative : Sign::Positive; }
|
||||
private:
|
||||
constexpr static int k_doublePrecision = 15;
|
||||
constexpr static double k_biggestMantissaFromDouble = 999999999999999;
|
||||
constexpr static int k_maxDoubleExponent = 308;
|
||||
int numberOfDigitsInMantissaWithoutSign() const;
|
||||
/* Comparison */
|
||||
int simplificationOrderSameType(const Expression * e) const override;
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
|
||||
/* Simplification */
|
||||
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;
|
||||
|
||||
constexpr static int k_maxLength = 10;
|
||||
Integer m_mantissa;
|
||||
int m_exponent;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,21 +1,32 @@
|
||||
#ifndef POINCARE_DERIVATIVE_H
|
||||
#define POINCARE_DERIVATIVE_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/variable_context.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Derivative : public Function {
|
||||
class Derivative : public StaticHierarchy<2> {
|
||||
using StaticHierarchy<2>::StaticHierarchy;
|
||||
public:
|
||||
Derivative();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
|
||||
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
|
||||
}
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
const char * name() const { return "diff"; }
|
||||
/* 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;
|
||||
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?
|
||||
|
||||
@@ -1,20 +1,32 @@
|
||||
#ifndef POINCARE_DETERMINANT_H
|
||||
#define POINCARE_DETERMINANT_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/complex.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Determinant : public Function {
|
||||
class Determinant : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Determinant();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
|
||||
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
|
||||
}
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
const char * name() const { return "det"; }
|
||||
/* 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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
45
poincare/include/poincare/division.h
Normal file
45
poincare/include/poincare/division.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef POINCARE_DIVISION_H
|
||||
#define POINCARE_DIVISION_H
|
||||
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Division : public StaticHierarchy<2> {
|
||||
using StaticHierarchy<2>::StaticHierarchy;
|
||||
friend class Multiplication;
|
||||
friend class Power;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
template<typename T> static Complex<T> compute(const Complex<T> c, const Complex<T> d);
|
||||
private:
|
||||
/* Layout */
|
||||
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;
|
||||
});
|
||||
}
|
||||
/* 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>);
|
||||
}
|
||||
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 * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::mapReduce<double>(this, context, angleUnit, compute<double>, computeOnComplexAndMatrix<double>, computeOnMatrixAndComplex<double>, computeOnMatrices<double>);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,20 +1,32 @@
|
||||
#ifndef POINCARE_DIVISION_QUOTIENT_H
|
||||
#define POINCARE_DIVISION_QUOTIENT_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/complex.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class DivisionQuotient : public Function {
|
||||
class DivisionQuotient : public StaticHierarchy<2> {
|
||||
using StaticHierarchy<2>::StaticHierarchy;
|
||||
public:
|
||||
DivisionQuotient();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
|
||||
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
|
||||
}
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
const char * name() const { return "quo"; }
|
||||
/* 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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,20 +1,33 @@
|
||||
#ifndef POINCARE_DIVISION_REMAINDER_H
|
||||
#define POINCARE_DIVISION_REMAINDER_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/complex.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class DivisionRemainder : public Function {
|
||||
class DivisionRemainder : public StaticHierarchy<2> {
|
||||
using StaticHierarchy<2>::StaticHierarchy;
|
||||
public:
|
||||
DivisionRemainder();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
|
||||
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
|
||||
}
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
const char * name() const { return "rem"; }
|
||||
/* 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;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
43
poincare/include/poincare/dynamic_hierarchy.h
Normal file
43
poincare/include/poincare/dynamic_hierarchy.h
Normal file
@@ -0,0 +1,43 @@
|
||||
#ifndef POINCARE_DYNAMIC_HIERARCHY_H
|
||||
#define POINCARE_DYNAMIC_HIERARCHY_H
|
||||
|
||||
#include <poincare/hierarchy.h>
|
||||
#include <poincare/rational.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class DynamicHierarchy : public Hierarchy {
|
||||
public:
|
||||
DynamicHierarchy();
|
||||
DynamicHierarchy(const Expression * const * operands, int numberOfOperands, bool cloneOperands = true);
|
||||
DynamicHierarchy(const Expression * operand1, const Expression * operand2, bool cloneOperands = true) :
|
||||
DynamicHierarchy(ExpressionArray(operand1, operand2), 2, cloneOperands) {}
|
||||
~DynamicHierarchy();
|
||||
DynamicHierarchy(const DynamicHierarchy & other) = delete;
|
||||
DynamicHierarchy(DynamicHierarchy && other) = delete;
|
||||
DynamicHierarchy& operator=(const DynamicHierarchy & other) = delete;
|
||||
DynamicHierarchy& operator=(DynamicHierarchy && other) = delete;
|
||||
|
||||
int numberOfOperands() const override { return m_numberOfOperands; }
|
||||
const Expression * const * operands() const override { return m_operands; };
|
||||
|
||||
void removeOperand(const Expression * e, bool deleteAfterRemoval = true);
|
||||
void addOperands(const Expression * const * operands, int numberOfOperands);
|
||||
void addOperand(Expression * operand);
|
||||
void addOperandAtIndex(Expression * operand, int index);
|
||||
void mergeOperands(DynamicHierarchy * d);
|
||||
typedef int (*ExpressionOrder)(const Expression * e1, const Expression * e2);
|
||||
void sortOperands(ExpressionOrder order);
|
||||
Expression * squashUnaryHierarchy();
|
||||
protected:
|
||||
const Expression ** m_operands;
|
||||
int m_numberOfOperands;
|
||||
private:
|
||||
void removeOperandAtIndex(int i, bool deleteAfterRemoval);
|
||||
int simplificationOrderSameType(const Expression * e) const override;
|
||||
int simplificationOrderGreaterType(const Expression * e) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,28 +0,0 @@
|
||||
#ifndef POINCARE_EVALUATION_H
|
||||
#define POINCARE_EVALUATION_H
|
||||
|
||||
#include <poincare/matrix.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
template<class T>
|
||||
class Complex;
|
||||
|
||||
template<typename T>
|
||||
class Evaluation : public Matrix {
|
||||
public:
|
||||
virtual T toScalar() const = 0;
|
||||
Type type() const override;
|
||||
bool hasValidNumberOfArguments() const override;
|
||||
virtual const Expression * operand(int i) const override;
|
||||
virtual const Complex<T> * complexOperand(int i) const = 0;
|
||||
virtual Evaluation<T> * clone() const override = 0;
|
||||
virtual Evaluation<T> * createTrace() const;
|
||||
virtual Evaluation<T> * createDeterminant() const;
|
||||
virtual Evaluation<T> * createInverse() const;
|
||||
Evaluation<T> * createTranspose() const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
28
poincare/include/poincare/evaluation_engine.h
Normal file
28
poincare/include/poincare/evaluation_engine.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef POINCARE_EVALUATION_ENGINE_H
|
||||
#define POINCARE_EVALUATION_ENGINE_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/complex.h>
|
||||
#include <poincare/matrix.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class EvaluationEngine {
|
||||
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);
|
||||
|
||||
template <typename T> using ComplexAndComplexReduction = Complex<T>(*)(const Complex<T>, const Complex<T>);
|
||||
template <typename T> using ComplexAndMatrixReduction = Matrix * (*)(const Complex<T> * c, const Matrix * m);
|
||||
template <typename T> using MatrixAndComplexReduction = Matrix * (*)(const Matrix * m, const Complex<T> * c);
|
||||
template <typename T> using MatrixAndMatrixReduction = Matrix * (*)(const Matrix * m, const Matrix * n);
|
||||
template<typename T> static Expression * mapReduce(const Expression * expression, Context& context, Expression::AngleUnit angleUnit, ComplexAndComplexReduction<T> computeOnComplexes, ComplexAndMatrixReduction<T> computeOnComplexAndMatrix, MatrixAndComplexReduction<T> computeOnMatrixAndComplex, MatrixAndMatrixReduction<T> computeOnMatrices);
|
||||
|
||||
template<typename T> static Matrix * elementWiseOnComplexAndComplexMatrix(const Complex<T> * c, const Matrix * n, ComplexAndComplexReduction<T> computeOnComplexes);
|
||||
template<typename T> static Matrix * elementWiseOnComplexMatrices(const Matrix * m, const Matrix * n, ComplexAndComplexReduction<T> computeOnComplexes);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -2,38 +2,107 @@
|
||||
#define POINCARE_EXPRESSION_H
|
||||
|
||||
#include <poincare/expression_layout.h>
|
||||
#include <kandinsky.h>
|
||||
extern "C" {
|
||||
#include <assert.h>
|
||||
}
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Context;
|
||||
template<class T>
|
||||
class Evaluation;
|
||||
template<class T> class Complex;
|
||||
class Rational;
|
||||
|
||||
class Expression {
|
||||
friend class Undefined;
|
||||
friend class Rational;
|
||||
friend class Decimal;
|
||||
friend class Multiplication;
|
||||
friend class Power;
|
||||
friend class Addition;
|
||||
friend class Factorial;
|
||||
friend class Division;
|
||||
friend class Store;
|
||||
friend class Sine;
|
||||
friend class Cosine;
|
||||
friend class Tangent;
|
||||
friend class AbsoluteValue;
|
||||
friend class ArcCosine;
|
||||
friend class ArcSine;
|
||||
friend class ArcTangent;
|
||||
friend class BinomialCoefficient;
|
||||
friend class Ceiling;
|
||||
friend class ComplexArgument;
|
||||
friend class ConfidenceInterval;
|
||||
friend class Conjugate;
|
||||
friend class Derivative;
|
||||
friend class Determinant;
|
||||
friend class DivisionQuotient;
|
||||
friend class DivisionRemainder;
|
||||
friend class Floor;
|
||||
friend class FracPart;
|
||||
friend class GreatCommonDivisor;
|
||||
friend class HyperbolicArcCosine;
|
||||
friend class HyperbolicArcSine;
|
||||
friend class HyperbolicArcTangent;
|
||||
friend class HyperbolicCosine;
|
||||
friend class HyperbolicSine;
|
||||
friend class HyperbolicTangent;
|
||||
friend class ImaginaryPart;
|
||||
friend class Integral;
|
||||
friend class LeastCommonMultiple;
|
||||
friend class Logarithm;
|
||||
friend class MatrixDimension;
|
||||
friend class MatrixInverse;
|
||||
friend class MatrixTrace;
|
||||
friend class MatrixTranspose;
|
||||
friend class NaperianLogarithm;
|
||||
friend class NthRoot;
|
||||
friend class Opposite;
|
||||
friend class Parenthesis;
|
||||
friend class PermuteCoefficient;
|
||||
friend class PredictionInterval;
|
||||
friend class Product;
|
||||
friend class RealPart;
|
||||
friend class Round;
|
||||
friend class SquareRoot;
|
||||
friend class Subtraction;
|
||||
friend class Sum;
|
||||
friend class Symbol;
|
||||
friend class Matrix;
|
||||
friend class SimplificationRoot;
|
||||
friend class Sequence;
|
||||
friend class Trigonometry;
|
||||
friend class EvaluationEngine;
|
||||
friend class SimplificationEngine;
|
||||
|
||||
public:
|
||||
enum class Type : uint8_t {
|
||||
AbsoluteValue,
|
||||
Undefined = 0,
|
||||
Rational = 1,
|
||||
Decimal,
|
||||
Multiplication,
|
||||
Power,
|
||||
Addition,
|
||||
Factorial,
|
||||
Division,
|
||||
Store,
|
||||
Sine,
|
||||
Cosine,
|
||||
Tangent,
|
||||
AbsoluteValue,
|
||||
ArcCosine,
|
||||
ArcSine,
|
||||
ArcTangent,
|
||||
BinomialCoefficient,
|
||||
Ceiling,
|
||||
Complex,
|
||||
ComplexArgument,
|
||||
ConfidenceInterval,
|
||||
Conjugate,
|
||||
Cosine,
|
||||
Derivative,
|
||||
Determinant,
|
||||
DivisionQuotient,
|
||||
DivisionRemainder,
|
||||
Factorial,
|
||||
Float,
|
||||
Floor,
|
||||
FracPart,
|
||||
ExpressionMatrix,
|
||||
GreatCommonDivisor,
|
||||
HyperbolicArcCosine,
|
||||
HyperbolicArcSine,
|
||||
@@ -42,39 +111,31 @@ public:
|
||||
HyperbolicSine,
|
||||
HyperbolicTangent,
|
||||
ImaginaryPart,
|
||||
Integer,
|
||||
Integral,
|
||||
Logarithm,
|
||||
LeastCommonMultiple,
|
||||
MatrixDimension,
|
||||
MatrixInverse,
|
||||
Logarithm,
|
||||
MatrixTrace,
|
||||
MatrixTranspose,
|
||||
Multiplication,
|
||||
NaperianLogarithm,
|
||||
NthRoot,
|
||||
Evaluation,
|
||||
Opposite,
|
||||
PredictionInterval,
|
||||
Fraction,
|
||||
Parenthesis,
|
||||
PermuteCoefficient,
|
||||
Power,
|
||||
Product,
|
||||
RealPart,
|
||||
Round,
|
||||
Sine,
|
||||
SquareRoot,
|
||||
Store,
|
||||
Sum,
|
||||
Subtraction,
|
||||
Sum,
|
||||
Symbol,
|
||||
Tangent,
|
||||
};
|
||||
enum class AngleUnit {
|
||||
Degree = 0,
|
||||
Radian = 1,
|
||||
Default = 2
|
||||
|
||||
Complex,
|
||||
Matrix,
|
||||
ConfidenceInterval,
|
||||
MatrixDimension,
|
||||
MatrixInverse,
|
||||
MatrixTranspose,
|
||||
PredictionInterval,
|
||||
SimplificationRoot,
|
||||
};
|
||||
enum class FloatDisplayMode {
|
||||
Decimal = 0,
|
||||
@@ -86,70 +147,122 @@ public:
|
||||
Polar = 1,
|
||||
Default = 2
|
||||
};
|
||||
enum class AngleUnit {
|
||||
Degree = 0,
|
||||
Radian = 1,
|
||||
Default = 2
|
||||
};
|
||||
|
||||
/* Constructor & Destructor */
|
||||
static Expression * parse(char const * string);
|
||||
virtual ~Expression() = default;
|
||||
virtual bool hasValidNumberOfArguments() const = 0;
|
||||
ExpressionLayout * createLayout(FloatDisplayMode floatDisplayMode = FloatDisplayMode::Default, ComplexFormat complexFormat = ComplexFormat::Default) const; // Returned object must be deleted
|
||||
virtual const Expression * operand(int i) const = 0;
|
||||
virtual int numberOfOperands() const = 0;
|
||||
virtual Expression * clone() const = 0;
|
||||
virtual Expression * cloneWithDifferentOperands(Expression** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const = 0;
|
||||
|
||||
// TODO: Consider std::unique_ptr - see https://google-styleguide.googlecode.com/svn/trunk/cppguide.html#Ownership_and_Smart_Pointers
|
||||
|
||||
/* This tests whether two expressions are the same, this takes into account
|
||||
* commutativity of operators.
|
||||
*
|
||||
* For example 3+5 is identical to 5+3 but is not identical to 8.
|
||||
*/
|
||||
bool isIdenticalTo(const Expression * e) const;
|
||||
|
||||
/* This tests whether two expressions are equivalent.
|
||||
* This is done by testing wheter they simplify to the same expression.
|
||||
*
|
||||
* For example:
|
||||
* - 3+5 and 4+4 are equivalent.
|
||||
* - (x+y)*z and x*z+y*z are equivalent.
|
||||
*
|
||||
* Here we assume that two equivalent expressions have the same
|
||||
* simplification, we don't really know whether that's the case,
|
||||
* nevertheless we are sure that if two expressions simplify to the same
|
||||
* expression they are indeed equivalent.
|
||||
*/
|
||||
bool isEquivalentTo(Expression * e) const;
|
||||
|
||||
/* Compare the value of two expressions.
|
||||
* This only make sense if the two values are of the same type
|
||||
*/
|
||||
virtual bool valueEquals(const Expression * e) const;
|
||||
Expression * simplify() const;
|
||||
|
||||
/* Poor man's RTTI */
|
||||
virtual Type type() const = 0;
|
||||
virtual bool isCommutative() const;
|
||||
|
||||
typedef bool (*CircuitBreaker)(const Expression * e);
|
||||
static void setCircuitBreaker(CircuitBreaker cb);
|
||||
bool shouldStopProcessing() const;
|
||||
/* Circuit breaker */
|
||||
typedef bool (*CircuitBreaker)();
|
||||
static void setCircuitBreaker(CircuitBreaker cb);
|
||||
static bool shouldStopProcessing();
|
||||
|
||||
/* The function evaluate creates a new expression and thus mallocs memory.
|
||||
/* Hierarchy */
|
||||
virtual const Expression * operand(int i) const = 0;
|
||||
Expression * editableOperand(int i) { return const_cast<Expression *>(operand(i)); }
|
||||
virtual int numberOfOperands() const = 0;
|
||||
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 {
|
||||
Negative = -1,
|
||||
Unknown = 0,
|
||||
Positive = 1
|
||||
};
|
||||
virtual Sign sign() const { return Sign::Unknown; }
|
||||
typedef bool (*ExpressionTest)(const Expression * e);
|
||||
bool recursivelyMatches(ExpressionTest test) const;
|
||||
static bool IsMatrix(const Expression * e);
|
||||
|
||||
/* Comparison */
|
||||
/* isIdenticalTo is the "easy" equality, it returns true if both trees have
|
||||
* same structures and all their nodes have same types and values (ie,
|
||||
* sqrt(pi^2) is NOT identical to pi). */
|
||||
bool isIdenticalTo(const Expression * e) const {
|
||||
/* We use the simplification order only because it is a already-coded total
|
||||
* order on expresssions. */
|
||||
return SimplificationOrder(this, e) == 0;
|
||||
}
|
||||
|
||||
/* Layout Engine */
|
||||
ExpressionLayout * createLayout(FloatDisplayMode floatDisplayMode = FloatDisplayMode::Default, ComplexFormat complexFormat = ComplexFormat::Default) const; // Returned object must be deleted
|
||||
virtual int writeTextInBuffer(char * buffer, int bufferSize) const = 0;
|
||||
|
||||
/* Simplification */
|
||||
static void Simplify(Expression ** expressionAddress, Context & context, AngleUnit angleUnit = AngleUnit::Default);
|
||||
|
||||
/* 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> Evaluation<T> * evaluate(Context& context, AngleUnit angleUnit = AngleUnit::Default) const;
|
||||
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);
|
||||
virtual int writeTextInBuffer(char * buffer, int bufferSize) const;
|
||||
protected:
|
||||
/* Constructor */
|
||||
Expression() : m_parent(nullptr) {}
|
||||
/* Evaluation Engine */
|
||||
typedef float SinglePrecision;
|
||||
typedef double DoublePrecision;
|
||||
template<typename T> static T epsilon();
|
||||
constexpr static int k_maxNumberOfSteps = 10000;
|
||||
|
||||
/* Simplification */
|
||||
/* SimplificationOrder returns:
|
||||
* 1 if e1 > e2
|
||||
* -1 if e1 < e2
|
||||
* 0 if e1 == e
|
||||
* Following the order described in Computer Algebra and Symbolic Computation,
|
||||
* Joel S. Cohen (section 3.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). */
|
||||
static int SimplificationOrder(const Expression * e1, const Expression * e2);
|
||||
private:
|
||||
/* Properties */
|
||||
virtual Expression * setSign(Sign s, Context & context, AngleUnit angleUnit) { assert(false); return nullptr; }
|
||||
/* Comparison */
|
||||
/* In the simplification order, most expressions are compared by only
|
||||
* comparing their types. However hierarchical expressions of same type would
|
||||
* compare their operands and thus need to reimplement
|
||||
* simplificationOrderSameType. Besides, operations that can be simplified
|
||||
* (ie +, *, ^, !) have specific rules to group like terms together and thus
|
||||
* reimplement simplificationOrderGreaterType. */
|
||||
virtual int simplificationOrderGreaterType(const Expression * e) const { return -1; }
|
||||
//TODO: What should be the implementation for complex?
|
||||
virtual int simplificationOrderSameType(const Expression * e) const { return 0; }
|
||||
/* Layout Engine */
|
||||
virtual ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const = 0;
|
||||
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const = 0;
|
||||
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const = 0;
|
||||
bool sequentialOperandsIdentity(const Expression * e) const;
|
||||
bool commutativeOperandsIdentity(const Expression * e) const;
|
||||
bool combinatoryCommutativeOperandsIdentity(const Expression * e,
|
||||
bool * operandMatched, int leftToMatch) const;
|
||||
/* Simplification */
|
||||
static void Reduce(Expression ** expressionAddress, Context & context, AngleUnit angleUnit, bool recursively = true);
|
||||
Expression * deepBeautify(Context & context, AngleUnit angleUnit);
|
||||
Expression * deepReduce(Context & context, AngleUnit angleUnit);
|
||||
// TODO: should be virtual pure
|
||||
virtual Expression * shallowReduce(Context & context, AngleUnit angleUnit);
|
||||
virtual Expression * shallowBeautify(Context & context, AngleUnit angleUnit) { return this; };
|
||||
|
||||
// Private methods used in simplification process
|
||||
virtual Expression * cloneDenominator(Context & context, AngleUnit angleUnit) const {
|
||||
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;
|
||||
|
||||
Expression * m_parent;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
#ifndef POINCARE_EXPRESSION_MATRIX_H
|
||||
#define POINCARE_EXPRESSION_MATRIX_H
|
||||
|
||||
#include <poincare/matrix.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class ExpressionMatrix : public Matrix {
|
||||
public:
|
||||
ExpressionMatrix(MatrixData * matrixData);
|
||||
ExpressionMatrix(Expression ** newOperands, int numberOfOperands, int m_numberOfRows, int m_numberOfColumns, bool cloneOperands);
|
||||
~ExpressionMatrix();
|
||||
ExpressionMatrix(const Matrix& other) = delete;
|
||||
ExpressionMatrix(Matrix&& other) = delete;
|
||||
ExpressionMatrix& operator=(const ExpressionMatrix& other) = delete;
|
||||
ExpressionMatrix& operator=(ExpressionMatrix&& other) = delete;
|
||||
bool hasValidNumberOfArguments() const override;
|
||||
int numberOfRows() const override;
|
||||
int numberOfColumns() const override;
|
||||
const Expression * operand(int i) const override;
|
||||
Expression * clone() const override;
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
private:
|
||||
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
MatrixData * m_matrixData;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,25 +1,30 @@
|
||||
#ifndef POINCARE_FACTORIAL_H
|
||||
#define POINCARE_FACTORIAL_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Factorial : public Function {
|
||||
class Factorial : public StaticHierarchy<1> {
|
||||
public:
|
||||
Factorial(Expression * argument, bool clone = true);
|
||||
Factorial(const Expression * argument, bool clone = true);
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Complex<float> computeComplex(const Complex<float> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c);
|
||||
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>);
|
||||
}
|
||||
Complex<double> computeComplex(const Complex<double> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c);
|
||||
Expression * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
template<typename T> Complex<T> templatedComputeComplex(const Complex<T> c) const;
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override;
|
||||
int simplificationOrderGreaterType(const Expression * e) const override;
|
||||
int simplificationOrderSameType(const Expression * e) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,25 +1,34 @@
|
||||
#ifndef POINCARE_FLOOR_H
|
||||
#define POINCARE_FLOOR_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Floor : public Function {
|
||||
class Floor : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Floor();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Complex<float> computeComplex(const Complex<float> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c);
|
||||
}
|
||||
Complex<double> computeComplex(const Complex<double> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c);
|
||||
}
|
||||
template<typename T> Complex<T> templatedComputeComplex(const Complex<T> c) const;
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
const char * name() const { return "floor"; }
|
||||
/* 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 * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,24 +1,36 @@
|
||||
#ifndef POINCARE_FRAC_PART_H
|
||||
#define POINCARE_FRAC_PART_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class FracPart : public Function {
|
||||
class FracPart : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
FracPart();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Complex<float> computeComplex(const Complex<float> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c);
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
|
||||
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
|
||||
}
|
||||
Complex<double> computeComplex(const Complex<double> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c);
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
const char * name() const { return "frac"; }
|
||||
/* 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 * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
template<typename T> Complex<T> templatedComputeComplex(const Complex<T> c) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
#ifndef POINCARE_FRACTION_H
|
||||
#define POINCARE_FRACTION_H
|
||||
|
||||
#include <poincare/binary_operation.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Fraction : public BinaryOperation {
|
||||
using BinaryOperation::BinaryOperation;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression** newOperands,
|
||||
int numnerOfOperands, bool cloneOperands = true) const override;
|
||||
template<typename T> static Complex<T> compute(const Complex<T> c, const Complex<T> d);
|
||||
private:
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
|
||||
|
||||
Evaluation<float> * computeOnComplexAndComplexMatrix(const Complex<float> * c, Evaluation<float> * n) const override {
|
||||
return templatedComputeOnComplexAndComplexMatrix(c, n);
|
||||
}
|
||||
Evaluation<double> * computeOnComplexAndComplexMatrix(const Complex<double> * c, Evaluation<double> * n) const override {
|
||||
return templatedComputeOnComplexAndComplexMatrix(c, n);
|
||||
}
|
||||
template<typename T> Evaluation<T> * templatedComputeOnComplexAndComplexMatrix(const Complex<T> * c, Evaluation<T> * n) const;
|
||||
|
||||
Evaluation<float> * computeOnComplexMatrices(Evaluation<float> * m, Evaluation<float> * n) const override {
|
||||
return templatedComputeOnComplexMatrices(m, n);
|
||||
}
|
||||
Evaluation<double> * computeOnComplexMatrices(Evaluation<double> * m, Evaluation<double> * n) const override {
|
||||
return templatedComputeOnComplexMatrices(m, n);
|
||||
}
|
||||
template<typename T> Evaluation<T> * templatedComputeOnComplexMatrices(Evaluation<T> * m, Evaluation<T> * n) const;
|
||||
|
||||
Complex<float> privateCompute(const Complex<float> c, const Complex<float> d) const override {
|
||||
return compute(c, d);
|
||||
}
|
||||
Complex<double> privateCompute(const Complex<double> c, const Complex<double> d) const override {
|
||||
return compute(c, d);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,50 +0,0 @@
|
||||
#ifndef POINCARE_FUNCTION_H
|
||||
#define POINCARE_FUNCTION_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/list_data.h>
|
||||
#include <poincare/complex.h>
|
||||
#include <poincare/complex_matrix.h>
|
||||
#include <cmath>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
/* The Function class represents the built-in math functions such as cos, sin,
|
||||
* tan, log, etc... */
|
||||
|
||||
class Function : public Expression {
|
||||
public:
|
||||
Function(const char * name, int requiredNumberOfArguments = 1);
|
||||
~Function();
|
||||
Function(const Function& other) = delete;
|
||||
Function(Function&& other) = delete;
|
||||
Function& operator=(const Function& other) = delete;
|
||||
Function& operator=(Function&& other) = delete;
|
||||
void setArgument(Expression ** args, int numberOfArguments, bool clone = true);
|
||||
void setArgument(ListData * listData, bool clone = true);
|
||||
bool hasValidNumberOfArguments() const override;
|
||||
const Expression * operand(int i) const override;
|
||||
int numberOfOperands() const override;
|
||||
Expression * clone() const override;
|
||||
protected:
|
||||
virtual Complex<float> computeComplex(const Complex<float> c, AngleUnit angleUnit) const {
|
||||
return Complex<float>::Float(NAN);
|
||||
}
|
||||
virtual Complex<double> computeComplex(const Complex<double> c, AngleUnit angleUnit) const {
|
||||
return Complex<double>::Float(NAN);
|
||||
}
|
||||
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
|
||||
void build(Expression ** args, int numberOfArguments, bool clone);
|
||||
void clean();
|
||||
Expression ** m_args;
|
||||
int m_numberOfArguments;
|
||||
int m_requiredNumberOfArguments;
|
||||
const char * m_name;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -2,8 +2,8 @@
|
||||
#define POINCARE_GLOBAL_CONTEXT_H
|
||||
|
||||
#include <poincare/context.h>
|
||||
#include <poincare/matrix.h>
|
||||
#include <poincare/complex.h>
|
||||
#include <poincare/complex_matrix.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -21,11 +21,8 @@ public:
|
||||
GlobalContext& operator=(GlobalContext&& other) = delete;
|
||||
/* The expression recorded in global context is already a expression.
|
||||
* Otherwise, we would need the context and the angle unit to evaluate it */
|
||||
const Expression * expressionForSymbol(const Symbol * symbol) override {
|
||||
return evaluationForSymbol(symbol);
|
||||
}
|
||||
const Evaluation<double> * evaluationForSymbol(const Symbol * symbol);
|
||||
void setExpressionForSymbolName(Expression * expression, const Symbol * symbol) override;
|
||||
const Expression * expressionForSymbol(const Symbol * symbol) override;
|
||||
void setExpressionForSymbolName(const Expression * expression, const Symbol * symbol, Context & context) override;
|
||||
static constexpr uint16_t k_maxNumberOfScalarExpressions = 26;
|
||||
static constexpr uint16_t k_maxNumberOfListExpressions = 10;
|
||||
static constexpr uint16_t k_maxNumberOfMatrixExpressions = 10;
|
||||
@@ -33,9 +30,10 @@ public:
|
||||
private:
|
||||
int symbolIndex(const Symbol * symbol) const;
|
||||
Complex<double> * m_expressions[k_maxNumberOfScalarExpressions];
|
||||
ComplexMatrix<double> * m_matrixExpressions[k_maxNumberOfMatrixExpressions];
|
||||
Matrix * m_matrixExpressions[k_maxNumberOfMatrixExpressions];
|
||||
Complex<double> m_pi;
|
||||
Complex<double> m_e;
|
||||
Complex<double> m_i;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,20 +1,32 @@
|
||||
#ifndef POINCARE_GREAT_COMMON_DIVISOR_H
|
||||
#define POINCARE_GREAT_COMMON_DIVISOR_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/complex.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class GreatCommonDivisor : public Function {
|
||||
class GreatCommonDivisor : public StaticHierarchy<2> {
|
||||
using StaticHierarchy<2>::StaticHierarchy;
|
||||
public:
|
||||
GreatCommonDivisor();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
|
||||
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
|
||||
}
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
const char * name() const { return "gcd"; }
|
||||
/* 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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
25
poincare/include/poincare/hierarchy.h
Normal file
25
poincare/include/poincare/hierarchy.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#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
|
||||
@@ -1,24 +1,36 @@
|
||||
#ifndef POINCARE_HYPERBOLIC_ARC_COSINE_H
|
||||
#define POINCARE_HYPERBOLIC_ARC_COSINE_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class HyperbolicArcCosine : public Function {
|
||||
class HyperbolicArcCosine : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
HyperbolicArcCosine();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Complex<float> computeComplex(const Complex<float> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c);
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
|
||||
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
|
||||
}
|
||||
Complex<double> computeComplex(const Complex<double> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c);
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
const char * name() const { return "acosh"; }
|
||||
/* 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 * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
template<typename T> Complex<T> templatedComputeComplex(const Complex<T> c) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,24 +1,36 @@
|
||||
#ifndef POINCARE_HYPERBOLIC_ARC_SINE_H
|
||||
#define POINCARE_HYPERBOLIC_ARC_SINE_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class HyperbolicArcSine : public Function {
|
||||
class HyperbolicArcSine : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
HyperbolicArcSine();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Complex<float> computeComplex(const Complex<float> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c);
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
|
||||
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
|
||||
}
|
||||
Complex<double> computeComplex(const Complex<double> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c);
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
const char * name() const { return "asinh"; }
|
||||
/* 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 * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
template<typename T> Complex<T> templatedComputeComplex(const Complex<T> c) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,24 +1,36 @@
|
||||
#ifndef POINCARE_HYPERBOLIC_ARC_TANGENT_H
|
||||
#define POINCARE_HYPERBOLIC_ARC_TANGENT_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class HyperbolicArcTangent : public Function {
|
||||
class HyperbolicArcTangent : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
HyperbolicArcTangent();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Complex<float> computeComplex(const Complex<float> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c);
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
|
||||
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
|
||||
}
|
||||
Complex<double> computeComplex(const Complex<double> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c);
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
const char * name() const { return "atanh"; }
|
||||
/* 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 * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
template<typename T> Complex<T> templatedComputeComplex(const Complex<T> c) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,23 +1,35 @@
|
||||
#ifndef POINCARE_HYPERBOLIC_COSINE_H
|
||||
#define POINCARE_HYPERBOLIC_COSINE_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class HyperbolicCosine : public Function {
|
||||
class HyperbolicCosine : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
HyperbolicCosine();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
template<typename T> static Complex<T> compute(const Complex<T> c);
|
||||
Expression * clone() const override;
|
||||
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
|
||||
private:
|
||||
Complex<float> computeComplex(const Complex<float> c, AngleUnit angleUnit) const override {
|
||||
return compute(c);
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
|
||||
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
|
||||
}
|
||||
Complex<double> computeComplex(const Complex<double> c, AngleUnit angleUnit) const override {
|
||||
return compute(c);
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
const char * name() const { return "cosh"; }
|
||||
/* 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 * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,23 +1,35 @@
|
||||
#ifndef POINCARE_HYPERBOLIC_SINE_H
|
||||
#define POINCARE_HYPERBOLIC_SINE_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class HyperbolicSine : public Function {
|
||||
class HyperbolicSine : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
HyperbolicSine();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
template<typename T> static Complex<T> compute(const Complex<T> c);
|
||||
Expression * clone() const override;
|
||||
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
|
||||
private:
|
||||
Complex<float> computeComplex(const Complex<float> c, AngleUnit angleUnit) const override {
|
||||
return compute(c);
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
|
||||
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
|
||||
}
|
||||
Complex<double> computeComplex(const Complex<double> c, AngleUnit angleUnit) const override {
|
||||
return compute(c);
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
const char * name() const { return "sinh"; }
|
||||
/* 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 * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,23 +1,35 @@
|
||||
#ifndef POINCARE_HYPERBOLIC_TANGENT_H
|
||||
#define POINCARE_HYPERBOLIC_TANGENT_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class HyperbolicTangent : public Function {
|
||||
class HyperbolicTangent : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
HyperbolicTangent();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
template<typename T> static Complex<T> compute(const Complex<T> c);
|
||||
Expression * clone() const override;
|
||||
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
|
||||
private:
|
||||
Complex<float> computeComplex(const Complex<float> c, AngleUnit angleUnit) const override {
|
||||
return compute(c);
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
|
||||
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
|
||||
}
|
||||
Complex<double> computeComplex(const Complex<double> c, AngleUnit angleUnit) const override {
|
||||
return compute(c);
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
const char * name() const { return "tanh"; }
|
||||
/* 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 * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,24 +1,36 @@
|
||||
#ifndef POINCARE_IMAGINARY_PART_H
|
||||
#define POINCARE_IMAGINARY_PART_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class ImaginaryPart : public Function {
|
||||
class ImaginaryPart : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
ImaginaryPart();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Complex<float> computeComplex(const Complex<float> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c);
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
|
||||
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
|
||||
}
|
||||
Complex<double> computeComplex(const Complex<double> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c);
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
const char * name() const { return "im"; }
|
||||
/* 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 * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
template<typename T> Complex<T> templatedComputeComplex(const Complex<T> c) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,66 +1,116 @@
|
||||
#ifndef POINCARE_INTEGER_H
|
||||
#define POINCARE_INTEGER_H
|
||||
|
||||
#include <poincare/leaf_expression.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef int32_t native_int_t;
|
||||
typedef uint32_t native_uint_t;
|
||||
typedef uint64_t double_native_uint_t;
|
||||
#include <assert.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Integer : public LeafExpression {
|
||||
/* All algorithm should be improved with:
|
||||
* Modern Computer Arithmetic, Richard P. Brent and Paul Zimmermann */
|
||||
|
||||
struct IntegerDivision;
|
||||
|
||||
class Integer {
|
||||
public:
|
||||
Integer(native_int_t i);
|
||||
typedef uint16_t half_native_uint_t;
|
||||
typedef int32_t native_int_t;
|
||||
typedef int64_t double_native_int_t;
|
||||
typedef uint32_t native_uint_t;
|
||||
typedef uint64_t double_native_uint_t;
|
||||
|
||||
// FIXME: This constructor should be constexpr
|
||||
Integer(native_int_t i = 0) :
|
||||
m_digit(i>0 ? i : -i),
|
||||
m_numberOfDigits(1),
|
||||
m_negative(i<0)
|
||||
{
|
||||
}
|
||||
Integer(double_native_int_t i);
|
||||
Integer(const char * digits, bool negative = false); // Digits are NOT NULL-terminated
|
||||
Type type() const override;
|
||||
static Integer exponent(int fractionalPartLength, const char * exponent, int exponentLength, bool exponentNegative);
|
||||
static Integer numerator(const char * integralPart, int integralPartLength, const char * fractionalPart, int fractionalPartLength, bool negative, Integer * exponent);
|
||||
static Integer denominator(Integer * exponent);
|
||||
|
||||
~Integer();
|
||||
Integer(Integer&& other); // C++11 move constructor
|
||||
Integer& operator=(Integer&& other); // C++11 move assignment operator
|
||||
Integer(const Integer& other) = delete;
|
||||
Integer& operator=(const Integer& other) = delete;
|
||||
Integer(const Integer& other); // C++11 copy constructor
|
||||
Integer& operator=(const Integer& other); // C++11 copy assignment operator
|
||||
|
||||
// Getter & Setter
|
||||
bool isNegative() const { return m_negative; }
|
||||
void setNegative(bool negative);
|
||||
int extractedInt() { assert(m_numberOfDigits == 1 && m_digit <= 0x7FFFFFFF); return m_negative ? -m_digit : m_digit; }
|
||||
|
||||
// Comparison
|
||||
static int NaturalOrder(const Integer & i, const Integer & j);
|
||||
bool isEqualTo(const Integer & other) const;
|
||||
bool isLowerThan(const Integer & other) const;
|
||||
|
||||
// Layout
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const;
|
||||
ExpressionLayout * createLayout() const;
|
||||
|
||||
// Approximation
|
||||
template<typename T> T approximate() const;
|
||||
|
||||
// Arithmetic
|
||||
Integer add(const Integer &other) const;
|
||||
Integer subtract(const Integer &other) const;
|
||||
Integer multiply_by(const Integer &other) const;
|
||||
Integer divide_by(const Integer &other) const;
|
||||
|
||||
bool operator<(const Integer &other) const;
|
||||
bool operator==(const Integer &other) const;
|
||||
|
||||
bool valueEquals(const Expression * e) const override;
|
||||
|
||||
Expression * clone() const override;
|
||||
static Integer Addition(const Integer & i, const Integer & j);
|
||||
static Integer Subtraction(const Integer & i, const Integer & j);
|
||||
static Integer Multiplication(const Integer & i, const Integer & j);
|
||||
static Integer Factorial(const Integer & i);
|
||||
static IntegerDivision Division(const Integer & numerator, const Integer & denominator);
|
||||
static Integer Power(const Integer & i, const Integer & j);
|
||||
//static Integer Division(const Integer & i, const Integer & j);
|
||||
//static IntegerDivision division(const Integer & i, const Integer & j);
|
||||
bool isOne() const { return (m_numberOfDigits == 1 && digit(0) == 1 && !m_negative); };
|
||||
bool isTwo() const { return (m_numberOfDigits == 1 && digit(0) == 2 && !m_negative); };
|
||||
bool isTen() const { return (m_numberOfDigits == 1 && digit(0) == 10 && !m_negative); };
|
||||
bool isMinusOne() const { return (m_numberOfDigits == 1 && digit(0) == 1 && m_negative); };
|
||||
bool isZero() const { return (m_numberOfDigits == 1 && digit(0) == 0); };
|
||||
private:
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
|
||||
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override;
|
||||
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override;
|
||||
Integer add(const Integer &other, bool inverse_other_negative) const;
|
||||
int8_t ucmp(const Integer &other) const; // -1, 0, or 1
|
||||
Integer usum(const Integer &other, bool subtract, bool output_negative) const;
|
||||
/* WARNING: This constructor takes ownership of the bits array and will free it! */
|
||||
Integer(native_uint_t * digits, uint16_t numberOfDigits, bool negative);
|
||||
native_uint_t * m_digits; // LITTLE-ENDIAN
|
||||
uint16_t m_numberOfDigits; // In base native_uint_max
|
||||
bool m_negative;
|
||||
Integer(const native_uint_t * digits, uint16_t numberOfDigits, bool negative);
|
||||
static Integer IntegerWithHalfDigitAtIndex(half_native_uint_t halfDigit, int index);
|
||||
|
||||
/*
|
||||
// TODO: Small-int optimization
|
||||
union {
|
||||
uint32_t m_staticBits;
|
||||
char * m_dynamicBits;
|
||||
};
|
||||
*/
|
||||
void releaseDynamicIvars();
|
||||
static int8_t ucmp(const Integer & a, const Integer & b); // -1, 0, or 1
|
||||
static Integer usum(const Integer & a, const Integer & b, bool subtract, bool outputNegative);
|
||||
static Integer addition(const Integer & a, const Integer & b, bool inverseBNegative);
|
||||
static IntegerDivision udiv(const Integer & a, const Integer & b);
|
||||
bool usesImmediateDigit() const { return m_numberOfDigits == 1; }
|
||||
native_uint_t digit(int i) const {
|
||||
assert(i >= 0 && i < m_numberOfDigits);
|
||||
return (usesImmediateDigit() ? m_digit : m_digits[i]);
|
||||
}
|
||||
uint16_t numberOfHalfDigits() const {
|
||||
native_uint_t d = digit(m_numberOfDigits-1);
|
||||
native_uint_t halfBase = 1 << (8*sizeof(half_native_uint_t));
|
||||
return (d >= halfBase ? 2*m_numberOfDigits : 2*m_numberOfDigits-1);
|
||||
}
|
||||
half_native_uint_t halfDigit(int i) const {
|
||||
assert(i >= 0);
|
||||
if (i >= numberOfHalfDigits()) {
|
||||
return 0;
|
||||
}
|
||||
return (usesImmediateDigit() ? ((half_native_uint_t *)&m_digit)[i] : ((half_native_uint_t *)m_digits)[i]);
|
||||
}
|
||||
// Small integer optimization. Similar to short string optimization.
|
||||
union {
|
||||
const native_uint_t * m_digits; // Little-endian
|
||||
native_uint_t m_digit;
|
||||
};
|
||||
uint16_t m_numberOfDigits; // In base native_uint_max
|
||||
bool m_negative; // Make sure zero cannot be negative
|
||||
|
||||
static_assert(sizeof(native_int_t) <= sizeof(native_uint_t), "native_uint_t should be able to contain native_int_t data");
|
||||
static_assert(sizeof(double_native_uint_t) == 2*sizeof(native_uint_t), "double_native_uint_t should be twice the size of native_uint_t");
|
||||
};
|
||||
|
||||
class Division {
|
||||
public:
|
||||
Division(const Integer &numerator, const Integer &denominator);
|
||||
Integer m_quotient;
|
||||
Integer m_remainder;
|
||||
struct IntegerDivision {
|
||||
Integer quotient;
|
||||
Integer remainder;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,22 +1,30 @@
|
||||
#ifndef POINCARE_INTEGRAL_H
|
||||
#define POINCARE_INTEGRAL_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/variable_context.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/complex.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Integral : public Function {
|
||||
class Integral : public StaticHierarchy<3> {
|
||||
using StaticHierarchy<3>::StaticHierarchy;
|
||||
public:
|
||||
Integral();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, "int");
|
||||
}
|
||||
/* 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;
|
||||
template<typename T>
|
||||
struct DetailedResult
|
||||
{
|
||||
|
||||
20
poincare/include/poincare/layout_engine.h
Normal file
20
poincare/include/poincare/layout_engine.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef POINCARE_LAYOUT_ENGINE_H
|
||||
#define POINCARE_LAYOUT_ENGINE_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class LayoutEngine {
|
||||
public:
|
||||
static ExpressionLayout * createInfixLayout(const Expression * expression, Expression::FloatDisplayMode floatDisplayMode, Expression::ComplexFormat complexFormat, const char * operatorName);
|
||||
static ExpressionLayout * createPrefixLayout(const Expression * expression, Expression::FloatDisplayMode floatDisplayMode, Expression::ComplexFormat complexFormat, const char * operatorName);
|
||||
|
||||
typedef bool (*OperandNeedParenthesis)(const Expression * e);
|
||||
static int writeInfixExpressionTextInBuffer(const Expression * expression, char * buffer, int bufferSize, const char * operatorName, OperandNeedParenthesis operandNeedParenthesis = [](const Expression * e) { return e->type() == Expression::Type::Opposite; });
|
||||
static int writePrefixExpressionTextInBuffer(const Expression * expression, char * buffer, int bufferSize, const char * operatorName);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,19 +0,0 @@
|
||||
#ifndef POINCARE_LEAF_EXPRESSION_H
|
||||
#define POINCARE_LEAF_EXPRESSION_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class LeafExpression : public Expression {
|
||||
public:
|
||||
bool hasValidNumberOfArguments() const override;
|
||||
const Expression * operand(int i) const override;
|
||||
int numberOfOperands() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,20 +1,32 @@
|
||||
#ifndef POINCARE_LEAST_COMMON_MULTIPLE_H
|
||||
#define POINCARE_LEAST_COMMON_MULTIPLE_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/complex.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class LeastCommonMultiple : public Function {
|
||||
class LeastCommonMultiple : public StaticHierarchy<2> {
|
||||
using StaticHierarchy<2>::StaticHierarchy;
|
||||
public:
|
||||
LeastCommonMultiple();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
|
||||
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
|
||||
}
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
const char * name() const { return "lcm"; }
|
||||
/* 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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ public:
|
||||
Expression ** operands() const;
|
||||
const Expression * operand(int i) const;
|
||||
void pushExpression(Expression * operand);
|
||||
void detachOperands();
|
||||
private:
|
||||
int m_numberOfOperands;
|
||||
Expression ** m_operands;
|
||||
|
||||
@@ -1,29 +1,34 @@
|
||||
#ifndef POINCARE_LOGARITHM_H
|
||||
#define POINCARE_LOGARITHM_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/bounded_static_hierarchy.h>
|
||||
#include <poincare/integer.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Logarithm : public Function {
|
||||
class Logarithm : public BoundedStaticHierarchy<2> {
|
||||
using BoundedStaticHierarchy<2>::BoundedStaticHierarchy;
|
||||
friend class NaperianLogarithm;
|
||||
public:
|
||||
Logarithm();
|
||||
bool hasValidNumberOfArguments() const override;
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
|
||||
Complex<float> computeComplex(const Complex<float> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c);
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, "log");
|
||||
}
|
||||
Complex<double> computeComplex(const Complex<double> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c);
|
||||
}
|
||||
template<typename T> Complex<T> templatedComputeComplex(const Complex<T> c) const;
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context & context, AngleUnit angleUnit) override;
|
||||
Expression * shallowBeautify(Context & context, AngleUnit angleUnit) override;
|
||||
bool parentIsAPowerOfSameBase() const;
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,22 +1,42 @@
|
||||
#ifndef POINCARE_MATRIX_H
|
||||
#define POINCARE_MATRIX_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/dynamic_hierarchy.h>
|
||||
#include <poincare/matrix_data.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Matrix : public Expression {
|
||||
class Matrix : public DynamicHierarchy {
|
||||
public:
|
||||
virtual const Expression * operand(int i) const override = 0;
|
||||
int numberOfOperands() const override;
|
||||
virtual int numberOfRows() const = 0;
|
||||
virtual int numberOfColumns() const = 0;
|
||||
/* If the buffer is too small, the function fills the buffer until reaching
|
||||
* buffer size */
|
||||
Matrix(MatrixData * matrixData); // pilfer the operands of matrixData
|
||||
Matrix(const Expression * const * operands, int numberOfRows, int numberOfColumns, bool cloneOperands = true);
|
||||
int numberOfRows() const;
|
||||
int numberOfColumns() const;
|
||||
|
||||
/* Expression */
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override;
|
||||
|
||||
/* Operation on matrix */
|
||||
/* createDeterminant, createTrace and createInverse can only be called on an
|
||||
* matrix of complex expressions. createDeterminant and createTrace return
|
||||
* a complex expression and createInverse returns a matrix of complex
|
||||
* expressions or nullptr if the inverse could not be computed. */
|
||||
template<typename T> Complex<T> * createTrace() const;
|
||||
template<typename T> Complex<T> * createDeterminant() const;
|
||||
template<typename T> Matrix * createInverse() const;
|
||||
Matrix * createTranspose() const;
|
||||
static Matrix * createIdentity(int dim);
|
||||
template<typename T> static Matrix * createApproximateIdentity(int dim);
|
||||
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;
|
||||
int m_numberOfRows;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ class Complex;
|
||||
class MatrixData {
|
||||
public:
|
||||
MatrixData(ListData * listData, bool clone);
|
||||
MatrixData(Expression ** newOperands, int numberOfOperands, int m_numberOfRows, int m_numberOfColumns, bool cloneOperands);
|
||||
~MatrixData();
|
||||
MatrixData(const MatrixData& other) = delete;
|
||||
MatrixData(MatrixData&& other) = delete;
|
||||
@@ -21,11 +20,11 @@ public:
|
||||
void pushListData(ListData * listData, bool clone);
|
||||
int numberOfRows();
|
||||
int numberOfColumns();
|
||||
Expression ** operands() const;
|
||||
void pilferOperands(const Expression *** newStorageAddress);
|
||||
private:
|
||||
int m_numberOfRows;
|
||||
int m_numberOfColumns;
|
||||
Expression ** m_operands;
|
||||
const Expression ** m_operands;
|
||||
static Complex<double> * defaultExpression();
|
||||
};
|
||||
|
||||
|
||||
@@ -1,20 +1,32 @@
|
||||
#ifndef POINCARE_MATRIX_DIMENSION_H
|
||||
#define POINCARE_MATRIX_DIMENSION_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/complex.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class MatrixDimension : public Function {
|
||||
class MatrixDimension : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
MatrixDimension();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
|
||||
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
|
||||
}
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
const char * name() const { return "dimension"; }
|
||||
/* 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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,20 +1,32 @@
|
||||
#ifndef POINCARE_MATRIX_INVERSE_H
|
||||
#define POINCARE_MATRIX_INVERSE_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/complex.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class MatrixInverse : public Function {
|
||||
class MatrixInverse : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
MatrixInverse();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
/* Evaluation */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
|
||||
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
|
||||
}
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
const char * name() const { return "inverse"; }
|
||||
/* 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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,20 +1,32 @@
|
||||
#ifndef POINCARE_MATRIX_TRACE_H
|
||||
#define POINCARE_MATRIX_TRACE_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/complex.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class MatrixTrace : public Function {
|
||||
class MatrixTrace : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
MatrixTrace();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
|
||||
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
|
||||
}
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
const char * name() const { return "trace"; }
|
||||
/* 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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,20 +1,32 @@
|
||||
#ifndef POINCARE_MATRIX_TRANSPOSE_H
|
||||
#define POINCARE_MATRIX_TRANSPOSE_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/complex.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class MatrixTranspose : public Function {
|
||||
class MatrixTranspose : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
MatrixTranspose();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
|
||||
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
|
||||
}
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
const char * name() const { return "transpose"; }
|
||||
/* 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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,34 +1,65 @@
|
||||
#ifndef POINCARE_MULTIPLICATION_H
|
||||
#define POINCARE_MULTIPLICATION_H
|
||||
|
||||
#include <poincare/binary_operation.h>
|
||||
#include <poincare/dynamic_hierarchy.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Multiplication : public BinaryOperation {
|
||||
using BinaryOperation::BinaryOperation;
|
||||
class Multiplication : public DynamicHierarchy {
|
||||
using DynamicHierarchy::DynamicHierarchy;
|
||||
friend class Addition;
|
||||
friend class Division;
|
||||
friend class Logarithm;
|
||||
friend class Opposite;
|
||||
friend class Power;
|
||||
friend class Subtraction;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression** newOperands,
|
||||
int numnerOfOperands, bool cloneOperands = true) const override;
|
||||
template<typename T> static Evaluation<T> * computeOnMatrices(Evaluation<T> * m, Evaluation<T> * n);
|
||||
template<typename T> static Evaluation<T> * computeOnComplexAndMatrix(const Complex<T> * c, Evaluation<T> * m);
|
||||
Expression * clone() const override;
|
||||
Sign sign() const override;
|
||||
/* 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>);
|
||||
}
|
||||
template<typename T> static Matrix * computeOnMatrices(const Matrix * m, const Matrix * n);
|
||||
private:
|
||||
/* 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;
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
|
||||
Expression * privateShallowReduce(Context& context, AngleUnit angleUnit, bool expand);
|
||||
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);
|
||||
Expression * cloneDenominator(Context & context, AngleUnit angleUnit) const override;
|
||||
void addMissingFactors(Expression * factor, Context & context, AngleUnit angleUnit);
|
||||
void factorizeSineAndCosine(Expression * o1, Expression * o2, Context & context, AngleUnit angleUnit);
|
||||
static bool HaveSameNonRationalFactors(const Expression * e1, const Expression * e2);
|
||||
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;
|
||||
// Warning: mergeNegativePower not always returns a multiplication: *(b^-1,c^-1) -> (bc)^-1
|
||||
Expression * mergeNegativePower(Context & context, AngleUnit angleUnit);
|
||||
/* Evaluation */
|
||||
|
||||
Evaluation<float> * computeOnComplexMatrices(Evaluation<float> * m, Evaluation<float> * n) const override {
|
||||
return computeOnMatrices(m, n);
|
||||
template<typename T> static Matrix * computeOnMatrixAndComplex(const Matrix * m, const Complex<T> * c) {
|
||||
return EvaluationEngine::elementWiseOnComplexAndComplexMatrix(c, m, compute<T>);
|
||||
}
|
||||
Evaluation<double> * computeOnComplexMatrices(Evaluation<double> * m, Evaluation<double> * n) const override {
|
||||
return computeOnMatrices(m, n);
|
||||
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>);
|
||||
}
|
||||
|
||||
Complex<float> privateCompute(const Complex<float> c, const Complex<float> d) const override {
|
||||
return compute(c, d);
|
||||
}
|
||||
Complex<double> privateCompute(const Complex<double> c, const Complex<double> d) const override {
|
||||
return compute(c, d);
|
||||
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>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,24 +1,36 @@
|
||||
#ifndef POINCARE_NAPERIAN_LOGARITHM_H
|
||||
#define POINCARE_NAPERIAN_LOGARITHM_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class NaperianLogarithm : public Function {
|
||||
class NaperianLogarithm : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
NaperianLogarithm();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Complex<float> computeComplex(const Complex<float> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c);
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
|
||||
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
|
||||
}
|
||||
Complex<double> computeComplex(const Complex<double> c, AngleUnit angleUnit) const override {
|
||||
return templatedComputeComplex(c);
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
|
||||
}
|
||||
const char * name() const { return "ln"; }
|
||||
/* 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 * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
template<typename T> Complex<T> templatedComputeComplex(const Complex<T> c) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,22 +1,31 @@
|
||||
#ifndef POINCARE_NTH_ROOT_H
|
||||
#define POINCARE_NTH_ROOT_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/complex.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class NthRoot : public Function {
|
||||
class NthRoot : public StaticHierarchy<2> {
|
||||
using StaticHierarchy<2>::StaticHierarchy;
|
||||
public:
|
||||
NthRoot();
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression ** newOperands,
|
||||
int numberOfOperands, bool cloneOperands = true) const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
|
||||
template<typename T> Complex<T> compute(const Complex<T> c, const Complex<T> d) const;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, "root");
|
||||
}
|
||||
/* Simplification */
|
||||
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;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,34 +1,31 @@
|
||||
#ifndef POINCARE_OPPOSITE_H
|
||||
#define POINCARE_OPPOSITE_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/matrix.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/evaluation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Opposite : public Expression {
|
||||
class Opposite : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Opposite(Expression * operand, bool cloneOperands = true);
|
||||
~Opposite();
|
||||
Opposite(const Opposite& other) = delete;
|
||||
Opposite(Opposite&& other) = delete;
|
||||
Opposite& operator=(const Opposite& other) = delete;
|
||||
Opposite& operator=(Opposite&& other) = delete;
|
||||
bool hasValidNumberOfArguments() const override;
|
||||
const Expression * operand(int i) const override;
|
||||
int numberOfOperands() const override;
|
||||
Expression * clone() const override;
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression** newOperands,
|
||||
int numnerOfOperands, bool cloneOperands = true) const override;
|
||||
template<typename T> static Complex<T> compute(const Complex<T> c);
|
||||
template<typename T> static Evaluation<T> * computeOnMatrix(Evaluation<T> * m);
|
||||
template<typename T> static Complex<T> compute(const Complex<T> c, AngleUnit angleUnit);
|
||||
private:
|
||||
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
|
||||
/* Layout */
|
||||
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
|
||||
Expression * m_operand;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const override;
|
||||
/* 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 * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
|
||||
return EvaluationEngine::map<double>(this, context, angleUnit, compute<double>);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user