mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[poincare] Clean Expression and Layout builders
Before: Opposite(Opposite(Rational(1))) misleadingly created the expression "-1"; now, Opposite::Builder(Opposite::Builder(Rational(1))) creates "--1"
This commit is contained in:
committed by
LeaNumworks
parent
b3d15d7e7f
commit
ac6f23684d
@@ -25,7 +25,7 @@ CalculationController::CalculationController(Responder * parentResponder, Button
|
||||
m_hideableCell(),
|
||||
m_store(store)
|
||||
{
|
||||
m_r2Layout = HorizontalLayout(CharLayout('r', KDFont::SmallFont), VerticalOffsetLayout(CharLayout('2', KDFont::SmallFont), VerticalOffsetLayoutNode::Type::Superscript));
|
||||
m_r2Layout = HorizontalLayout::Builder(CharLayout('r', KDFont::SmallFont), VerticalOffsetLayout::Builder(CharLayout('2', KDFont::SmallFont), VerticalOffsetLayoutNode::Type::Superscript));
|
||||
m_selectableTableView.setVerticalCellOverlap(0);
|
||||
m_selectableTableView.setBackgroundColor(Palette::WallScreenDark);
|
||||
m_selectableTableView.setMargins(k_margin, k_scrollBarMargin, k_scrollBarMargin, k_margin);
|
||||
|
||||
@@ -23,7 +23,7 @@ Layout CubicModel::layout() {
|
||||
CharLayout('a', KDFont::SmallFont),
|
||||
CharLayout(Ion::Charset::MiddleDot, KDFont::SmallFont),
|
||||
CharLayout('X', KDFont::SmallFont),
|
||||
VerticalOffsetLayout(
|
||||
VerticalOffsetLayout::Builder(
|
||||
CharLayout('3', KDFont::SmallFont),
|
||||
VerticalOffsetLayoutNode::Type::Superscript
|
||||
),
|
||||
@@ -31,7 +31,7 @@ Layout CubicModel::layout() {
|
||||
CharLayout('b', KDFont::SmallFont),
|
||||
CharLayout(Ion::Charset::MiddleDot, KDFont::SmallFont),
|
||||
CharLayout('X', KDFont::SmallFont),
|
||||
VerticalOffsetLayout(
|
||||
VerticalOffsetLayout::Builder(
|
||||
CharLayout('2', KDFont::SmallFont),
|
||||
VerticalOffsetLayoutNode::Type::Superscript
|
||||
),
|
||||
@@ -42,7 +42,7 @@ Layout CubicModel::layout() {
|
||||
CharLayout('+', KDFont::SmallFont),
|
||||
CharLayout('d', KDFont::SmallFont),
|
||||
};
|
||||
m_layout = HorizontalLayout(layoutChildren, 15);
|
||||
m_layout = HorizontalLayout::Builder(layoutChildren, 15);
|
||||
}
|
||||
return m_layout;
|
||||
}
|
||||
@@ -53,23 +53,23 @@ Expression CubicModel::simplifiedExpression(double * modelCoefficients, Poincare
|
||||
double c = modelCoefficients[2];
|
||||
double d = modelCoefficients[3];
|
||||
Expression addChildren[] = {
|
||||
Multiplication(
|
||||
Multiplication::Builder(
|
||||
Number::DecimalNumber(a),
|
||||
Power(
|
||||
Power::Builder(
|
||||
Symbol('x'),
|
||||
Decimal(3.0))),
|
||||
Multiplication(
|
||||
Multiplication::Builder(
|
||||
Number::DecimalNumber(b),
|
||||
Power(
|
||||
Power::Builder(
|
||||
Symbol('x'),
|
||||
Decimal(2.0))),
|
||||
Multiplication(
|
||||
Multiplication::Builder(
|
||||
Number::DecimalNumber(c),
|
||||
Symbol('x')),
|
||||
Number::DecimalNumber(d)
|
||||
};
|
||||
// a*x^3+b*x^2+c*x+d
|
||||
Expression result = Addition(addChildren, 4);
|
||||
Expression result = Addition::Builder(addChildren, 4);
|
||||
PoincareHelpers::Simplify(&result, *context);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@ Layout ExponentialModel::layout() {
|
||||
CharLayout('a', KDFont::SmallFont),
|
||||
CharLayout(Ion::Charset::MiddleDot, KDFont::SmallFont),
|
||||
CharLayout('e', KDFont::SmallFont),
|
||||
VerticalOffsetLayout(
|
||||
HorizontalLayout(
|
||||
VerticalOffsetLayout::Builder(
|
||||
HorizontalLayout::Builder(
|
||||
CharLayout('b', KDFont::SmallFont),
|
||||
CharLayout(Ion::Charset::MiddleDot, KDFont::SmallFont),
|
||||
CharLayout('X', KDFont::SmallFont)
|
||||
@@ -24,7 +24,7 @@ Layout ExponentialModel::layout() {
|
||||
VerticalOffsetLayoutNode::Type::Superscript
|
||||
)
|
||||
};
|
||||
m_layout = HorizontalLayout(layoutChildren, 4);
|
||||
m_layout = HorizontalLayout::Builder(layoutChildren, 4);
|
||||
}
|
||||
return m_layout;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ Layout LinearModel::layout() {
|
||||
CharLayout('+', KDFont::SmallFont),
|
||||
CharLayout('b', KDFont::SmallFont),
|
||||
};
|
||||
m_layout = HorizontalLayout(layoutChildren, 5);
|
||||
m_layout = HorizontalLayout::Builder(layoutChildren, 5);
|
||||
}
|
||||
return m_layout;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ Layout LogarithmicModel::layout() {
|
||||
CharLayout('+', KDFont::SmallFont),
|
||||
CharLayout('b', KDFont::SmallFont)
|
||||
};
|
||||
m_layout = HorizontalLayout(layoutChildren, 9);
|
||||
m_layout = HorizontalLayout::Builder(layoutChildren, 9);
|
||||
}
|
||||
return m_layout;
|
||||
}
|
||||
|
||||
@@ -24,14 +24,14 @@ Layout LogisticModel::layout() {
|
||||
CharLayout('a', KDFont::SmallFont),
|
||||
CharLayout(Ion::Charset::MiddleDot, KDFont::SmallFont),
|
||||
CharLayout('e', KDFont::SmallFont),
|
||||
VerticalOffsetLayout(
|
||||
HorizontalLayout(exponentLayoutChildren, 4),
|
||||
VerticalOffsetLayout::Builder(
|
||||
HorizontalLayout::Builder(exponentLayoutChildren, 4),
|
||||
VerticalOffsetLayoutNode::Type::Superscript
|
||||
)
|
||||
};
|
||||
m_layout = FractionLayout(
|
||||
m_layout = FractionLayout::Builder(
|
||||
CharLayout('c', KDFont::SmallFont),
|
||||
HorizontalLayout(layoutChildren, 6)
|
||||
HorizontalLayout::Builder(layoutChildren, 6)
|
||||
);
|
||||
}
|
||||
return m_layout;
|
||||
|
||||
@@ -16,12 +16,12 @@ Layout PowerModel::layout() {
|
||||
CharLayout('a', KDFont::SmallFont),
|
||||
CharLayout(Ion::Charset::MiddleDot, KDFont::SmallFont),
|
||||
CharLayout('X', KDFont::SmallFont),
|
||||
VerticalOffsetLayout(
|
||||
VerticalOffsetLayout::Builder(
|
||||
CharLayout('b', KDFont::SmallFont),
|
||||
VerticalOffsetLayoutNode::Type::Superscript
|
||||
),
|
||||
};
|
||||
m_layout = HorizontalLayout(layoutChildren, 4);
|
||||
m_layout = HorizontalLayout::Builder(layoutChildren, 4);
|
||||
}
|
||||
return m_layout;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ Layout QuadraticModel::layout() {
|
||||
CharLayout('a', KDFont::SmallFont),
|
||||
CharLayout(Ion::Charset::MiddleDot, KDFont::SmallFont),
|
||||
CharLayout('X', KDFont::SmallFont),
|
||||
VerticalOffsetLayout(
|
||||
VerticalOffsetLayout::Builder(
|
||||
CharLayout('2', KDFont::SmallFont),
|
||||
VerticalOffsetLayoutNode::Type::Superscript
|
||||
),
|
||||
@@ -34,7 +34,7 @@ Layout QuadraticModel::layout() {
|
||||
CharLayout('+', KDFont::SmallFont),
|
||||
CharLayout('c', KDFont::SmallFont),
|
||||
};
|
||||
m_layout = HorizontalLayout(layoutChildren, 10);
|
||||
m_layout = HorizontalLayout::Builder(layoutChildren, 10);
|
||||
}
|
||||
return m_layout;
|
||||
}
|
||||
@@ -45,17 +45,17 @@ Expression QuadraticModel::simplifiedExpression(double * modelCoefficients, Poin
|
||||
double c = modelCoefficients[2];
|
||||
// a*x^2+b*x+c
|
||||
Expression addChildren[] = {
|
||||
Multiplication(
|
||||
Multiplication::Builder(
|
||||
Number::DecimalNumber(a),
|
||||
Power(
|
||||
Power::Builder(
|
||||
Symbol('x'),
|
||||
Decimal(2.0))),
|
||||
Multiplication(
|
||||
Multiplication::Builder(
|
||||
Number::DecimalNumber(b),
|
||||
Symbol('x')),
|
||||
Number::DecimalNumber(c)
|
||||
};
|
||||
Expression result = Addition(addChildren, 3);
|
||||
Expression result = Addition::Builder(addChildren, 3);
|
||||
PoincareHelpers::Simplify(&result, *context);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ Layout QuarticModel::layout() {
|
||||
CharLayout('a', KDFont::SmallFont),
|
||||
CharLayout(Ion::Charset::MiddleDot, KDFont::SmallFont),
|
||||
CharLayout('X', KDFont::SmallFont),
|
||||
VerticalOffsetLayout(
|
||||
VerticalOffsetLayout::Builder(
|
||||
CharLayout('4', KDFont::SmallFont),
|
||||
VerticalOffsetLayoutNode::Type::Superscript
|
||||
),
|
||||
@@ -31,7 +31,7 @@ Layout QuarticModel::layout() {
|
||||
CharLayout('b', KDFont::SmallFont),
|
||||
CharLayout(Ion::Charset::MiddleDot, KDFont::SmallFont),
|
||||
CharLayout('X', KDFont::SmallFont),
|
||||
VerticalOffsetLayout(
|
||||
VerticalOffsetLayout::Builder(
|
||||
CharLayout('3', KDFont::SmallFont),
|
||||
VerticalOffsetLayoutNode::Type::Superscript
|
||||
),
|
||||
@@ -39,7 +39,7 @@ Layout QuarticModel::layout() {
|
||||
CharLayout('c', KDFont::SmallFont),
|
||||
CharLayout(Ion::Charset::MiddleDot, KDFont::SmallFont),
|
||||
CharLayout('X', KDFont::SmallFont),
|
||||
VerticalOffsetLayout(
|
||||
VerticalOffsetLayout::Builder(
|
||||
CharLayout('2', KDFont::SmallFont),
|
||||
VerticalOffsetLayoutNode::Type::Superscript
|
||||
),
|
||||
@@ -50,7 +50,7 @@ Layout QuarticModel::layout() {
|
||||
CharLayout('+', KDFont::SmallFont),
|
||||
CharLayout('e', KDFont::SmallFont),
|
||||
};
|
||||
m_layout = HorizontalLayout(layoutChildren, 20);
|
||||
m_layout = HorizontalLayout::Builder(layoutChildren, 20);
|
||||
}
|
||||
return m_layout;
|
||||
}
|
||||
@@ -63,31 +63,31 @@ Expression QuarticModel::simplifiedExpression(double * modelCoefficients, Poinca
|
||||
double e = modelCoefficients[4];
|
||||
Expression addChildren[] = {
|
||||
// a*x^4
|
||||
Multiplication(
|
||||
Multiplication::Builder(
|
||||
Number::DecimalNumber(a),
|
||||
Power(
|
||||
Power::Builder(
|
||||
Symbol('x'),
|
||||
Decimal(4.0))),
|
||||
// b*x^3
|
||||
Multiplication(
|
||||
Multiplication::Builder(
|
||||
Number::DecimalNumber(b),
|
||||
Power(
|
||||
Power::Builder(
|
||||
Symbol('x'),
|
||||
Decimal(3.0))),
|
||||
// c*x^2
|
||||
Multiplication(
|
||||
Multiplication::Builder(
|
||||
Number::DecimalNumber(c),
|
||||
Power(
|
||||
Power::Builder(
|
||||
Symbol('x'),
|
||||
Decimal(2.0))),
|
||||
// d*x
|
||||
Multiplication(
|
||||
Multiplication::Builder(
|
||||
Number::DecimalNumber(d),
|
||||
Symbol('x')),
|
||||
// e
|
||||
Number::DecimalNumber(e)
|
||||
};
|
||||
Expression result = Addition(addChildren, 5);
|
||||
Expression result = Addition::Builder(addChildren, 5);
|
||||
PoincareHelpers::Simplify(&result, *context);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ Layout TrigonometricModel::layout() {
|
||||
CharLayout('+', KDFont::SmallFont),
|
||||
CharLayout('d', KDFont::SmallFont)
|
||||
};
|
||||
m_layout = HorizontalLayout(layoutChildren, 14);
|
||||
m_layout = HorizontalLayout::Builder(layoutChildren, 14);
|
||||
}
|
||||
return m_layout;
|
||||
}
|
||||
@@ -48,12 +48,12 @@ Expression TrigonometricModel::simplifiedExpression(double * modelCoefficients,
|
||||
double d = modelCoefficients[3];
|
||||
// a*sin(bx+c)+d
|
||||
Expression result =
|
||||
Addition(
|
||||
Multiplication(
|
||||
Addition::Builder(
|
||||
Multiplication::Builder(
|
||||
Number::DecimalNumber(a),
|
||||
Sine::Builder(
|
||||
Addition(
|
||||
Multiplication(
|
||||
Addition::Builder(
|
||||
Multiplication::Builder(
|
||||
Number::DecimalNumber(b),
|
||||
Symbol('x')),
|
||||
Number::DecimalNumber(c)))),
|
||||
|
||||
@@ -50,9 +50,9 @@ double TermSumController::cursorNextStep(double x, int direction) {
|
||||
}
|
||||
|
||||
Layout TermSumController::createFunctionLayout(const char * functionName) {
|
||||
return HorizontalLayout(
|
||||
return HorizontalLayout::Builder(
|
||||
CharLayout(functionName[0], KDFont::SmallFont),
|
||||
VerticalOffsetLayout(
|
||||
VerticalOffsetLayout::Builder(
|
||||
CharLayout('n', KDFont::SmallFont),
|
||||
VerticalOffsetLayoutNode::Type::Subscript
|
||||
)
|
||||
|
||||
@@ -76,20 +76,20 @@ void SequenceToolbox::buildExtraCellsLayouts(const char * sequenceName, int recu
|
||||
const char * otherSequenceName = SequenceStore::k_sequenceNames[1-sequenceIndex];
|
||||
for (int j = 0; j < recurrenceDepth; j++) {
|
||||
const char * indice = j == 0 ? "n" : "n+1";
|
||||
m_addedCellLayout[j] = HorizontalLayout(
|
||||
m_addedCellLayout[j] = HorizontalLayout::Builder(
|
||||
CharLayout(sequenceName[0], KDFont::LargeFont),
|
||||
VerticalOffsetLayout(LayoutHelper::String(indice, strlen(indice), KDFont::LargeFont), VerticalOffsetLayoutNode::Type::Subscript)
|
||||
VerticalOffsetLayout::Builder(LayoutHelper::String(indice, strlen(indice), KDFont::LargeFont), VerticalOffsetLayoutNode::Type::Subscript)
|
||||
);
|
||||
m_addedCellLayout[j+recurrenceDepth] = HorizontalLayout(
|
||||
m_addedCellLayout[j+recurrenceDepth] = HorizontalLayout::Builder(
|
||||
CharLayout(otherSequenceName[0], KDFont::LargeFont),
|
||||
VerticalOffsetLayout(LayoutHelper::String(indice, strlen(indice), KDFont::LargeFont), VerticalOffsetLayoutNode::Type::Subscript)
|
||||
VerticalOffsetLayout::Builder(LayoutHelper::String(indice, strlen(indice), KDFont::LargeFont), VerticalOffsetLayoutNode::Type::Subscript)
|
||||
);
|
||||
}
|
||||
if (recurrenceDepth < 2) {
|
||||
const char * indice = recurrenceDepth == 0 ? "n" : (recurrenceDepth == 1 ? "n+1" : "n+2");
|
||||
m_addedCellLayout[2*recurrenceDepth] = HorizontalLayout(
|
||||
m_addedCellLayout[2*recurrenceDepth] = HorizontalLayout::Builder(
|
||||
CharLayout(otherSequenceName[0], KDFont::LargeFont),
|
||||
VerticalOffsetLayout(LayoutHelper::String(indice, strlen(indice), KDFont::LargeFont), VerticalOffsetLayoutNode::Type::Subscript)
|
||||
VerticalOffsetLayout::Builder(LayoutHelper::String(indice, strlen(indice), KDFont::LargeFont), VerticalOffsetLayoutNode::Type::Subscript)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,9 +115,9 @@ void TypeParameterController::willDisplayCellAtLocation(HighlightCell * cell, in
|
||||
font = KDFont::SmallFont;
|
||||
}
|
||||
const char * subscripts[3] = {"n", "n+1", "n+2"};
|
||||
m_layouts[j] = HorizontalLayout(
|
||||
m_layouts[j] = HorizontalLayout::Builder(
|
||||
CharLayout(nextName[0], font),
|
||||
VerticalOffsetLayout(LayoutHelper::String(subscripts[j], strlen(subscripts[j]), font), VerticalOffsetLayoutNode::Type::Subscript)
|
||||
VerticalOffsetLayout::Builder(LayoutHelper::String(subscripts[j], strlen(subscripts[j]), font), VerticalOffsetLayoutNode::Type::Subscript)
|
||||
);
|
||||
ExpressionTableCellWithPointer * myCell = (ExpressionTableCellWithPointer *)cell;
|
||||
myCell->setLayout(m_layouts[j]);
|
||||
|
||||
@@ -146,9 +146,9 @@ int Sequence::numberOfElements() {
|
||||
|
||||
Poincare::Layout Sequence::nameLayout() {
|
||||
if (m_nameLayout.isUninitialized()) {
|
||||
m_nameLayout = HorizontalLayout(
|
||||
m_nameLayout = HorizontalLayout::Builder(
|
||||
CharLayout(name()[0], KDFont::SmallFont),
|
||||
VerticalOffsetLayout(CharLayout('n', KDFont::SmallFont), VerticalOffsetLayoutNode::Type::Subscript)
|
||||
VerticalOffsetLayout::Builder(CharLayout('n', KDFont::SmallFont), VerticalOffsetLayoutNode::Type::Subscript)
|
||||
);
|
||||
}
|
||||
return m_nameLayout;
|
||||
@@ -157,18 +157,18 @@ Poincare::Layout Sequence::nameLayout() {
|
||||
Poincare::Layout Sequence::definitionName() {
|
||||
if (m_definitionName.isUninitialized()) {
|
||||
if (m_type == Type::Explicit) {
|
||||
m_definitionName = HorizontalLayout(
|
||||
m_definitionName = HorizontalLayout::Builder(
|
||||
CharLayout(name()[0], k_layoutFont),
|
||||
VerticalOffsetLayout(LayoutHelper::String("n", 1, k_layoutFont), VerticalOffsetLayoutNode::Type::Subscript));
|
||||
VerticalOffsetLayout::Builder(LayoutHelper::String("n", 1, k_layoutFont), VerticalOffsetLayoutNode::Type::Subscript));
|
||||
} else if (m_type == Type::SingleRecurrence) {
|
||||
m_definitionName = HorizontalLayout(
|
||||
m_definitionName = HorizontalLayout::Builder(
|
||||
CharLayout(name()[0], k_layoutFont),
|
||||
VerticalOffsetLayout(LayoutHelper::String("n+1", 3, k_layoutFont), VerticalOffsetLayoutNode::Type::Subscript));
|
||||
VerticalOffsetLayout::Builder(LayoutHelper::String("n+1", 3, k_layoutFont), VerticalOffsetLayoutNode::Type::Subscript));
|
||||
} else {
|
||||
assert(m_type == Type::DoubleRecurrence);
|
||||
m_definitionName = HorizontalLayout(
|
||||
m_definitionName = HorizontalLayout::Builder(
|
||||
CharLayout(name()[0], k_layoutFont),
|
||||
VerticalOffsetLayout(LayoutHelper::String("n+2", 3, k_layoutFont), VerticalOffsetLayoutNode::Type::Subscript));
|
||||
VerticalOffsetLayout::Builder(LayoutHelper::String("n+2", 3, k_layoutFont), VerticalOffsetLayoutNode::Type::Subscript));
|
||||
}
|
||||
}
|
||||
return m_definitionName;
|
||||
@@ -182,9 +182,9 @@ Poincare::Layout Sequence::firstInitialConditionName() {
|
||||
|| m_type == Type::DoubleRecurrence))
|
||||
{
|
||||
Layout indexLayout = LayoutHelper::String(buffer, strlen(buffer), k_layoutFont);
|
||||
m_firstInitialConditionName = HorizontalLayout(
|
||||
m_firstInitialConditionName = HorizontalLayout::Builder(
|
||||
CharLayout(name()[0], k_layoutFont),
|
||||
VerticalOffsetLayout(indexLayout, VerticalOffsetLayoutNode::Type::Subscript));
|
||||
VerticalOffsetLayout::Builder(indexLayout, VerticalOffsetLayoutNode::Type::Subscript));
|
||||
}
|
||||
return m_firstInitialConditionName;
|
||||
}
|
||||
@@ -195,9 +195,9 @@ Poincare::Layout Sequence::secondInitialConditionName() {
|
||||
if (m_secondInitialConditionName.isUninitialized()) {
|
||||
if (m_type == Type::DoubleRecurrence) {
|
||||
Layout indexLayout = LayoutHelper::String(buffer, strlen(buffer), k_layoutFont);
|
||||
m_secondInitialConditionName = HorizontalLayout(
|
||||
m_secondInitialConditionName = HorizontalLayout::Builder(
|
||||
CharLayout(name()[0], k_layoutFont),
|
||||
VerticalOffsetLayout(indexLayout, VerticalOffsetLayoutNode::Type::Subscript));
|
||||
VerticalOffsetLayout::Builder(indexLayout, VerticalOffsetLayoutNode::Type::Subscript));
|
||||
}
|
||||
}
|
||||
return m_secondInitialConditionName;
|
||||
|
||||
@@ -60,7 +60,7 @@ Layout layoutForPreferences(I18n::Message message) {
|
||||
case I18n::Message::Radian:
|
||||
{
|
||||
const char pi[] = {Ion::Charset::SmallPi};
|
||||
return FractionLayout(
|
||||
return FractionLayout::Builder(
|
||||
LayoutHelper::String(pi, sizeof(pi), KDFont::SmallFont),
|
||||
LayoutHelper::String("2", 1, KDFont::SmallFont)
|
||||
);
|
||||
@@ -75,9 +75,9 @@ Layout layoutForPreferences(I18n::Message message) {
|
||||
}
|
||||
// Edition mode
|
||||
case I18n::Message::Edition2D:
|
||||
return HorizontalLayout(
|
||||
return HorizontalLayout::Builder(
|
||||
LayoutHelper::String("1+", 2, KDFont::SmallFont),
|
||||
FractionLayout(LayoutHelper::String("2", 1, KDFont::SmallFont), LayoutHelper::String("3", 1, KDFont::SmallFont))
|
||||
FractionLayout::Builder(LayoutHelper::String("2", 1, KDFont::SmallFont), LayoutHelper::String("3", 1, KDFont::SmallFont))
|
||||
);
|
||||
case I18n::Message::EditionLinear:
|
||||
return LayoutHelper::String("1+2/3", 5, KDFont::SmallFont);
|
||||
@@ -95,9 +95,9 @@ Layout layoutForPreferences(I18n::Message message) {
|
||||
{
|
||||
const char base[] = {'r', Ion::Charset::Exponential};
|
||||
const char superscript[] = {Ion::Charset::IComplex, Ion::Charset::SmallTheta};
|
||||
return HorizontalLayout(
|
||||
return HorizontalLayout::Builder(
|
||||
LayoutHelper::String(base, sizeof(base), KDFont::SmallFont),
|
||||
VerticalOffsetLayout(LayoutHelper::String(superscript, sizeof(superscript), KDFont::SmallFont), VerticalOffsetLayoutNode::Type::Superscript)
|
||||
VerticalOffsetLayout::Builder(LayoutHelper::String(superscript, sizeof(superscript), KDFont::SmallFont), VerticalOffsetLayoutNode::Type::Superscript)
|
||||
);
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -60,7 +60,7 @@ Layout StorageExpressionModel::layout() {
|
||||
if (m_layout.isUninitialized()) {
|
||||
m_layout = PoincareHelpers::CreateLayout(expressionClone());
|
||||
if (m_layout.isUninitialized()) {
|
||||
m_layout = HorizontalLayout();
|
||||
m_layout = HorizontalLayout::Builder();
|
||||
}
|
||||
}
|
||||
return m_layout;
|
||||
|
||||
@@ -240,7 +240,7 @@ void StorageSumGraphController::LegendView::setSumSymbol(Step step, double start
|
||||
} else if (step == Step::SecondParameter) {
|
||||
char buffer[PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits)];
|
||||
PrintFloat::convertFloatToText<double>(start, buffer, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits), Constant::MediumNumberOfSignificantDigits, Preferences::PrintFloatMode::Decimal);
|
||||
m_sumLayout = CondensedSumLayout(
|
||||
m_sumLayout = CondensedSumLayout::Builder(
|
||||
LayoutHelper::String(sigma, sizeof(sigma)),
|
||||
LayoutHelper::String(buffer, strlen(buffer), k_font),
|
||||
EmptyLayout(EmptyLayoutNode::Color::Yellow, false, k_font, false));
|
||||
@@ -251,13 +251,13 @@ void StorageSumGraphController::LegendView::setSumSymbol(Step step, double start
|
||||
Layout start = LayoutHelper::String(buffer, strlen(buffer), KDFont::SmallFont);
|
||||
PrintFloat::convertFloatToText<double>(end, buffer, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, Preferences::PrintFloatMode::Decimal);
|
||||
Layout end = LayoutHelper::String(buffer, strlen(buffer), k_font);
|
||||
m_sumLayout = CondensedSumLayout(
|
||||
m_sumLayout = CondensedSumLayout::Builder(
|
||||
LayoutHelper::String(sigma, sizeof(sigma)),
|
||||
start,
|
||||
end);
|
||||
strlcpy(buffer, "= ", 3);
|
||||
PoincareHelpers::ConvertFloatToText<double>(result, buffer+2, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits);
|
||||
m_sumLayout = HorizontalLayout(
|
||||
m_sumLayout = HorizontalLayout::Builder(
|
||||
m_sumLayout,
|
||||
functionLayout,
|
||||
LayoutHelper::String(buffer, strlen(buffer), k_font));
|
||||
|
||||
@@ -239,7 +239,7 @@ void SumGraphController::LegendView::setSumSymbol(Step step, double start, doubl
|
||||
} else if (step == Step::SecondParameter) {
|
||||
char buffer[PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits)];
|
||||
PrintFloat::convertFloatToText<double>(start, buffer, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits), Constant::MediumNumberOfSignificantDigits, Preferences::PrintFloatMode::Decimal);
|
||||
m_sumLayout = CondensedSumLayout(
|
||||
m_sumLayout = CondensedSumLayout::Builder(
|
||||
LayoutHelper::String(sigma, sizeof(sigma)),
|
||||
LayoutHelper::String(buffer, strlen(buffer), KDFont::SmallFont),
|
||||
EmptyLayout(EmptyLayoutNode::Color::Yellow, false, KDFont::SmallFont, false));
|
||||
@@ -251,13 +251,13 @@ void SumGraphController::LegendView::setSumSymbol(Step step, double start, doubl
|
||||
Layout start = LayoutHelper::String(buffer, strlen(buffer), KDFont::SmallFont);
|
||||
PrintFloat::convertFloatToText<double>(end, buffer, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, Preferences::PrintFloatMode::Decimal);
|
||||
Layout end = LayoutHelper::String(buffer, strlen(buffer), KDFont::SmallFont);
|
||||
m_sumLayout = CondensedSumLayout(
|
||||
m_sumLayout = CondensedSumLayout::Builder(
|
||||
LayoutHelper::String(sigma, sizeof(sigma)),
|
||||
start,
|
||||
end);
|
||||
strlcpy(buffer, "= ", bufferSize);
|
||||
PoincareHelpers::ConvertFloatToText<double>(result, buffer+2, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits);
|
||||
m_sumLayout = HorizontalLayout(
|
||||
m_sumLayout = HorizontalLayout::Builder(
|
||||
m_sumLayout,
|
||||
functionLayout,
|
||||
LayoutHelper::String(buffer, strlen(buffer), KDFont::SmallFont));
|
||||
|
||||
@@ -211,7 +211,7 @@ EquationStore::Error EquationStore::resolveLinearSystem(Expression exactSolution
|
||||
while (m_variables[n][0] != 0) { n++; }
|
||||
int m = numberOfDefinedModels(); // m equations
|
||||
/* Create the matrix (A | b) for the equation Ax=b */
|
||||
Matrix Ab;
|
||||
Matrix Ab = Matrix::Builder();
|
||||
for (int i = 0; i < m; i++) {
|
||||
for (int j = 0; j < n; j++) {
|
||||
Ab.addChildAtIndexInPlace(coefficients[i][j], Ab.numberOfChildren(), Ab.numberOfChildren());
|
||||
@@ -257,20 +257,20 @@ EquationStore::Error EquationStore::oneDimensialPolynomialSolve(Expression exact
|
||||
/* Equation ax^2+bx+c = 0 */
|
||||
assert(degree == 2);
|
||||
// Compute delta = b*b-4ac
|
||||
Expression delta = Subtraction(Power(coefficients[1].clone(), Rational(2)), Multiplication(Rational(4), coefficients[0].clone(), coefficients[2].clone()));
|
||||
Expression delta = Subtraction::Builder(Power::Builder(coefficients[1].clone(), Rational(2)), Multiplication::Builder(Rational(4), coefficients[0].clone(), coefficients[2].clone()));
|
||||
delta = delta.simplify(*context, updatedComplexFormat(), Poincare::Preferences::sharedPreferences()->angleUnit());
|
||||
if (delta.isUninitialized()) {
|
||||
delta = Poincare::Undefined();
|
||||
}
|
||||
if (delta.isRationalZero()) {
|
||||
// if delta = 0, x0=x1= -b/(2a)
|
||||
exactSolutions[0] = Division(Opposite(coefficients[1]), Multiplication(Rational(2), coefficients[2]));
|
||||
exactSolutions[0] = Division::Builder(Opposite::Builder(coefficients[1]), Multiplication::Builder(Rational(2), coefficients[2]));
|
||||
m_numberOfSolutions = 2;
|
||||
} else {
|
||||
// x0 = (-b-sqrt(delta))/(2a)
|
||||
exactSolutions[0] = Division(Subtraction(Opposite(coefficients[1].clone()), SquareRoot::Builder(delta.clone())), Multiplication(Rational(2), coefficients[2].clone()));
|
||||
exactSolutions[0] = Division::Builder(Subtraction::Builder(Opposite::Builder(coefficients[1].clone()), SquareRoot::Builder(delta.clone())), Multiplication::Builder(Rational(2), coefficients[2].clone()));
|
||||
// x1 = (-b+sqrt(delta))/(2a)
|
||||
exactSolutions[1] = Division(Addition(Opposite(coefficients[1]), SquareRoot::Builder(delta.clone())), Multiplication(Rational(2), coefficients[2]));
|
||||
exactSolutions[1] = Division::Builder(Addition::Builder(Opposite::Builder(coefficients[1]), SquareRoot::Builder(delta.clone())), Multiplication::Builder(Rational(2), coefficients[2]));
|
||||
m_numberOfSolutions = 3;
|
||||
}
|
||||
exactSolutions[m_numberOfSolutions-1] = delta;
|
||||
@@ -285,23 +285,23 @@ EquationStore::Error EquationStore::oneDimensialPolynomialSolve(Expression exact
|
||||
Expression * c = coefficients[1];
|
||||
Expression * d = coefficients[0];
|
||||
// Delta = b^2*c^2+18abcd-27a^2*d^2-4ac^3-4db^3
|
||||
Expression * mult0Operands[2] = {new Power(b->clone(), new Rational(2), false), new Power(c->clone(), new Rational(2), false)};
|
||||
Expression * mult0Operands[2] = {new Power::Builder(b->clone(), new Rational(2), false), new Power::Builder(c->clone(), new Rational(2), false)};
|
||||
Expression * mult1Operands[5] = {new Rational(18), a->clone(), b->clone(), c->clone(), d->clone()};
|
||||
Expression * mult2Operands[3] = {new Rational(-27), new Power(a->clone(), new Rational(2), false), new Power(d->clone(), new Rational(2), false)};
|
||||
Expression * mult3Operands[3] = {new Rational(-4), a->clone(), new Power(c->clone(), new Rational(3), false)};
|
||||
Expression * mult4Operands[3] = {new Rational(-4), d->clone(), new Power(b->clone(), new Rational(3), false)};
|
||||
Expression * add0Operands[5] = {new Multiplication(mult0Operands, 2, false), new Multiplication(mult1Operands, 5, false), new Multiplication(mult2Operands, 3, false), new Multiplication(mult3Operands, 3, false), new Multiplication(mult4Operands, 3, false)};
|
||||
Expression * mult2Operands[3] = {new Rational(-27), new Power::Builder(a->clone(), new Rational(2), false), new Power::Builder(d->clone(), new Rational(2), false)};
|
||||
Expression * mult3Operands[3] = {new Rational(-4), a->clone(), new Power::Builder(c->clone(), new Rational(3), false)};
|
||||
Expression * mult4Operands[3] = {new Rational(-4), d->clone(), new Power::Builder(b->clone(), new Rational(3), false)};
|
||||
Expression * add0Operands[5] = {new Multiplication::Builder(mult0Operands, 2, false), new Multiplication::Builder(mult1Operands, 5, false), new Multiplication::Builder(mult2Operands, 3, false), new Multiplication::Builder(mult3Operands, 3, false), new Multiplication::Builder(mult4Operands, 3, false)};
|
||||
Expression * delta = new Addition(add0Operands, 5, false);
|
||||
PoincareHelpers::Simplify(&delta, *context);
|
||||
// Delta0 = b^2-3ac
|
||||
Expression * mult5Operands[3] = {new Rational(3), a->clone(), c->clone()};
|
||||
Expression * delta0 = new Subtraction(new Power(b->clone(), new Rational(2), false), new Multiplication(mult5Operands, 3, false), false);
|
||||
Expression * delta0 = new Subtraction::Builder(new Power::Builder(b->clone(), new Rational(2), false), new Multiplication::Builder(mult5Operands, 3, false), false);
|
||||
Reduce(&delta0, *context);
|
||||
if (delta->isRationalZero()) {
|
||||
if (delta0->isRationalZero()) {
|
||||
// delta0 = 0 && delta = 0 --> x0 = -b/(3a)
|
||||
delete delta0;
|
||||
m_exactSolutions[0] = new Opposite(new Division(b, new Multiplication(new Rational(3), a, false), false), false);
|
||||
m_exactSolutions[0] = new Opposite::Builder(new Division::Builder(b, new Multiplication::Builder(new Rational(3), a, false), false), false);
|
||||
m_numberOfSolutions = 1;
|
||||
delete c;
|
||||
delete d;
|
||||
@@ -309,33 +309,33 @@ EquationStore::Error EquationStore::oneDimensialPolynomialSolve(Expression exact
|
||||
// delta = 0 --> x0 = (9ad-bc)/(2delta0)
|
||||
// --> x1 = (4abc-9a^2d-b^3)/(a*delta0)
|
||||
Expression * mult6Operands[3] = {new Rational(9), a, d};
|
||||
m_exactSolutions[0] = new Division(new Subtraction(new Multiplication(mult6Operands, 3, false), new Multiplication(b, c, false), false), new Multiplication(new Rational(2), delta0, false), false);
|
||||
m_exactSolutions[0] = new Division::Builder(new Subtraction::Builder(new Multiplication::Builder(mult6Operands, 3, false), new Multiplication::Builder(b, c, false), false), new Multiplication::Builder(new Rational(2), delta0, false), false);
|
||||
Expression * mult7Operands[4] = {new Rational(4), a->clone(), b->clone(), c->clone()};
|
||||
Expression * mult8Operands[3] = {new Rational(-9), new Power(a->clone(), new Rational(2), false), d->clone()};
|
||||
Expression * add1Operands[3] = {new Multiplication(mult7Operands, 4, false), new Multiplication(mult8Operands,3, false), new Opposite(new Power(b->clone(), new Rational(3), false), false)};
|
||||
m_exactSolutions[1] = new Division(new Addition(add1Operands, 3, false), new Multiplication(a->clone(), delta0, false), false);
|
||||
Expression * mult8Operands[3] = {new Rational(-9), new Power::Builder(a->clone(), new Rational(2), false), d->clone()};
|
||||
Expression * add1Operands[3] = {new Multiplication::Builder(mult7Operands, 4, false), new Multiplication::Builder(mult8Operands,3, false), new Opposite::Builder(new Power::Builder(b->clone(), new Rational(3), false), false)};
|
||||
m_exactSolutions[1] = new Division::Builder(new Addition(add1Operands, 3, false), new Multiplication::Builder(a->clone(), delta0, false), false);
|
||||
m_numberOfSolutions = 2;
|
||||
}
|
||||
} else {
|
||||
// delta1 = 2b^3-9abc+27a^2*d
|
||||
Expression * mult9Operands[4] = {new Rational(-9), a, b, c};
|
||||
Expression * mult10Operands[3] = {new Rational(27), new Power(a->clone(), new Rational(2), false), d};
|
||||
Expression * add2Operands[3] = {new Multiplication(new Rational(2), new Power(b->clone(), new Rational(3), false), false), new Multiplication(mult9Operands, 4, false), new Multiplication(mult10Operands, 3, false)};
|
||||
Expression * mult10Operands[3] = {new Rational(27), new Power::Builder(a->clone(), new Rational(2), false), d};
|
||||
Expression * add2Operands[3] = {new Multiplication::Builder(new Rational(2), new Power::Builder(b->clone(), new Rational(3), false), false), new Multiplication::Builder(mult9Operands, 4, false), new Multiplication::Builder(mult10Operands, 3, false)};
|
||||
Expression * delta1 = new Addition(add2Operands, 3, false);
|
||||
// C = Root((delta1+sqrt(-27a^2*delta))/2, 3)
|
||||
Expression * mult11Operands[3] = {new Rational(-27), new Power(a->clone(), new Rational(2), false), (*delta)->clone()};
|
||||
Expression * c = new Power(new Division(new Addition(delta1, new SquareRoot(new Multiplication(mult11Operands, 3, false), false), false), new Rational(2), false), new Rational(1,3), false);
|
||||
Expression * unary3roots[2] = {new Addition(new Rational(-1,2), new Division(new Multiplication(new SquareRoot(new Rational(3), false), new Constant(Ion::Charset::IComplex), false), new Rational(2), false), false), new Subtraction(new Rational(-1,2), new Division(new Multiplication(new SquareRoot(new Rational(3), false), new Constant(Ion::Charset::IComplex), false), new Rational(2), false), false)};
|
||||
Expression * mult11Operands[3] = {new Rational(-27), new Power::Builder(a->clone(), new Rational(2), false), (*delta)->clone()};
|
||||
Expression * c = new Power::Builder(new Division::Builder(new Addition(delta1, new SquareRoot(new Multiplication::Builder(mult11Operands, 3, false), false), false), new Rational(2), false), new Rational(1,3), false);
|
||||
Expression * unary3roots[2] = {new Addition(new Rational(-1,2), new Division::Builder(new Multiplication::Builder(new SquareRoot(new Rational(3), false), new Constant(Ion::Charset::IComplex), false), new Rational(2), false), false), new Subtraction::Builder(new Rational(-1,2), new Division::Builder(new Multiplication::Builder(new SquareRoot(new Rational(3), false), new Constant(Ion::Charset::IComplex), false), new Rational(2), false), false)};
|
||||
// x_k = -1/(3a)*(b+C*z+delta0/(zC)) with z = unary cube root
|
||||
for (int k = 0; k < 3; k++) {
|
||||
Expression * ccopy = c;
|
||||
Expression * delta0copy = delta0;
|
||||
if (k < 2) {
|
||||
ccopy = new Multiplication(c->clone(), unary3roots[k], false);
|
||||
ccopy = new Multiplication::Builder(c->clone(), unary3roots[k], false);
|
||||
delta0copy = delta0->clone();
|
||||
}
|
||||
Expression * add3Operands[3] = {b->clone(), ccopy, new Division(delta0copy, ccopy->clone(), false)};
|
||||
m_exactSolutions[k] = new Multiplication(new Division(new Rational(-1), new Multiplication(new Rational(3), a->clone(), false), false), new Addition(add3Operands, 3, false), false);
|
||||
Expression * add3Operands[3] = {b->clone(), ccopy, new Division::Builder(delta0copy, ccopy->clone(), false)};
|
||||
m_exactSolutions[k] = new Multiplication::Builder(new Division::Builder(new Rational(-1), new Multiplication::Builder(new Rational(3), a->clone(), false), false), new Addition(add3Operands, 3, false), false);
|
||||
}
|
||||
m_numberOfSolutions = 3;
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ SolutionsController::SolutionsController(Responder * parentResponder, EquationSt
|
||||
m_delta2Layout(),
|
||||
m_contentView(this)
|
||||
{
|
||||
m_delta2Layout = HorizontalLayout(VerticalOffsetLayout(CharLayout('2', KDFont::SmallFont), VerticalOffsetLayoutNode::Type::Superscript), LayoutHelper::String("-4ac", 4, KDFont::SmallFont));
|
||||
m_delta2Layout = HorizontalLayout::Builder(VerticalOffsetLayout::Builder(CharLayout('2', KDFont::SmallFont), VerticalOffsetLayoutNode::Type::Superscript), LayoutHelper::String("-4ac", 4, KDFont::SmallFont));
|
||||
char deltaB[] = {Ion::Charset::CapitalDelta, '=', 'b'};
|
||||
static_cast<HorizontalLayout&>(m_delta2Layout).addOrMergeChildAtIndex(LayoutHelper::String(deltaB, 3, KDFont::SmallFont), 0, false);
|
||||
for (int i = 0; i < EquationStore::k_maxNumberOfExactSolutions; i++) {
|
||||
|
||||
@@ -25,7 +25,7 @@ void LayoutField::ContentView::setEditing(bool isEditing) {
|
||||
}
|
||||
|
||||
void LayoutField::ContentView::clearLayout() {
|
||||
HorizontalLayout h;
|
||||
HorizontalLayout h = HorizontalLayout::Builder();
|
||||
m_expressionView.setLayout(h);
|
||||
m_cursor.setLayout(h);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@ private:
|
||||
|
||||
class AbsoluteValueLayout final : public Layout {
|
||||
public:
|
||||
static AbsoluteValueLayout Builder(Layout l) { return AbsoluteValueLayout(l); }
|
||||
private:
|
||||
explicit AbsoluteValueLayout(Layout l) :
|
||||
Layout(TreePool::sharedPool()->createTreeNode<AbsoluteValueLayoutNode>())
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define POINCARE_ADDITION_H
|
||||
|
||||
#include <poincare/approximation_helper.h>
|
||||
#include <poincare/array_builder.h>
|
||||
#include <poincare/n_ary_expression_node.h>
|
||||
#include <poincare/rational.h>
|
||||
|
||||
@@ -60,24 +61,23 @@ private:
|
||||
class Addition final : public NAryExpression {
|
||||
public:
|
||||
Addition(const AdditionNode * n) : NAryExpression(n) {}
|
||||
Addition();
|
||||
explicit Addition(Expression e1) : Addition() {
|
||||
addChildAtIndexInPlace(e1, 0, 0);
|
||||
}
|
||||
Addition(Expression e1, Expression e2) : Addition() {
|
||||
addChildAtIndexInPlace(e2, 0, 0);
|
||||
addChildAtIndexInPlace(e1, 0, numberOfChildren());
|
||||
}
|
||||
Addition(Expression * children, size_t numberOfChildren) : Addition() {
|
||||
static Addition Builder() { return Addition(); }
|
||||
static Addition Builder(Expression e1) { return Addition::Builder(&e1, 1); }
|
||||
static Addition Builder(Expression e1, Expression e2) { return Addition::Builder(ArrayBuilder<Expression>(e1, e2).array(), 2); }
|
||||
static Addition Builder(Expression * children, size_t numberOfChildren) {
|
||||
Addition a = Addition::Builder();
|
||||
for (size_t i = 0; i < numberOfChildren; i++) {
|
||||
addChildAtIndexInPlace(children[i], i, i);
|
||||
a.addChildAtIndexInPlace(children[i], i, i);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
// Expression
|
||||
Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target);
|
||||
Expression shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target);
|
||||
int getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const;
|
||||
private:
|
||||
Addition() : NAryExpression(TreePool::sharedPool()->createTreeNode<AdditionNode>()) {}
|
||||
|
||||
static const Number NumeralFactor(const Expression & e);
|
||||
static inline int NumberOfNonNumeralFactors(const Expression & e);
|
||||
static inline const Expression FirstNonNumeralFactor(const Expression & e);
|
||||
|
||||
20
poincare/include/poincare/array_builder.h
Normal file
20
poincare/include/poincare/array_builder.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef POINCARE_ARRAY_BUILDER_H
|
||||
#define POINCARE_ARRAY_BUILDER_H
|
||||
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
template <class T>
|
||||
class ArrayBuilder {
|
||||
public:
|
||||
ArrayBuilder(T e1 = T(), T e2 = T(), T e3 = T(), T e4 = T()) :
|
||||
m_data{e1, e2, e3, e4}
|
||||
{}
|
||||
T * array() { return const_cast<T *>(m_data); }
|
||||
private:
|
||||
T m_data[4];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -43,6 +43,9 @@ private:
|
||||
|
||||
class BinomialCoefficientLayout final : public Layout {
|
||||
public:
|
||||
static BinomialCoefficientLayout Builder(Layout n, Layout k) { return BinomialCoefficientLayout(n, k); }
|
||||
|
||||
private:
|
||||
BinomialCoefficientLayout(Layout n, Layout k) :
|
||||
Layout(TreePool::sharedPool()->createTreeNode<BinomialCoefficientLayoutNode>())
|
||||
{
|
||||
|
||||
@@ -30,6 +30,8 @@ protected:
|
||||
|
||||
class CeilingLayout final : public Layout {
|
||||
public:
|
||||
static CeilingLayout Builder(Layout l) { return CeilingLayout(l); }
|
||||
private:
|
||||
explicit CeilingLayout(Layout l) : Layout(TreePool::sharedPool()->createTreeNode<CeilingLayoutNode>()) {
|
||||
replaceChildAtIndexInPlace(0, l);
|
||||
}
|
||||
|
||||
@@ -51,7 +51,15 @@ private:
|
||||
|
||||
class CondensedSumLayout final : public Layout {
|
||||
public:
|
||||
CondensedSumLayout(Layout base, Layout subscript, Layout superscript);
|
||||
static CondensedSumLayout Builder(Layout base, Layout subscript, Layout superscript) { return CondensedSumLayout(base, subscript, superscript); }
|
||||
private:
|
||||
CondensedSumLayout(Layout base, Layout subscript, Layout superscript) :
|
||||
Layout(TreePool::sharedPool()->createTreeNode<CondensedSumLayoutNode>())
|
||||
{
|
||||
replaceChildAtIndexInPlace(0, base);
|
||||
replaceChildAtIndexInPlace(1, subscript);
|
||||
replaceChildAtIndexInPlace(2, superscript);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -40,6 +40,8 @@ private:
|
||||
|
||||
class ConjugateLayout final : public Layout {
|
||||
public:
|
||||
static ConjugateLayout Builder(Layout l) { return ConjugateLayout(l); }
|
||||
private:
|
||||
explicit ConjugateLayout(Layout l) : Layout(TreePool::sharedPool()->createTreeNode<ConjugateLayoutNode>()) {
|
||||
replaceChildAtIndexInPlace(0, l);
|
||||
}
|
||||
|
||||
@@ -60,14 +60,19 @@ private:
|
||||
|
||||
class Division final : public Expression {
|
||||
public:
|
||||
Division();
|
||||
Division(Expression numerator, Expression denominator) : Division() {
|
||||
replaceChildAtIndexInPlace(0, numerator);
|
||||
replaceChildAtIndexInPlace(1, denominator);
|
||||
}
|
||||
Division(const DivisionNode * n) : Expression(n) {}
|
||||
static Division Builder() { return Division(); }
|
||||
static Division Builder(Expression numerator, Expression denominator) {
|
||||
Division d;
|
||||
d.replaceChildAtIndexInPlace(0, numerator);
|
||||
d.replaceChildAtIndexInPlace(1, denominator);
|
||||
return d;
|
||||
}
|
||||
|
||||
Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target);
|
||||
|
||||
private:
|
||||
Division() : Expression(TreePool::sharedPool()->createTreeNode<DivisionNode>()) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -51,16 +51,19 @@ private:
|
||||
|
||||
class Factorial final : public Expression {
|
||||
public:
|
||||
Factorial();
|
||||
Factorial(const FactorialNode * n) : Expression(n) {}
|
||||
explicit Factorial(Expression child) : Factorial() {
|
||||
replaceChildAtIndexInPlace(0, child);
|
||||
static Factorial Builder() { return Factorial(); }
|
||||
static Factorial Builder(Expression child) {
|
||||
Factorial f;
|
||||
f.replaceChildAtIndexInPlace(0, child);
|
||||
return f;
|
||||
}
|
||||
|
||||
Expression shallowReduce();
|
||||
Expression shallowBeautify();
|
||||
private:
|
||||
constexpr static int k_maxOperandValue = 100;
|
||||
Factorial() : Expression(TreePool::sharedPool()->createTreeNode<FactorialNode>()) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@ protected:
|
||||
|
||||
class FloorLayout final : public Layout {
|
||||
public:
|
||||
static FloorLayout Builder(Layout l) { return FloorLayout(l); }
|
||||
private:
|
||||
explicit FloorLayout(Layout l) : Layout(TreePool::sharedPool()->createTreeNode<FloorLayoutNode>()) {
|
||||
replaceChildAtIndexInPlace(0, l);
|
||||
}
|
||||
|
||||
@@ -58,7 +58,14 @@ private:
|
||||
|
||||
class FractionLayout final : public Layout {
|
||||
public:
|
||||
FractionLayout(Layout numerator, Layout denominator);
|
||||
static FractionLayout Builder(Layout numerator, Layout denominator) { return FractionLayout(numerator, denominator); }
|
||||
private:
|
||||
FractionLayout(Layout numerator, Layout denominator) :
|
||||
Layout(TreePool::sharedPool()->createTreeNode<FractionLayoutNode>())
|
||||
{
|
||||
replaceChildAtIndexInPlace(0, numerator);
|
||||
replaceChildAtIndexInPlace(1, denominator);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ namespace Poincare {
|
||||
|
||||
class Ghost final : public TreeHandle {
|
||||
public:
|
||||
static Ghost Builder() { return Ghost(); }
|
||||
private:
|
||||
Ghost() : TreeHandle(TreePool::sharedPool()->createTreeNode<GhostNode>()) {}
|
||||
};
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ private:
|
||||
class GridLayout : public Layout {
|
||||
public:
|
||||
GridLayout(const GridLayoutNode * n) : Layout(n) {}
|
||||
GridLayout() : Layout(TreePool::sharedPool()->createTreeNode<GridLayoutNode>()) {}
|
||||
static GridLayout Builder() { return GridLayout(); }
|
||||
void setDimensions(int rows, int columns);
|
||||
void addChildAtIndex(Layout l, int index, int currentNumberOfChildren, LayoutCursor * cursor) {
|
||||
Layout::addChildAtIndex(l, index, currentNumberOfChildren, cursor);
|
||||
@@ -97,6 +97,7 @@ public:
|
||||
int numberOfRows() const { return node()->numberOfRows(); }
|
||||
int numberOfColumns() const { return node()->numberOfColumns(); }
|
||||
private:
|
||||
GridLayout() : Layout(TreePool::sharedPool()->createTreeNode<GridLayoutNode>()) {}
|
||||
virtual GridLayoutNode * node() const { return static_cast<GridLayoutNode *>(Layout::node()); }
|
||||
void setNumberOfRows(int rows) {
|
||||
assert(rows >= 0);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef POINCARE_HORIZONTAL_LAYOUT_NODE_H
|
||||
#define POINCARE_HORIZONTAL_LAYOUT_NODE_H
|
||||
|
||||
#include <poincare/array_builder.h>
|
||||
#include <poincare/layout.h>
|
||||
#include <poincare/layout_cursor.h>
|
||||
|
||||
@@ -65,13 +66,21 @@ private:
|
||||
class HorizontalLayout final : public Layout {
|
||||
friend class HorizontalLayoutNode;
|
||||
public:
|
||||
// Constructors
|
||||
HorizontalLayout(HorizontalLayoutNode * n) : Layout(n) {}
|
||||
HorizontalLayout();
|
||||
explicit HorizontalLayout(Layout l);
|
||||
HorizontalLayout(Layout l1, Layout l2);
|
||||
HorizontalLayout(Layout l1, Layout l2, Layout l3);
|
||||
HorizontalLayout(Layout l1, Layout l2, Layout l3, Layout l4);
|
||||
HorizontalLayout(const Layout * children, size_t numberOfChildren);
|
||||
static HorizontalLayout Builder() { return HorizontalLayout(); }
|
||||
static HorizontalLayout Builder(Layout l) { return HorizontalLayout::Builder(&l, 1); }
|
||||
static HorizontalLayout Builder(Layout l1, Layout l2) { return HorizontalLayout::Builder(ArrayBuilder<Layout>(l1, l2).array(), 2); }
|
||||
static HorizontalLayout Builder(Layout l1, Layout l2, Layout l3) { return HorizontalLayout::Builder(ArrayBuilder<Layout>(l1, l2, l3).array(), 3); }
|
||||
static HorizontalLayout Builder(Layout l1, Layout l2, Layout l3, Layout l4) { return HorizontalLayout::Builder(ArrayBuilder<Layout>(l1, l2, l3, l4).array(), 4); }
|
||||
static HorizontalLayout Builder(const Layout * children, size_t numberOfChildren) {
|
||||
HorizontalLayout h = HorizontalLayout::Builder();
|
||||
for (size_t i = 0; i < numberOfChildren; i++) {
|
||||
h.addChildAtIndexInPlace(children[i], i, i);
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
void addChildAtIndex(Layout l, int index, int currentNumberOfChildren, LayoutCursor * cursor, bool removeEmptyChildren = false);
|
||||
// Remove puts a child at the end of the pool
|
||||
void removeChild(Layout l, LayoutCursor * cursor, bool force = false) {
|
||||
@@ -82,7 +91,9 @@ public:
|
||||
}
|
||||
void addOrMergeChildAtIndex(Layout l, int index, bool removeEmptyChildren, LayoutCursor * cursor = nullptr);
|
||||
void mergeChildrenAtIndex(HorizontalLayout h, int index, bool removeEmptyChildren, LayoutCursor * cursor = nullptr);
|
||||
|
||||
private:
|
||||
HorizontalLayout() : Layout(TreePool::sharedPool()->createTreeNode<HorizontalLayoutNode>()) {}
|
||||
void removeEmptyChildBeforeInsertionAtIndex(int * index, int * currentNumberOfChildren, bool shouldRemoveOnLeft, LayoutCursor * cursor = nullptr);
|
||||
};
|
||||
|
||||
|
||||
@@ -56,6 +56,8 @@ private:
|
||||
|
||||
class IntegralLayout final : public Layout {
|
||||
public:
|
||||
static IntegralLayout Builder(Layout integrand, Layout differential, Layout lowerBound, Layout upperBound) { return IntegralLayout(integrand, differential, lowerBound, upperBound); }
|
||||
private:
|
||||
IntegralLayout(Layout integrand, Layout differential, Layout lowerBound, Layout upperBound) :
|
||||
Layout(TreePool::sharedPool()->createTreeNode<IntegralLayoutNode>())
|
||||
{
|
||||
|
||||
@@ -35,7 +35,9 @@ protected:
|
||||
|
||||
class LeftParenthesisLayout final : public Layout {
|
||||
public:
|
||||
LeftParenthesisLayout();
|
||||
static LeftParenthesisLayout Builder() { return LeftParenthesisLayout(); }
|
||||
private:
|
||||
LeftParenthesisLayout() : Layout(TreePool::sharedPool()->createTreeNode<LeftParenthesisLayoutNode>()) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -29,7 +29,9 @@ protected:
|
||||
|
||||
class LeftSquareBracketLayout final : public Layout {
|
||||
public:
|
||||
LeftSquareBracketLayout();
|
||||
static LeftSquareBracketLayout Builder() { return LeftSquareBracketLayout(); }
|
||||
private:
|
||||
LeftSquareBracketLayout() : Layout(TreePool::sharedPool()->createTreeNode<LeftSquareBracketLayoutNode>()) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -62,14 +62,8 @@ class Matrix final : public Expression {
|
||||
template<typename T> friend class MatrixComplexNode;
|
||||
friend class GlobalContext;
|
||||
public:
|
||||
static Matrix EmptyMatrix() {
|
||||
return Matrix(TreePool::sharedPool()->createTreeNode<MatrixNode>());
|
||||
}
|
||||
Matrix() : Matrix(TreePool::sharedPool()->createTreeNode<MatrixNode>()) {}
|
||||
Matrix(const MatrixNode * node) : Expression(node) {}
|
||||
explicit Matrix(Expression e) : Matrix() {
|
||||
addChildAtIndexInPlace(e, 0, 0);
|
||||
}
|
||||
static Matrix Builder() { return Matrix(); }
|
||||
|
||||
void setDimensions(int rows, int columns);
|
||||
int numberOfRows() const { return node()->numberOfRows(); }
|
||||
@@ -91,6 +85,7 @@ public:
|
||||
Expression inverse(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
#endif
|
||||
private:
|
||||
Matrix() : Matrix(TreePool::sharedPool()->createTreeNode<MatrixNode>()) {}
|
||||
// TODO: find another solution for inverse and determinant (avoid capping the matrix)
|
||||
static constexpr int k_maxNumberOfCoefficients = 100;
|
||||
|
||||
@@ -98,7 +93,7 @@ private:
|
||||
void setNumberOfRows(int rows) { assert(rows >= 0); node()->setNumberOfRows(rows); }
|
||||
void setNumberOfColumns(int columns) { assert(columns >= 0); node()->setNumberOfColumns(columns); }
|
||||
/* rowCanonize turns a matrix in its reduced row echelon form. */
|
||||
Matrix rowCanonize(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Multiplication m = Multiplication());
|
||||
Matrix rowCanonize(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Multiplication m = Multiplication::Builder());
|
||||
// Row canonize the array in place
|
||||
template<typename T> static void ArrayRowCanonize(T * array, int numberOfRows, int numberOfColumns, T * c = nullptr);
|
||||
};
|
||||
|
||||
@@ -57,13 +57,23 @@ private:
|
||||
class MatrixLayout /*final*/ : public GridLayout {
|
||||
friend class MatrixLayoutNode;
|
||||
public:
|
||||
MatrixLayout(const MatrixLayoutNode * n);
|
||||
MatrixLayout();
|
||||
MatrixLayout(Layout l1, Layout l2, Layout l3, Layout l4);
|
||||
static MatrixLayout Builder() { return MatrixLayout(); }
|
||||
MatrixLayout(const MatrixLayoutNode * n) : GridLayout(n) {}
|
||||
static MatrixLayout Builder(Layout l1, Layout l2, Layout l3, Layout l4) {
|
||||
MatrixLayout m = MatrixLayout::Builder();
|
||||
m.addChildAtIndexInPlace(l1, 0, 0);
|
||||
m.addChildAtIndexInPlace(l2, 1, 1);
|
||||
m.addChildAtIndexInPlace(l3, 2, 2);
|
||||
m.addChildAtIndexInPlace(l4, 3, 3);
|
||||
m.setDimensions(2, 2);
|
||||
return m;
|
||||
}
|
||||
|
||||
bool hasGreySquares() const { return node()->hasGreySquares(); }
|
||||
void addGreySquares() { node()->addGreySquares(); }
|
||||
void removeGreySquares() { node()->removeGreySquares(); }
|
||||
private:
|
||||
MatrixLayout() : GridLayout(TreePool::sharedPool()->createTreeNode<MatrixLayoutNode>()) {}
|
||||
MatrixLayoutNode * node() const { return static_cast<MatrixLayoutNode *>(Layout::node()); }
|
||||
};
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define POINCARE_MULTIPLICATION_H
|
||||
|
||||
#include <poincare/approximation_helper.h>
|
||||
#include <poincare/array_builder.h>
|
||||
#include <poincare/n_ary_expression_node.h>
|
||||
|
||||
namespace Poincare {
|
||||
@@ -66,17 +67,10 @@ class Multiplication final : public NAryExpression {
|
||||
friend class Power;
|
||||
public:
|
||||
Multiplication(const MultiplicationNode * n) : NAryExpression(n) {}
|
||||
Multiplication();
|
||||
explicit Multiplication(Expression e1) : Multiplication() {
|
||||
addChildAtIndexInPlace(e1, 0, 0);
|
||||
}
|
||||
Multiplication(Expression e1, Expression e2) : Multiplication() {
|
||||
addChildAtIndexInPlace(e2, 0, 0);
|
||||
addChildAtIndexInPlace(e1, 0, numberOfChildren());
|
||||
}
|
||||
Multiplication(Expression e1, Expression e2, Expression e3) : Multiplication(e2, e3) {
|
||||
addChildAtIndexInPlace(e1, 0, numberOfChildren());
|
||||
}
|
||||
static Multiplication Builder() { return Multiplication(); }
|
||||
static Multiplication Builder(Expression e1) { return Multiplication(&e1, 1); }
|
||||
static Multiplication Builder(Expression e1, Expression e2) { return Multiplication(ArrayBuilder<Expression>(e1, e2).array(), 2); }
|
||||
static Multiplication Builder(Expression e1, Expression e2, Expression e3) { return Multiplication(ArrayBuilder<Expression>(e1, e2, e3).array(), 3); }
|
||||
|
||||
template<typename T> static void computeOnArrays(T * m, T * n, T * result, int mNumberOfColumns, int mNumberOfRows, int nNumberOfColumns);
|
||||
// Expression
|
||||
@@ -86,6 +80,13 @@ public:
|
||||
int getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const;
|
||||
Expression denominator(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
private:
|
||||
// Constructors
|
||||
Multiplication() : NAryExpression(TreePool::sharedPool()->createTreeNode<MultiplicationNode>()) {}
|
||||
explicit Multiplication(Expression * children, size_t numberOfChildren) : Multiplication() {
|
||||
for (size_t i = 0; i < numberOfChildren; i++) {
|
||||
addChildAtIndexInPlace(children[i], i, i);
|
||||
}
|
||||
}
|
||||
// Simplification
|
||||
Expression privateShallowReduce(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool expand, bool canBeInterrupted);
|
||||
void mergeMultiplicationChildrenInPlace();
|
||||
|
||||
@@ -67,10 +67,17 @@ private:
|
||||
|
||||
class NthRootLayout final : public Layout {
|
||||
public:
|
||||
explicit NthRootLayout(Layout radicand);
|
||||
NthRootLayout(Layout radicand, Layout index);
|
||||
static NthRootLayout Builder(Layout radicand) { return NthRootLayout(radicand); }
|
||||
static NthRootLayout Builder(Layout radicand, Layout index) {
|
||||
NthRootLayout n(radicand);
|
||||
n.addChildAtIndexInPlace(index, 1, 1);
|
||||
static_cast<NthRootLayoutNode *>(n.node())->setNumberOfChildren(2);
|
||||
return n;
|
||||
}
|
||||
private:
|
||||
NthRootLayout();
|
||||
NthRootLayout(Layout radicand) : Layout(TreePool::sharedPool()->createTreeNode<NthRootLayoutNode>()) {
|
||||
replaceChildAtIndexInPlace(0, radicand);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -46,13 +46,17 @@ public:
|
||||
|
||||
class Opposite final : public Expression {
|
||||
public:
|
||||
Opposite();
|
||||
Opposite(const OppositeNode * n) : Expression(n) {}
|
||||
static Opposite Builder() { return Opposite(); }
|
||||
static Opposite Builder(Expression child) { return Opposite(child); }
|
||||
|
||||
Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target);
|
||||
|
||||
private:
|
||||
Opposite() : Expression(TreePool::sharedPool()->createTreeNode<OppositeNode>()) {}
|
||||
explicit Opposite(Expression child) : Expression(TreePool::sharedPool()->createTreeNode<OppositeNode>()) {
|
||||
replaceChildAtIndexInPlace(0, child);
|
||||
}
|
||||
|
||||
Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -38,11 +38,14 @@ private:
|
||||
class Parenthesis final : public Expression {
|
||||
public:
|
||||
Parenthesis(const ParenthesisNode * n) : Expression(n) {}
|
||||
static Parenthesis Builder(Expression child) { return Parenthesis(child); }
|
||||
// Expression
|
||||
Expression shallowReduce();
|
||||
|
||||
private:
|
||||
Parenthesis(Expression exp) : Expression(TreePool::sharedPool()->createTreeNode<ParenthesisNode>()) {
|
||||
replaceChildAtIndexInPlace(0, exp);
|
||||
}
|
||||
// Expression
|
||||
Expression shallowReduce();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -66,8 +66,9 @@ class Power final : public Expression {
|
||||
friend class PowerNode;
|
||||
friend class Round;
|
||||
public:
|
||||
Power(Expression base, Expression exponent);
|
||||
Power(const PowerNode * n) : Expression(n) {}
|
||||
static Power Builder(Expression base, Expression exponent) { return Power(base, exponent); }
|
||||
|
||||
Expression setSign(ExpressionNode::Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target);
|
||||
int getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const;
|
||||
Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target);
|
||||
@@ -77,6 +78,12 @@ private:
|
||||
constexpr static int k_maxExactPowerMatrix = 100;
|
||||
constexpr static int k_maxNumberOfTermsInExpandedMultinome = 25;
|
||||
|
||||
// Constructors
|
||||
Power(Expression base, Expression exponent) : Expression(TreePool::sharedPool()->createTreeNode<PowerNode>()) {
|
||||
replaceChildAtIndexInPlace(0, base);
|
||||
replaceChildAtIndexInPlace(1, exponent);
|
||||
}
|
||||
|
||||
// Simplification
|
||||
Expression denominator(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@ private:
|
||||
|
||||
class ProductLayout final : public Layout {
|
||||
public:
|
||||
static ProductLayout Builder(Layout argument, Layout variable, Layout lowerB, Layout upperB) { return ProductLayout(argument, variable, lowerB, upperB); }
|
||||
private:
|
||||
ProductLayout(Layout argument, Layout variable, Layout lowerB, Layout upperB) :
|
||||
Layout(TreePool::sharedPool()->createTreeNode<ProductLayoutNode>())
|
||||
{
|
||||
|
||||
@@ -36,7 +36,9 @@ protected:
|
||||
|
||||
class RightParenthesisLayout final : public Layout {
|
||||
public:
|
||||
RightParenthesisLayout();
|
||||
static RightParenthesisLayout Builder() { return RightParenthesisLayout(); }
|
||||
private:
|
||||
RightParenthesisLayout() : Layout(TreePool::sharedPool()->createTreeNode<RightParenthesisLayoutNode>()) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -29,7 +29,10 @@ protected:
|
||||
|
||||
class RightSquareBracketLayout final : public Layout {
|
||||
public:
|
||||
RightSquareBracketLayout();
|
||||
static RightSquareBracketLayout Builder() { return RightSquareBracketLayout(); }
|
||||
|
||||
private:
|
||||
RightSquareBracketLayout() : Layout(TreePool::sharedPool()->createTreeNode<RightSquareBracketLayoutNode>()) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -40,10 +40,7 @@ class Store final : public Expression {
|
||||
friend class StoreNode;
|
||||
public:
|
||||
Store(const StoreNode * n) : Expression(n) {}
|
||||
Store(Expression value, SymbolAbstract symbol) : Expression(TreePool::sharedPool()->createTreeNode<StoreNode>()) {
|
||||
replaceChildAtIndexInPlace(0, value);
|
||||
replaceChildAtIndexInPlace(1, symbol);
|
||||
}
|
||||
static Store Builder(Expression value, SymbolAbstract symbol) { return Store(value, symbol); }
|
||||
|
||||
// Store
|
||||
const SymbolAbstract symbol() const {
|
||||
@@ -58,6 +55,11 @@ public:
|
||||
// Expression
|
||||
Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target);
|
||||
private:
|
||||
Store(Expression value, SymbolAbstract symbol) : Expression(TreePool::sharedPool()->createTreeNode<StoreNode>()) {
|
||||
replaceChildAtIndexInPlace(0, value);
|
||||
replaceChildAtIndexInPlace(1, symbol);
|
||||
}
|
||||
|
||||
Expression storeValueForSymbol(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
StoreNode * node() const { return static_cast<StoreNode *>(Expression::node()); }
|
||||
};
|
||||
|
||||
@@ -54,15 +54,20 @@ private:
|
||||
|
||||
class Subtraction final : public Expression {
|
||||
public:
|
||||
Subtraction();
|
||||
Subtraction(const SubtractionNode * n) : Expression(n) {}
|
||||
Subtraction(Expression child0, Expression child1) : Subtraction() {
|
||||
replaceChildAtIndexInPlace(0, child0);
|
||||
replaceChildAtIndexInPlace(1, child1);
|
||||
static Subtraction Builder() { return Subtraction(); }
|
||||
static Subtraction Builder(Expression child0, Expression child1) {
|
||||
Subtraction s = Subtraction::Builder();
|
||||
s.replaceChildAtIndexInPlace(0, child0);
|
||||
s.replaceChildAtIndexInPlace(1, child1);
|
||||
return s;
|
||||
}
|
||||
|
||||
// Expression
|
||||
Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target);
|
||||
|
||||
private:
|
||||
Subtraction() : Expression(TreePool::sharedPool()->createTreeNode<SubtractionNode>()) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ private:
|
||||
|
||||
class SumLayout final : public Layout {
|
||||
public:
|
||||
static SumLayout Builder(Layout argument, Layout variable, Layout lowerB, Layout upperB) { return SumLayout(argument, variable, lowerB, upperB); }
|
||||
private:
|
||||
SumLayout(Layout argument, Layout variable, Layout lowerB, Layout upperB) :
|
||||
Layout(TreePool::sharedPool()->createTreeNode<SumLayoutNode>())
|
||||
{
|
||||
|
||||
@@ -59,7 +59,15 @@ private:
|
||||
|
||||
class VerticalOffsetLayout final : public Layout {
|
||||
public:
|
||||
VerticalOffsetLayout(Layout l, VerticalOffsetLayoutNode::Type type);
|
||||
static VerticalOffsetLayout Builder(Layout l, VerticalOffsetLayoutNode::Type type) { return VerticalOffsetLayout(l, type); }
|
||||
|
||||
private:
|
||||
VerticalOffsetLayout(Layout l, VerticalOffsetLayoutNode::Type type) :
|
||||
Layout(TreePool::sharedPool()->createTreeNode<VerticalOffsetLayoutNode>())
|
||||
{
|
||||
static_cast<VerticalOffsetLayoutNode *>(node())->setType(type);
|
||||
replaceChildAtIndexInPlace(0,l);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ Expression AbsoluteValueNode::setSign(Sign s, Context * context, Preferences::Co
|
||||
}
|
||||
|
||||
Layout AbsoluteValueNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return AbsoluteValueLayout(childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits));
|
||||
return AbsoluteValueLayout::Builder(childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits));
|
||||
}
|
||||
|
||||
int AbsoluteValueNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
@@ -62,7 +62,7 @@ Expression AbsoluteValue::shallowReduce(Context & context, Preferences::ComplexF
|
||||
} else if (!std::isnan(app) &&
|
||||
((c.isNumber() && app < 0.0f) || app <= -Expression::Epsilon<float>())) {
|
||||
// abs(a) = -a with a < 0 (same comment as above to check that a < 0)
|
||||
Multiplication m(Rational(-1), c);
|
||||
Multiplication m = Multiplication::Builder(Rational(-1), c);
|
||||
replaceWithInPlace(m);
|
||||
return m.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
}
|
||||
|
||||
@@ -59,7 +59,6 @@ Expression AdditionNode::shallowBeautify(Context & context, Preferences::Complex
|
||||
}
|
||||
|
||||
// Addition
|
||||
Addition::Addition() : NAryExpression(TreePool::sharedPool()->createTreeNode<AdditionNode>()) {}
|
||||
|
||||
const Number Addition::NumeralFactor(const Expression & e) {
|
||||
if (e.type() == ExpressionNode::Type::Multiplication && e.childAtIndex(0).isNumber()) {
|
||||
@@ -94,7 +93,7 @@ Expression Addition::shallowBeautify(Context & context, Preferences::ComplexForm
|
||||
* In practice, we want to turn "a+(-1)*b" into "a-b". Or, more precisely, any
|
||||
* "a+(-r)*b" into "a-r*b" where r is a positive Rational.
|
||||
* Note: the process will slightly differ if the negative product occurs on
|
||||
* the first term: we want to turn "AdditionNode(Multiplication(-1,b))" into
|
||||
* the first term: we want to turn "Addition(Multiplication::Builder(-1,b))" into
|
||||
* "Opposite(b)".
|
||||
* Last but not least, special care must be taken when iterating over children
|
||||
* since we may remove some during the process. */
|
||||
@@ -115,7 +114,7 @@ Expression Addition::shallowBeautify(Context & context, Preferences::ComplexForm
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
Opposite o = Opposite(subtractant);
|
||||
Opposite o = Opposite::Builder(subtractant);
|
||||
replaceChildAtIndexInPlace(i, o);
|
||||
} else {
|
||||
Expression leftSibling = childAtIndex(i-1);
|
||||
@@ -123,7 +122,7 @@ Expression Addition::shallowBeautify(Context & context, Preferences::ComplexForm
|
||||
/* CAUTION: we removed a child. So we need to decrement i to make sure
|
||||
* the next iteration is actually on the next child. */
|
||||
i--;
|
||||
Subtraction s = Subtraction(leftSibling, subtractant);
|
||||
Subtraction s = Subtraction::Builder(leftSibling, subtractant);
|
||||
/* We stole subtractant from this which replaced it by a ghost. We thus
|
||||
* need to put the subtraction at the previous index of subtractant, which
|
||||
* is still i because we updated i after removing a child. */
|
||||
@@ -262,7 +261,7 @@ Expression Addition::shallowReduce(Context & context, Preferences::ComplexFormat
|
||||
* We can bubble up ComplexCartesian nodes. */
|
||||
if (allChildrenAreReal(context) == 0) {
|
||||
/* We turn (a+ib)+(c+id) into (a+c)+i(c+d)*/
|
||||
Addition imag; // we store all imaginary parts in 'imag'
|
||||
Addition imag = Addition::Builder(); // we store all imaginary parts in 'imag'
|
||||
Addition real = *this; // we store all real parts in 'real'
|
||||
i = numberOfChildren() - 1;
|
||||
while (i >= 0) {
|
||||
@@ -341,7 +340,7 @@ Expression Addition::factorizeOnCommonDenominator(Context & context, Preferences
|
||||
// We want to turn (a/b+c/d+e/b) into (a*d+b*c+e*d)/(b*d)
|
||||
|
||||
// Step 1: We want to compute the common denominator, b*d
|
||||
Multiplication commonDenominator = Multiplication();
|
||||
Multiplication commonDenominator;
|
||||
for (int i = 0; i < numberOfChildren(); i++) {
|
||||
Expression currentDenominator = childAtIndex(i).denominator(context, complexFormat, angleUnit);
|
||||
if (!currentDenominator.isUninitialized()) {
|
||||
@@ -356,16 +355,16 @@ Expression Addition::factorizeOnCommonDenominator(Context & context, Preferences
|
||||
|
||||
/* Step 2: Create the numerator. We start with this being a/b+c/d+e/b and we
|
||||
* want to create numerator = a/b*b*d + c/d*b*d + e/b*b*d = a*d + c*b + e*d */
|
||||
Addition numerator = Addition();
|
||||
Addition numerator = Addition::Builder();
|
||||
for (int i = 0; i < numberOfChildren(); i++) {
|
||||
Multiplication m = Multiplication(childAtIndex(i), commonDenominator.clone());
|
||||
Multiplication m = Multiplication::Builder(childAtIndex(i), commonDenominator.clone());
|
||||
numerator.addChildAtIndexInPlace(m, numerator.numberOfChildren(), numerator.numberOfChildren());
|
||||
m.privateShallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User, true, false);
|
||||
}
|
||||
|
||||
// Step 3: Add the denominator
|
||||
Power inverseDenominator = Power(commonDenominator, Rational(-1));
|
||||
Multiplication result = Multiplication(numerator, inverseDenominator);
|
||||
Power inverseDenominator = Power::Builder(commonDenominator, Rational(-1));
|
||||
Multiplication result = Multiplication::Builder(numerator, inverseDenominator);
|
||||
|
||||
// Step 4: Simplify the numerator
|
||||
numerator.shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User);
|
||||
@@ -396,7 +395,7 @@ void Addition::factorizeChildrenAtIndexesInPlace(int index1, int index2, Context
|
||||
removeChildAtIndexInPlace(index2);
|
||||
|
||||
// Step 3: Create a multiplication
|
||||
Multiplication m;
|
||||
Multiplication m = Multiplication::Builder();
|
||||
if (e1.type() == ExpressionNode::Type::Multiplication) {
|
||||
m = static_cast<Multiplication&>(e1);
|
||||
} else {
|
||||
|
||||
@@ -19,7 +19,7 @@ Expression BinomialCoefficientNode::shallowReduce(Context & context, Preferences
|
||||
}
|
||||
|
||||
Layout BinomialCoefficientNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return BinomialCoefficientLayout(
|
||||
return BinomialCoefficientLayout::Builder(
|
||||
childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits),
|
||||
childAtIndex(1)->createLayout(floatDisplayMode, numberOfSignificantDigits));
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ constexpr Expression::FunctionHelper Ceiling::s_functionHelper;
|
||||
int CeilingNode::numberOfChildren() const { return Ceiling::s_functionHelper.numberOfChildren(); }
|
||||
|
||||
Layout CeilingNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return CeilingLayout(childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits));
|
||||
return CeilingLayout::Builder(childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits));
|
||||
}
|
||||
|
||||
int CeilingNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
|
||||
@@ -106,13 +106,13 @@ Expression ComplexCartesian::squareNorm(Context & context, Preferences::ComplexF
|
||||
factorAndArgumentOfFunction(a, ExpressionNode::Type::Cosine, &aFactor, &aArgument, context, complexFormat, angleUnit, target);
|
||||
factorAndArgumentOfFunction(b, ExpressionNode::Type::Sine, &bFactor, &bArgument, context, complexFormat, angleUnit, target);
|
||||
if (!aFactor.isUninitialized() && !aArgument.isUninitialized() && !bFactor.isUninitialized() && !bArgument.isUninitialized() && aFactor.isIdenticalTo(bFactor) && aArgument.isIdenticalTo(bArgument)) {
|
||||
Power result(aFactor, Rational(2));
|
||||
Power result = Power::Builder(aFactor, Rational(2));
|
||||
aFactor.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
return result;
|
||||
}
|
||||
Expression a2 = Power(a, Rational(2));
|
||||
Expression b2 = Power(b, Rational(2));
|
||||
Addition add(a2, b2);
|
||||
Expression a2 = Power::Builder(a, Rational(2));
|
||||
Expression b2 = Power::Builder(b, Rational(2));
|
||||
Addition add = Addition::Builder(a2, b2);
|
||||
a2.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
b2.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
return add;
|
||||
@@ -142,7 +142,7 @@ Expression ComplexCartesian::argument(Context & context, Preferences::ComplexFor
|
||||
if (!b.isRationalZero()) {
|
||||
// if b != 0, argument = sign(b) * Pi/2 - arctan(a/b)
|
||||
// First, compute arctan(a/b) or (Pi/180)*arctan(a/b)
|
||||
Expression divab = Division(a, b.clone());
|
||||
Expression divab = Division::Builder(a, b.clone());
|
||||
Expression arcTangent = ArcTangent::Builder(divab);
|
||||
divab.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
if (angleUnit == Preferences::AngleUnit::Degree) {
|
||||
@@ -152,18 +152,18 @@ Expression ComplexCartesian::argument(Context & context, Preferences::ComplexFor
|
||||
}
|
||||
// Then, compute sign(b) * Pi/2 - arctan(a/b)
|
||||
Expression signb = SignFunction::Builder(b);
|
||||
Expression signbPi2 = Multiplication(Rational(1,2), signb, Constant(Ion::Charset::SmallPi));
|
||||
Expression signbPi2 = Multiplication::Builder(Rational(1,2), signb, Constant(Ion::Charset::SmallPi));
|
||||
signb.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
Expression sub = Subtraction(signbPi2, arcTangent);
|
||||
Expression sub = Subtraction::Builder(signbPi2, arcTangent);
|
||||
signbPi2.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
arcTangent.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
return sub;
|
||||
} else {
|
||||
// if b == 0, argument = (1-sign(a))*Pi/2
|
||||
Expression signa = SignFunction::Builder(a).shallowReduce(context, complexFormat, angleUnit, target);
|
||||
Subtraction sub(Rational(1), signa);
|
||||
Subtraction sub = Subtraction::Builder(Rational(1), signa);
|
||||
signa.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
Multiplication mul(Rational(1,2), Constant(Ion::Charset::SmallPi), sub);
|
||||
Multiplication mul = Multiplication::Builder(Rational(1,2), Constant(Ion::Charset::SmallPi), sub);
|
||||
sub.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
return mul;
|
||||
}
|
||||
@@ -175,14 +175,14 @@ ComplexCartesian ComplexCartesian::inverse(Context & context, Preferences::Compl
|
||||
// 1/(a+ib) = a/(a^2+b^2)+i*(-b/(a^2+b^2))
|
||||
Expression denominatorReal = clone().convert<ComplexCartesian>().squareNorm(context, complexFormat, angleUnit, target);
|
||||
Expression denominatorImag = denominatorReal.clone();
|
||||
Expression denominatorRealInv = Power(denominatorReal, Rational(-1));
|
||||
Expression denominatorRealInv = Power::Builder(denominatorReal, Rational(-1));
|
||||
denominatorReal.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
Expression denominatorImagInv = Power(denominatorImag, Rational(-1));
|
||||
Expression denominatorImagInv = Power::Builder(denominatorImag, Rational(-1));
|
||||
denominatorImag.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
Multiplication A(a, denominatorRealInv);
|
||||
Multiplication A = Multiplication::Builder(a, denominatorRealInv);
|
||||
denominatorRealInv.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
Expression numeratorImag = Multiplication(Rational(-1), b);
|
||||
Multiplication B(numeratorImag, denominatorImagInv);
|
||||
Expression numeratorImag = Multiplication::Builder(Rational(-1), b);
|
||||
Multiplication B = Multiplication::Builder(numeratorImag, denominatorImagInv);
|
||||
numeratorImag.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
denominatorImagInv.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
ComplexCartesian result(A,B);
|
||||
@@ -193,11 +193,11 @@ ComplexCartesian ComplexCartesian::inverse(Context & context, Preferences::Compl
|
||||
|
||||
Multiplication ComplexCartesian::squareRootHelper(Expression e, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) {
|
||||
//(1/2)*sqrt(2*e)
|
||||
Multiplication doubleE(Rational(2), e);
|
||||
Multiplication doubleE = Multiplication::Builder(Rational(2), e);
|
||||
e.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
Expression sqrt = SquareRoot::Builder(doubleE);
|
||||
doubleE.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
Multiplication result(Rational(1,2), sqrt);
|
||||
Multiplication result = Multiplication::Builder(Rational(1,2), sqrt);
|
||||
sqrt.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
return result;
|
||||
}
|
||||
@@ -210,11 +210,11 @@ ComplexCartesian ComplexCartesian::squareRoot(Context & context, Preferences::Co
|
||||
Expression normA = clone().convert<ComplexCartesian>().norm(context, complexFormat, angleUnit, target);
|
||||
Expression normB = normA.clone();
|
||||
// A = (1/2)*sqrt(2*(sqrt(a^2+b^2)+a))
|
||||
Addition normAdda(normA, a.clone());
|
||||
Addition normAdda = Addition::Builder(normA, a.clone());
|
||||
normA.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
Multiplication A = squareRootHelper(normAdda, context, complexFormat, angleUnit, target);
|
||||
// B = B: (1/2)*sqrt(2*(sqrt(a^2+b^2)-a))
|
||||
Subtraction normSuba(normB, a);
|
||||
Subtraction normSuba = Subtraction::Builder(normB, a);
|
||||
normB.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
Multiplication B = squareRootHelper(normSuba, context, complexFormat, angleUnit, target);
|
||||
// B = B: (1/2)*sqrt(2*(sqrt(a^2+b^2)-a))*sign(b)
|
||||
@@ -238,9 +238,9 @@ ComplexCartesian ComplexCartesian::powerInteger(int n, Context & context, Prefer
|
||||
// (b*i)^n = b^n*i^n with i^n == i, -i, 1 or -1
|
||||
if (a.isRationalZero()) {
|
||||
ComplexCartesian result;
|
||||
Expression bpow = Power(b, Rational(n));
|
||||
Expression bpow = Power::Builder(b, Rational(n));
|
||||
if (n/2%2 == 1) {
|
||||
Expression temp = Multiplication(Rational(-1), bpow);
|
||||
Expression temp = Multiplication::Builder(Rational(-1), bpow);
|
||||
bpow.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
bpow = temp;
|
||||
}
|
||||
@@ -255,16 +255,16 @@ ComplexCartesian ComplexCartesian::powerInteger(int n, Context & context, Prefer
|
||||
// (a+ib) = a^n+i*b*a^(n-1)+(-1)*b^2*a^(n-2)+(-i)*b^3*a^(n-3)+b^3*a^(n-4)+...
|
||||
// Real part: A = a^n+(-1)*b^2*a^(n-2)+...
|
||||
// Imaginary part: B = b*a^(n-1)
|
||||
Addition A;
|
||||
Addition B;
|
||||
Addition A = Addition::Builder();
|
||||
Addition B = Addition::Builder();
|
||||
ComplexCartesian result = ComplexCartesian::Builder(A, B);
|
||||
for (int i = 0; i <= n; i++) {
|
||||
BinomialCoefficient binom = BinomialCoefficient::Builder(Rational(n), Rational(i));
|
||||
Expression aclone = i == n ? a : a.clone();
|
||||
Expression bclone = i == n ? b : b.clone();
|
||||
Power apow(aclone, Rational(n-i));
|
||||
Power bpow(bclone, Rational(i));
|
||||
Multiplication m(binom, apow, bpow);
|
||||
Power apow = Power::Builder(aclone, Rational(n-i));
|
||||
Power bpow = Power::Builder(bclone, Rational(i));
|
||||
Multiplication m = Multiplication::Builder(binom, apow, bpow);
|
||||
binom.shallowReduce();
|
||||
apow.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
bpow.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
@@ -294,15 +294,15 @@ ComplexCartesian ComplexCartesian::multiply(ComplexCartesian & other, Context &
|
||||
Expression d = other.imag();
|
||||
// (a+ib) * (c+id) = (ac-bd)+i*(ad+bc)
|
||||
// Compute ac-bd
|
||||
Expression ac = Multiplication(a.clone(), c.clone());
|
||||
Expression bd = Multiplication(b.clone(), d.clone());
|
||||
Subtraction A(ac, bd);
|
||||
Expression ac = Multiplication::Builder(a.clone(), c.clone());
|
||||
Expression bd = Multiplication::Builder(b.clone(), d.clone());
|
||||
Subtraction A = Subtraction::Builder(ac, bd);
|
||||
ac.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
bd.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
// Compute ad+bc
|
||||
Expression ad = Multiplication(a, d);
|
||||
Expression bc = Multiplication(b, c);
|
||||
Addition B(ad, bc);
|
||||
Expression ad = Multiplication::Builder(a, d);
|
||||
Expression bc = Multiplication::Builder(b, c);
|
||||
Addition B = Addition::Builder(ad, bc);
|
||||
ad.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
bc.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
ComplexCartesian result = ComplexCartesian::Builder(A, B);
|
||||
@@ -312,7 +312,7 @@ ComplexCartesian ComplexCartesian::multiply(ComplexCartesian & other, Context &
|
||||
}
|
||||
|
||||
Expression ComplexCartesian::powerHelper(Expression norm, Expression trigo, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) {
|
||||
Multiplication m(norm, trigo);
|
||||
Multiplication m = Multiplication::Builder(norm, trigo);
|
||||
norm.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
trigo.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
return m;
|
||||
@@ -326,24 +326,24 @@ ComplexCartesian ComplexCartesian::power(ComplexCartesian & other, Context & con
|
||||
Expression c = other.real();
|
||||
Expression d = other.imag();
|
||||
// R = r^c*e^(-th*d)
|
||||
Expression rpowc = Power(rclone, c.clone());
|
||||
Expression rpowc = Power::Builder(rclone, c.clone());
|
||||
rclone.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
Expression thmuld = Multiplication(Rational(-1), thclone, d.clone());
|
||||
Expression thmuld = Multiplication::Builder(Rational(-1), thclone, d.clone());
|
||||
thclone.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
Expression exp = Power(Constant(Ion::Charset::Exponential), thmuld);
|
||||
Expression exp = Power::Builder(Constant(Ion::Charset::Exponential), thmuld);
|
||||
thmuld.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
Multiplication norm(rpowc, exp);
|
||||
Multiplication norm = Multiplication::Builder(rpowc, exp);
|
||||
rpowc.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
exp.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
|
||||
// TH = d*ln(r)+c*th
|
||||
Expression lnr = NaperianLogarithm::Builder(r);
|
||||
r.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
Multiplication dlnr(d, lnr);
|
||||
Multiplication dlnr = Multiplication::Builder(d, lnr);
|
||||
lnr.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
Multiplication thc(th, c);
|
||||
Multiplication thc = Multiplication::Builder(th, c);
|
||||
th.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
Expression argument = Addition(thc, dlnr);
|
||||
Expression argument = Addition::Builder(thc, dlnr);
|
||||
thc.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
dlnr.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
|
||||
|
||||
@@ -37,12 +37,4 @@ KDPoint CondensedSumLayoutNode::positionOfChild(LayoutNode * child) {
|
||||
return KDPoint(x,y);
|
||||
}
|
||||
|
||||
CondensedSumLayout::CondensedSumLayout(Layout base, Layout subscript, Layout superscript) :
|
||||
Layout(TreePool::sharedPool()->createTreeNode<CondensedSumLayoutNode>())
|
||||
{
|
||||
replaceChildAtIndexInPlace(0, base);
|
||||
replaceChildAtIndexInPlace(1, subscript);
|
||||
replaceChildAtIndexInPlace(2, superscript);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -88,10 +88,10 @@ Expression ConfidenceInterval::shallowReduce(Context & context, Preferences::Com
|
||||
Rational r0 = static_cast<Rational&>(c0);
|
||||
Rational r1 = static_cast<Rational&>(c1);
|
||||
// Compute [r0-1/sqr(r1), r0+1/sqr(r1)]
|
||||
Expression sqr = Power(r1, Rational(-1, 2));
|
||||
Matrix matrix;
|
||||
matrix.addChildAtIndexInPlace(Addition(r0.clone(), Multiplication(Rational(-1), sqr.clone())), 0, 0);
|
||||
matrix.addChildAtIndexInPlace(Addition(r0, sqr), 1, 1);
|
||||
Expression sqr = Power::Builder(r1, Rational(-1, 2));
|
||||
Matrix matrix = Matrix::Builder();
|
||||
matrix.addChildAtIndexInPlace(Addition::Builder(r0.clone(), Multiplication::Builder(Rational(-1), sqr.clone())), 0, 0);
|
||||
matrix.addChildAtIndexInPlace(Addition::Builder(r0, sqr), 1, 1);
|
||||
matrix.setDimensions(1, 2);
|
||||
replaceWithInPlace(matrix);
|
||||
matrix.deepReduceChildren(context, complexFormat, angleUnit, target);
|
||||
|
||||
@@ -16,7 +16,7 @@ constexpr Expression::FunctionHelper Conjugate::s_functionHelper;
|
||||
int ConjugateNode::numberOfChildren() const { return Conjugate::s_functionHelper.numberOfChildren(); }
|
||||
|
||||
Layout ConjugateNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return ConjugateLayout(childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits));
|
||||
return ConjugateLayout::Builder(childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits));
|
||||
}
|
||||
|
||||
int ConjugateNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
@@ -51,7 +51,7 @@ Expression Conjugate::shallowReduce(Context & context, Preferences::ComplexForma
|
||||
}
|
||||
if (c.type() == ExpressionNode::Type::ComplexCartesian) {
|
||||
ComplexCartesian complexChild = static_cast<ComplexCartesian &>(c);
|
||||
Multiplication m(Rational(-1), complexChild.imag());
|
||||
Multiplication m = Multiplication::Builder(Rational(-1), complexChild.imag());
|
||||
complexChild.replaceChildAtIndexInPlace(1, m);
|
||||
m.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
replaceWithInPlace(complexChild);
|
||||
|
||||
@@ -378,7 +378,7 @@ Expression Decimal::shallowReduce() {
|
||||
Expression Decimal::shallowBeautify() {
|
||||
if (sign() == ExpressionNode::Sign::Negative) {
|
||||
Expression abs = setSign(ExpressionNode::Sign::Positive);
|
||||
Opposite o;
|
||||
Opposite o = Opposite::Builder();
|
||||
replaceWithInPlace(o);
|
||||
o.replaceChildAtIndexInPlace(0, abs);
|
||||
return o;
|
||||
|
||||
@@ -35,7 +35,7 @@ bool DivisionNode::childNeedsParenthesis(const TreeNode * child) const {
|
||||
Layout DivisionNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
const ExpressionNode * numerator = childAtIndex(0)->type() == Type::Parenthesis ? childAtIndex(0)->childAtIndex(0) : childAtIndex(0);
|
||||
const ExpressionNode * denominator = childAtIndex(1)->type() == Type::Parenthesis ? childAtIndex(1)->childAtIndex(0) : childAtIndex(1);
|
||||
return FractionLayout(numerator->createLayout(floatDisplayMode, numberOfSignificantDigits), denominator->createLayout(floatDisplayMode, numberOfSignificantDigits));
|
||||
return FractionLayout::Builder(numerator->createLayout(floatDisplayMode, numberOfSignificantDigits), denominator->createLayout(floatDisplayMode, numberOfSignificantDigits));
|
||||
}
|
||||
|
||||
int DivisionNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
@@ -70,8 +70,6 @@ template<typename T> MatrixComplex<T> DivisionNode::computeOnMatrices(const Matr
|
||||
|
||||
// Division
|
||||
|
||||
Division::Division() : Expression(TreePool::sharedPool()->createTreeNode<DivisionNode>()) {}
|
||||
|
||||
Expression Division::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) {
|
||||
{
|
||||
Expression e = Expression::defaultShallowReduce();
|
||||
@@ -79,9 +77,9 @@ Expression Division::shallowReduce(Context & context, Preferences::ComplexFormat
|
||||
return e;
|
||||
}
|
||||
}
|
||||
Expression p = Power(childAtIndex(1), Rational(-1));
|
||||
Multiplication m = Multiplication(childAtIndex(0), p);
|
||||
p.shallowReduce(context, complexFormat, angleUnit, target); // Imagine Division(2,1). p would be 1^(-1) which can be simplified
|
||||
Expression p = Power::Builder(childAtIndex(1), Rational(-1));
|
||||
Multiplication m = Multiplication::Builder(childAtIndex(0), p);
|
||||
p.shallowReduce(context, complexFormat, angleUnit, target); // Imagine Division::Builder(2,1). p would be 1^(-1) which can be simplified
|
||||
replaceWithInPlace(m);
|
||||
return m.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ Expression EqualNode::shallowReduce(Context & context, Preferences::ComplexForma
|
||||
}
|
||||
|
||||
Layout EqualNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
HorizontalLayout result;
|
||||
HorizontalLayout result = HorizontalLayout::Builder();
|
||||
result.addOrMergeChildAtIndex(childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits), 0, false);
|
||||
result.addChildAtIndex(CharLayout('='), result.numberOfChildren(), result.numberOfChildren(), nullptr);
|
||||
result.addOrMergeChildAtIndex(childAtIndex(1)->createLayout(floatDisplayMode, numberOfSignificantDigits), result.numberOfChildren(), false);
|
||||
@@ -42,7 +42,7 @@ Evaluation<T> EqualNode::templatedApproximate(Context& context, Preferences::Com
|
||||
}
|
||||
|
||||
Expression Equal::standardEquation(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const {
|
||||
Expression sub = Subtraction(childAtIndex(0).clone(), childAtIndex(1).clone());
|
||||
Expression sub = Subtraction::Builder(childAtIndex(0).clone(), childAtIndex(1).clone());
|
||||
return sub.reduce(context, complexFormat, angleUnit);
|
||||
}
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@ bool Expression::getLinearCoefficients(char * variables, int maxVariableSize, Ex
|
||||
equation = polynomialCoefficients[0];
|
||||
index++;
|
||||
}
|
||||
constant[0] = Opposite(equation.clone()).reduce(context, complexFormat, angleUnit);
|
||||
constant[0] = Opposite::Builder(equation.clone()).reduce(context, complexFormat, angleUnit);
|
||||
/* The expression can be linear on all coefficients taken one by one but
|
||||
* non-linear (ex: xy = 2). We delete the results and return false if one of
|
||||
* the coefficients contains a variable. */
|
||||
@@ -519,12 +519,12 @@ Expression Expression::ExpressionWithoutSymbols(Expression e, Context & context)
|
||||
|
||||
Expression Expression::radianToDegree() {
|
||||
// e*180/Pi
|
||||
return Multiplication(*this, Rational(180), Power(Constant(Ion::Charset::SmallPi), Rational(-1)));
|
||||
return Multiplication::Builder(*this, Rational(180), Power::Builder(Constant(Ion::Charset::SmallPi), Rational(-1)));
|
||||
}
|
||||
|
||||
Expression Expression::degreeToRadian() {
|
||||
// e*Pi/180
|
||||
return Multiplication(*this, Rational(1, 180), Constant(Ion::Charset::SmallPi));
|
||||
return Multiplication::Builder(*this, Rational(1, 180), Constant(Ion::Charset::SmallPi));
|
||||
}
|
||||
|
||||
Expression Expression::reduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) {
|
||||
@@ -619,7 +619,7 @@ Expression Expression::CreateComplexExpression(Expression ra, Expression tb, Pre
|
||||
Expression imag;
|
||||
if (!isZeroRa || isZeroTb) {
|
||||
if (isNegativeRa) {
|
||||
real = Opposite(ra);
|
||||
real = Opposite::Builder(ra);
|
||||
} else {
|
||||
real = ra;
|
||||
}
|
||||
@@ -628,21 +628,21 @@ Expression Expression::CreateComplexExpression(Expression ra, Expression tb, Pre
|
||||
if (isOneTb) {
|
||||
imag = Constant(Ion::Charset::IComplex);
|
||||
} else {
|
||||
imag = Multiplication(tb , Constant(Ion::Charset::IComplex));
|
||||
imag = Multiplication::Builder(tb , Constant(Ion::Charset::IComplex));
|
||||
}
|
||||
}
|
||||
if (imag.isUninitialized()) {
|
||||
return real;
|
||||
} else if (real.isUninitialized()) {
|
||||
if (isNegativeTb) {
|
||||
return Opposite(imag);
|
||||
return Opposite::Builder(imag);
|
||||
} else {
|
||||
return imag;
|
||||
}
|
||||
} else if (isNegativeTb) {
|
||||
return Subtraction(real, imag);
|
||||
return Subtraction::Builder(real, imag);
|
||||
} else {
|
||||
return Addition(real, imag);
|
||||
return Addition::Builder(real, imag);
|
||||
}
|
||||
}
|
||||
default:
|
||||
@@ -659,19 +659,19 @@ Expression Expression::CreateComplexExpression(Expression ra, Expression tb, Pre
|
||||
if (isOneTb) {
|
||||
arg = Constant(Ion::Charset::IComplex);
|
||||
} else {
|
||||
arg = Multiplication(tb, Constant(Ion::Charset::IComplex));
|
||||
arg = Multiplication::Builder(tb, Constant(Ion::Charset::IComplex));
|
||||
}
|
||||
if (isNegativeTb) {
|
||||
arg = Opposite(arg);
|
||||
arg = Opposite::Builder(arg);
|
||||
}
|
||||
exp = Power(Constant(Ion::Charset::Exponential), arg);
|
||||
exp = Power::Builder(Constant(Ion::Charset::Exponential), arg);
|
||||
}
|
||||
if (exp.isUninitialized()) {
|
||||
return norm;
|
||||
} else if (norm.isUninitialized()) {
|
||||
return exp;
|
||||
} else {
|
||||
return Multiplication(norm, exp);
|
||||
return Multiplication::Builder(norm, exp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,10 +56,10 @@ Expression Factor::shallowBeautify(Context & context, Preferences::ComplexFormat
|
||||
replaceWithInPlace(result);
|
||||
return result;
|
||||
}
|
||||
result = Division(result, denominatorDecomp.squashUnaryHierarchyInPlace());
|
||||
result = Division::Builder(result, denominatorDecomp.squashUnaryHierarchyInPlace());
|
||||
}
|
||||
if (r.sign() == ExpressionNode::Sign::Negative) {
|
||||
result = Opposite(result);
|
||||
result = Opposite::Builder(result);
|
||||
}
|
||||
replaceWithInPlace(result);
|
||||
return result;
|
||||
@@ -68,7 +68,7 @@ Expression Factor::shallowBeautify(Context & context, Preferences::ComplexFormat
|
||||
Multiplication Factor::createMultiplicationOfIntegerPrimeDecomposition(Integer i, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const {
|
||||
assert(!i.isZero());
|
||||
assert(!i.isNegative());
|
||||
Multiplication m;
|
||||
Multiplication m = Multiplication::Builder();
|
||||
Integer factors[Arithmetic::k_maxNumberOfPrimeFactors];
|
||||
Integer coefficients[Arithmetic::k_maxNumberOfPrimeFactors];
|
||||
int numberOfPrimeFactors = Arithmetic::PrimeFactorization(i, factors, coefficients, Arithmetic::k_maxNumberOfPrimeFactors);
|
||||
@@ -83,7 +83,7 @@ Multiplication Factor::createMultiplicationOfIntegerPrimeDecomposition(Integer i
|
||||
for (int index = 0; index < numberOfPrimeFactors; index++) {
|
||||
Expression factor = Rational(factors[index]);
|
||||
if (!coefficients[index].isOne()) {
|
||||
factor = Power(factor, Rational(coefficients[index]));
|
||||
factor = Power::Builder(factor, Rational(coefficients[index]));
|
||||
}
|
||||
m.addChildAtIndexInPlace(factor, m.numberOfChildren(), m.numberOfChildren());
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ Complex<T> FactorialNode::computeOnComplex(const std::complex<T> c, Preferences:
|
||||
}
|
||||
|
||||
Layout FactorialNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
HorizontalLayout result;
|
||||
HorizontalLayout result = HorizontalLayout::Builder();
|
||||
result.addOrMergeChildAtIndex(childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits), 0, false);
|
||||
int childrenCount = result.numberOfChildren();
|
||||
result.addChildAtIndex(CharLayout('!'), childrenCount, childrenCount, nullptr);
|
||||
@@ -89,8 +89,6 @@ int FactorialNode::serialize(char * buffer, int bufferSize, Preferences::PrintFl
|
||||
return numberOfChar;
|
||||
}
|
||||
|
||||
Factorial::Factorial() : Expression(TreePool::sharedPool()->createTreeNode<FactorialNode>()) {}
|
||||
|
||||
Expression Factorial::shallowReduce() {
|
||||
{
|
||||
Expression e = Expression::defaultShallowReduce();
|
||||
@@ -133,7 +131,7 @@ Expression Factorial::shallowBeautify() {
|
||||
|| childAtIndex(0).type() == ExpressionNode::Type::Multiplication
|
||||
|| childAtIndex(0).type() == ExpressionNode::Type::Power)
|
||||
{
|
||||
Expression result = Factorial(Parenthesis(childAtIndex(0)));
|
||||
Expression result = Factorial::Builder(Parenthesis::Builder(childAtIndex(0)));
|
||||
replaceWithInPlace(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ constexpr Expression::FunctionHelper Floor::s_functionHelper;
|
||||
int FloorNode::numberOfChildren() const { return Floor::s_functionHelper.numberOfChildren(); }
|
||||
|
||||
Layout FloorNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return FloorLayout(childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits));
|
||||
return FloorLayout::Builder(childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits));
|
||||
}
|
||||
|
||||
int FloorNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
|
||||
@@ -216,11 +216,4 @@ void FractionLayoutNode::render(KDContext * ctx, KDPoint p, KDColor expressionCo
|
||||
ctx->fillRect(KDRect(p.x()+Metric::FractionAndConjugateHorizontalMargin, fractionLineY, layoutSize().width()-2*Metric::FractionAndConjugateHorizontalMargin, k_fractionLineHeight), expressionColor);
|
||||
}
|
||||
|
||||
FractionLayout::FractionLayout(Layout numerator, Layout denominator) :
|
||||
Layout(TreePool::sharedPool()->createTreeNode<FractionLayoutNode>())
|
||||
{
|
||||
replaceChildAtIndexInPlace(0, numerator);
|
||||
replaceChildAtIndexInPlace(1, denominator);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -105,7 +105,7 @@ Expression Function::replaceSymbolWithExpression(const SymbolAbstract & symbol,
|
||||
value = value.replaceSymbolWithExpression(xSymbol, xValue);
|
||||
Expression p = parent();
|
||||
if (!p.isUninitialized() && p.node()->childNeedsParenthesis(value.node())) {
|
||||
value = Parenthesis(value);
|
||||
value = Parenthesis::Builder(value);
|
||||
}
|
||||
replaceWithInPlace(value);
|
||||
return value;
|
||||
|
||||
@@ -226,7 +226,7 @@ KDPoint HorizontalLayoutNode::positionOfChild(LayoutNode * l) {
|
||||
|
||||
bool HorizontalLayoutNode::willAddChildAtIndex(LayoutNode * l, int * index, int * currentNumberOfChildren, LayoutCursor * cursor) {
|
||||
if (m_numberOfChildren > 0) {
|
||||
HorizontalLayout thisRef = HorizontalLayout(this);
|
||||
HorizontalLayout thisRef(this);
|
||||
thisRef.removeEmptyChildBeforeInsertionAtIndex(index, currentNumberOfChildren, !l->mustHaveLeftSibling(), cursor);
|
||||
*currentNumberOfChildren = thisRef.numberOfChildren();
|
||||
}
|
||||
@@ -353,33 +353,6 @@ bool HorizontalLayoutNode::willReplaceChild(LayoutNode * oldChild, LayoutNode *
|
||||
|
||||
// HorizontalLayout
|
||||
|
||||
HorizontalLayout::HorizontalLayout() : Layout(TreePool::sharedPool()->createTreeNode<HorizontalLayoutNode>()) {}
|
||||
|
||||
HorizontalLayout::HorizontalLayout(Layout l) : HorizontalLayout() {
|
||||
addChildAtIndexInPlace(l, 0, 0);
|
||||
}
|
||||
|
||||
HorizontalLayout::HorizontalLayout(Layout l1, Layout l2) : HorizontalLayout() {
|
||||
addChildAtIndexInPlace(l1, 0, 0);
|
||||
addChildAtIndexInPlace(l2, 1, 1);
|
||||
}
|
||||
HorizontalLayout::HorizontalLayout(Layout l1, Layout l2, Layout l3) : HorizontalLayout() {
|
||||
addChildAtIndexInPlace(l1, 0, 0);
|
||||
addChildAtIndexInPlace(l2, 1, 1);
|
||||
addChildAtIndexInPlace(l3, 2, 2);
|
||||
}
|
||||
HorizontalLayout::HorizontalLayout(Layout l1, Layout l2, Layout l3, Layout l4) : HorizontalLayout() {
|
||||
addChildAtIndexInPlace(l1, 0, 0);
|
||||
addChildAtIndexInPlace(l2, 1, 1);
|
||||
addChildAtIndexInPlace(l3, 2, 2);
|
||||
addChildAtIndexInPlace(l4, 3, 3);
|
||||
}
|
||||
HorizontalLayout::HorizontalLayout(const Layout * children, size_t numberOfChildren) : HorizontalLayout() {
|
||||
for (size_t i = 0; i < numberOfChildren; i++) {
|
||||
addChildAtIndexInPlace(children[i], i, i);
|
||||
}
|
||||
}
|
||||
|
||||
void HorizontalLayout::addOrMergeChildAtIndex(Layout l, int index, bool removeEmptyChildren, LayoutCursor * cursor) {
|
||||
if (l.isHorizontal()) {
|
||||
mergeChildrenAtIndex(HorizontalLayout(static_cast<HorizontalLayoutNode *>(l.node())), index, removeEmptyChildren, cursor);
|
||||
|
||||
@@ -33,7 +33,7 @@ Expression IntegralNode::replaceUnknown(const Symbol & symbol) {
|
||||
}
|
||||
|
||||
Layout IntegralNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return IntegralLayout(
|
||||
return IntegralLayout::Builder(
|
||||
childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits),
|
||||
childAtIndex(1)->createLayout(floatDisplayMode, numberOfSignificantDigits),
|
||||
childAtIndex(2)->createLayout(floatDisplayMode, numberOfSignificantDigits),
|
||||
|
||||
@@ -97,7 +97,7 @@ void Layout::replaceWithJuxtapositionOf(Layout leftChild, Layout rightChild, Lay
|
||||
if (!p.isHorizontal()) {
|
||||
/* One of the children to juxtapose might be "this", so we cannot just call
|
||||
* replaceWith. */
|
||||
HorizontalLayout horizontalLayoutR;
|
||||
HorizontalLayout horizontalLayoutR = HorizontalLayout::Builder();
|
||||
p.replaceChild(*this, horizontalLayoutR, cursor);
|
||||
horizontalLayoutR.addOrMergeChildAtIndex(leftChild, 0, false);
|
||||
if (putCursorInTheMiddle) {
|
||||
@@ -286,7 +286,7 @@ void Layout::collapseSiblings(LayoutCursor * cursor) {
|
||||
if (node()->shouldCollapseSiblingsOnRight()) {
|
||||
Layout absorbingChild = childAtIndex(rightCollapsingAbsorbingChildIndex());
|
||||
if (!absorbingChild.isHorizontal()) {
|
||||
Layout horRef = HorizontalLayout();
|
||||
Layout horRef = HorizontalLayout::Builder();
|
||||
replaceChild(absorbingChild, horRef, cursor, true);
|
||||
horRef.addChildAtIndexInPlace(absorbingChild, 0, 0);
|
||||
}
|
||||
@@ -295,7 +295,7 @@ void Layout::collapseSiblings(LayoutCursor * cursor) {
|
||||
if (node()->shouldCollapseSiblingsOnLeft()) {
|
||||
Layout absorbingChild = childAtIndex(leftCollapsingAbsorbingChildIndex());
|
||||
if (!absorbingChild.isHorizontal()) {
|
||||
Layout horRef = HorizontalLayout();
|
||||
Layout horRef = HorizontalLayout::Builder();
|
||||
replaceChild(absorbingChild, horRef, cursor, true);
|
||||
horRef.addChildAtIndexInPlace(absorbingChild, 0, 0);
|
||||
}
|
||||
|
||||
@@ -74,15 +74,15 @@ void LayoutCursor::move(MoveDirection direction, bool * shouldRecomputeLayout) {
|
||||
|
||||
void LayoutCursor::addEmptyExponentialLayout() {
|
||||
EmptyLayout emptyLayout;
|
||||
HorizontalLayout sibling = HorizontalLayout(
|
||||
HorizontalLayout sibling = HorizontalLayout::Builder(
|
||||
CharLayout(Ion::Charset::Exponential),
|
||||
VerticalOffsetLayout(emptyLayout, VerticalOffsetLayoutNode::Type::Superscript));
|
||||
VerticalOffsetLayout::Builder(emptyLayout, VerticalOffsetLayoutNode::Type::Superscript));
|
||||
m_layout.addSibling(this, sibling, false);
|
||||
m_layout = emptyLayout;
|
||||
}
|
||||
|
||||
void LayoutCursor::addEmptyMatrixLayout() {
|
||||
MatrixLayout matrixLayout = MatrixLayout(
|
||||
MatrixLayout matrixLayout = MatrixLayout::Builder(
|
||||
EmptyLayout(EmptyLayoutNode::Color::Yellow),
|
||||
EmptyLayout(EmptyLayoutNode::Color::Grey),
|
||||
EmptyLayout(EmptyLayoutNode::Color::Grey),
|
||||
@@ -93,31 +93,31 @@ void LayoutCursor::addEmptyMatrixLayout() {
|
||||
}
|
||||
|
||||
void LayoutCursor::addEmptySquareRootLayout() {
|
||||
HorizontalLayout child1 = HorizontalLayout(EmptyLayout());
|
||||
NthRootLayout newChild = NthRootLayout(child1);
|
||||
HorizontalLayout child1 = HorizontalLayout::Builder(EmptyLayout());
|
||||
NthRootLayout newChild = NthRootLayout::Builder(child1);
|
||||
m_layout.addSibling(this, newChild, false);
|
||||
m_layout = newChild.childAtIndex(0);
|
||||
((Layout *)&newChild)->collapseSiblings(this);
|
||||
}
|
||||
|
||||
void LayoutCursor::addEmptyPowerLayout() {
|
||||
VerticalOffsetLayout offsetLayout = VerticalOffsetLayout(EmptyLayout(), VerticalOffsetLayoutNode::Type::Superscript);
|
||||
VerticalOffsetLayout offsetLayout = VerticalOffsetLayout::Builder(EmptyLayout(), VerticalOffsetLayoutNode::Type::Superscript);
|
||||
privateAddEmptyPowerLayout(offsetLayout);
|
||||
m_layout = offsetLayout.childAtIndex(0);
|
||||
}
|
||||
|
||||
void LayoutCursor::addEmptySquarePowerLayout() {
|
||||
VerticalOffsetLayout offsetLayout = VerticalOffsetLayout(CharLayout('2'), VerticalOffsetLayoutNode::Type::Superscript);
|
||||
VerticalOffsetLayout offsetLayout = VerticalOffsetLayout::Builder(CharLayout('2'), VerticalOffsetLayoutNode::Type::Superscript);
|
||||
privateAddEmptyPowerLayout(offsetLayout);
|
||||
}
|
||||
|
||||
void LayoutCursor::addEmptyTenPowerLayout() {
|
||||
EmptyLayout emptyLayout;
|
||||
HorizontalLayout sibling = HorizontalLayout(
|
||||
HorizontalLayout sibling = HorizontalLayout::Builder(
|
||||
CharLayout(Ion::Charset::MiddleDot),
|
||||
CharLayout('1'),
|
||||
CharLayout('0'),
|
||||
VerticalOffsetLayout(
|
||||
VerticalOffsetLayout::Builder(
|
||||
emptyLayout,
|
||||
VerticalOffsetLayoutNode::Type::Superscript));
|
||||
m_layout.addSibling(this, sibling, false);
|
||||
@@ -125,9 +125,9 @@ void LayoutCursor::addEmptyTenPowerLayout() {
|
||||
}
|
||||
|
||||
void LayoutCursor::addFractionLayoutAndCollapseSiblings() {
|
||||
HorizontalLayout child1 = HorizontalLayout(EmptyLayout());
|
||||
HorizontalLayout child2 = HorizontalLayout(EmptyLayout());
|
||||
FractionLayout newChild = FractionLayout(child1, child2);
|
||||
HorizontalLayout child1 = HorizontalLayout::Builder(EmptyLayout());
|
||||
HorizontalLayout child2 = HorizontalLayout::Builder(EmptyLayout());
|
||||
FractionLayout newChild = FractionLayout::Builder(child1, child2);
|
||||
m_layout.addSibling(this, newChild, true);
|
||||
Layout(newChild.node()).collapseSiblings(this);
|
||||
}
|
||||
@@ -150,12 +150,12 @@ void LayoutCursor::insertText(const char * text) {
|
||||
if (text[i] == Ion::Charset::MultiplicationSign) {
|
||||
newChild = CharLayout(Ion::Charset::MiddleDot);
|
||||
} else if (text[i] == '(') {
|
||||
newChild = LeftParenthesisLayout();
|
||||
newChild = LeftParenthesisLayout::Builder();
|
||||
if (pointedChild.isUninitialized()) {
|
||||
pointedChild = newChild;
|
||||
}
|
||||
} else if (text[i] == ')') {
|
||||
newChild = RightParenthesisLayout();
|
||||
newChild = RightParenthesisLayout::Builder();
|
||||
}
|
||||
/* We never insert text with brackets for now. Removing this code saves the
|
||||
* binary file 2K. */
|
||||
@@ -218,7 +218,7 @@ void LayoutCursor::privateAddEmptyPowerLayout(VerticalOffsetLayout v) {
|
||||
}
|
||||
// Else, add an empty base
|
||||
EmptyLayout e = EmptyLayout();
|
||||
HorizontalLayout newChild = HorizontalLayout(e, v);
|
||||
HorizontalLayout newChild = HorizontalLayout::Builder(e, v);
|
||||
m_layout.addSibling(this, newChild, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Poincare {
|
||||
Layout LayoutHelper::Infix(const Expression & expression, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits, const char * operatorName) {
|
||||
int numberOfChildren = expression.numberOfChildren();
|
||||
assert(numberOfChildren > 1);
|
||||
HorizontalLayout result;
|
||||
HorizontalLayout result = HorizontalLayout::Builder();
|
||||
result.addOrMergeChildAtIndex(expression.childAtIndex(0).createLayout(floatDisplayMode, numberOfSignificantDigits), 0, true);
|
||||
for (int i = 1; i < numberOfChildren; i++) {
|
||||
result.addOrMergeChildAtIndex(String(operatorName, strlen(operatorName)), result.numberOfChildren(), true);
|
||||
@@ -24,12 +24,12 @@ Layout LayoutHelper::Infix(const Expression & expression, Preferences::PrintFloa
|
||||
}
|
||||
|
||||
Layout LayoutHelper::Prefix(const Expression & expression, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits, const char * operatorName) {
|
||||
HorizontalLayout result;
|
||||
HorizontalLayout result = HorizontalLayout::Builder();
|
||||
// Add the operator name.
|
||||
result.addOrMergeChildAtIndex(String(operatorName, strlen(operatorName)), 0, true);
|
||||
|
||||
// Create the layout of arguments separated by commas.
|
||||
HorizontalLayout args;
|
||||
HorizontalLayout args = HorizontalLayout::Builder();
|
||||
int numberOfChildren = expression.numberOfChildren();
|
||||
if (numberOfChildren > 0) {
|
||||
args.addOrMergeChildAtIndex(expression.childAtIndex(0).createLayout(floatDisplayMode, numberOfSignificantDigits), 0, true);
|
||||
@@ -44,18 +44,18 @@ Layout LayoutHelper::Prefix(const Expression & expression, Preferences::PrintFlo
|
||||
}
|
||||
|
||||
Layout LayoutHelper::Parentheses(Layout layout, bool cloneLayout) {
|
||||
HorizontalLayout result;
|
||||
result.addChildAtIndex(LeftParenthesisLayout(), 0, 0, nullptr);
|
||||
HorizontalLayout result = HorizontalLayout::Builder();
|
||||
result.addChildAtIndex(LeftParenthesisLayout::Builder(), 0, 0, nullptr);
|
||||
if (!layout.isUninitialized()) {
|
||||
result.addOrMergeChildAtIndex(cloneLayout ? layout.clone() : layout, 1, true);
|
||||
}
|
||||
result.addChildAtIndex(RightParenthesisLayout(), result.numberOfChildren(), result.numberOfChildren(), nullptr);
|
||||
result.addChildAtIndex(RightParenthesisLayout::Builder(), result.numberOfChildren(), result.numberOfChildren(), nullptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
HorizontalLayout LayoutHelper::String(const char * buffer, int bufferLen, const KDFont * font) {
|
||||
assert(bufferLen > 0);
|
||||
HorizontalLayout resultLayout;
|
||||
HorizontalLayout resultLayout = HorizontalLayout::Builder();
|
||||
for (int i = 0; i < bufferLen; i++) {
|
||||
resultLayout.addChildAtIndex(CharLayout(buffer[i], font), i, i, nullptr);
|
||||
}
|
||||
@@ -64,7 +64,7 @@ HorizontalLayout LayoutHelper::String(const char * buffer, int bufferLen, const
|
||||
|
||||
Layout LayoutHelper::Logarithm(Layout argument, Layout index) {
|
||||
HorizontalLayout resultLayout = String("log", 3);
|
||||
VerticalOffsetLayout offsetLayout = VerticalOffsetLayout(index, VerticalOffsetLayoutNode::Type::Subscript);
|
||||
VerticalOffsetLayout offsetLayout = VerticalOffsetLayout::Builder(index, VerticalOffsetLayoutNode::Type::Subscript);
|
||||
resultLayout.addChildAtIndex(offsetLayout, resultLayout.numberOfChildren(), resultLayout.numberOfChildren(), nullptr);
|
||||
resultLayout.addOrMergeChildAtIndex(Parentheses(argument, false), resultLayout.numberOfChildren(), true);
|
||||
return resultLayout;
|
||||
|
||||
@@ -59,6 +59,4 @@ void LeftParenthesisLayoutNode::render(KDContext * ctx, KDPoint p, KDColor expre
|
||||
RenderWithChildHeight(ParenthesisLayoutNode::ChildHeightGivenLayoutHeight(layoutSize().height()), ctx, p, expressionColor, backgroundColor);
|
||||
}
|
||||
|
||||
LeftParenthesisLayout::LeftParenthesisLayout() : Layout(TreePool::sharedPool()->createTreeNode<LeftParenthesisLayoutNode>()) {}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,6 +8,4 @@ void LeftSquareBracketLayoutNode::render(KDContext * ctx, KDPoint p, KDColor exp
|
||||
ctx->fillRect(KDRect(p.x()+k_externWidthMargin, p.y() + childHeight(), k_bracketWidth, k_lineThickness), expressionColor);
|
||||
}
|
||||
|
||||
LeftSquareBracketLayout::LeftSquareBracketLayout() : Layout(TreePool::sharedPool()->createTreeNode<LeftSquareBracketLayoutNode>()) {}
|
||||
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ Expression Logarithm::shallowReduce(Context & context, Preferences::ComplexForma
|
||||
Expression x = p.childAtIndex(0);
|
||||
Expression y = p.childAtIndex(1);
|
||||
replaceChildInPlace(p, x);
|
||||
Multiplication mult(y);
|
||||
Multiplication mult = Multiplication::Builder(y);
|
||||
replaceWithInPlace(mult);
|
||||
mult.addChildAtIndexInPlace(*this, 1, 1); // --> y*log(x,b)
|
||||
shallowReduce(context, complexFormat, angleUnit, target); // reduce log (ie log(e, e) = 1)
|
||||
@@ -168,7 +168,7 @@ Expression Logarithm::shallowReduce(Context & context, Preferences::ComplexForma
|
||||
}
|
||||
// log(x*y, b)->log(x,b)+log(y, b) if x,y>0
|
||||
if (!letLogAtRoot && c.type() == ExpressionNode::Type::Multiplication) {
|
||||
Addition a = Addition();
|
||||
Addition a = Addition::Builder();
|
||||
for (int i = 0; i < c.numberOfChildren()-1; i++) {
|
||||
Expression factor = c.childAtIndex(i);
|
||||
if (factor.sign(&context) == ExpressionNode::Sign::Positive) {
|
||||
@@ -190,7 +190,7 @@ Expression Logarithm::shallowReduce(Context & context, Preferences::ComplexForma
|
||||
// log(r) with r Rational
|
||||
if (!letLogAtRoot && c.type() == ExpressionNode::Type::Rational) {
|
||||
Rational r = static_cast<Rational &>(c);
|
||||
Addition a;
|
||||
Addition a = Addition::Builder();
|
||||
// if the log base is Integer: log_b(r) = c + log_b(r') with r = b^c*r'
|
||||
if (childAtIndex(1).type() == ExpressionNode::Type::Rational && childAtIndex(1).convert<Rational>().integerDenominator().isOne()) {
|
||||
Integer b = childAtIndex(1).convert<Rational>().signedIntegerNumerator();
|
||||
@@ -320,17 +320,17 @@ Expression Logarithm::splitLogarithmInteger(Integer i, bool isDenominator, Conte
|
||||
if (!isDenominator) {
|
||||
return e;
|
||||
}
|
||||
Multiplication m = Multiplication(Rational(-1), e);
|
||||
Multiplication m = Multiplication::Builder(Rational(-1), e);
|
||||
return m;
|
||||
}
|
||||
Addition a;
|
||||
Addition a = Addition::Builder();
|
||||
for (int index = 0; index < numberOfPrimeFactors; index++) {
|
||||
if (isDenominator) {
|
||||
coefficients[index].setNegative(true);
|
||||
}
|
||||
Logarithm e = clone().convert<Logarithm>();
|
||||
e.replaceChildAtIndexInPlace(0, Rational(factors[index]));
|
||||
Multiplication m = Multiplication(Rational(coefficients[index]), e);
|
||||
Multiplication m = Multiplication::Builder(Rational(coefficients[index]), e);
|
||||
e.simpleShallowReduce(context, complexFormat, angleUnit);
|
||||
a.addChildAtIndexInPlace(m, a.numberOfChildren(), a.numberOfChildren());
|
||||
m.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
|
||||
@@ -23,7 +23,7 @@ int MatrixNode::polynomialDegree(Context & context, const char * symbolName) con
|
||||
|
||||
Layout MatrixNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
assert(numberOfChildren() > 0);
|
||||
MatrixLayout layout;
|
||||
MatrixLayout layout = MatrixLayout::Builder();
|
||||
for (ExpressionNode * c : children()) {
|
||||
layout.addChildAtIndex(c->createLayout(floatDisplayMode, numberOfSignificantDigits), layout.numberOfChildren(), layout.numberOfChildren(), nullptr);
|
||||
}
|
||||
@@ -196,7 +196,7 @@ Matrix Matrix::rowCanonize(Context & context, Preferences::ComplexFormat complex
|
||||
if (!determinant.isUninitialized()) { determinant.addChildAtIndexInPlace(divisor.clone(), 0, determinant.numberOfChildren()); }
|
||||
for (int j = k+1; j < n; j++) {
|
||||
Expression opHJ = matrixChild(h, j);
|
||||
Expression newOpHJ = Division(opHJ, divisor.clone());
|
||||
Expression newOpHJ = Division::Builder(opHJ, divisor.clone());
|
||||
replaceChildAtIndexInPlace(h*n+j, newOpHJ);
|
||||
newOpHJ = newOpHJ.shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::System);
|
||||
}
|
||||
@@ -208,7 +208,7 @@ Matrix Matrix::rowCanonize(Context & context, Preferences::ComplexFormat complex
|
||||
Expression factor = matrixChild(i, k);
|
||||
for (int j = k+1; j < n; j++) {
|
||||
Expression opIJ = matrixChild(i, j);
|
||||
Expression newOpIJ = Subtraction(opIJ, Multiplication(matrixChild(h, j).clone(), factor.clone()));
|
||||
Expression newOpIJ = Subtraction::Builder(opIJ, Multiplication::Builder(matrixChild(h, j).clone(), factor.clone()));
|
||||
replaceChildAtIndexInPlace(i*n+j, newOpIJ);
|
||||
newOpIJ.childAtIndex(1).shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::System);
|
||||
newOpIJ = newOpIJ.shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::System);
|
||||
@@ -305,7 +305,7 @@ Expression Matrix::inverse(Context & context, Preferences::ComplexFormat complex
|
||||
}
|
||||
int dim = m_numberOfRows;
|
||||
/* Create the matrix inv = (A|I) with A the input matrix and I the dim identity matrix */
|
||||
Matrix AI;
|
||||
Matrix AI = Matrix::Builder();
|
||||
for (int i = 0; i < dim; i++) {
|
||||
for (int j = 0; j < dim; j++) {
|
||||
AI.addChildAtIndexInPlace(matrixChild(i, j), i*2*dim+j, i*2*dim+j);
|
||||
|
||||
@@ -38,7 +38,7 @@ bool MatrixComplexNode<T>::isUndefined() const {
|
||||
|
||||
template<typename T>
|
||||
Expression MatrixComplexNode<T>::complexToExpression(Preferences::ComplexFormat complexFormat) const {
|
||||
Matrix matrix = Matrix::EmptyMatrix();
|
||||
Matrix matrix = Matrix::Builder();
|
||||
int i = 0;
|
||||
for (EvaluationNode<T> * c : this->children()) {
|
||||
if (c->type() == EvaluationNode<T>::Type::Complex) {
|
||||
|
||||
@@ -48,14 +48,14 @@ Expression MatrixDimension::shallowReduce() {
|
||||
#if MATRIX_EXACT_REDUCING
|
||||
if (c.type() == ExpressionNode::Type::Matrix) {
|
||||
Matrix m = static_cast<Matrix &>(c);
|
||||
Matrix result;
|
||||
Matrix result = Matrix::Builder();
|
||||
result.addChildAtIndexInPlace(Rational(m.numberOfRows()), 0, 0);
|
||||
result.addChildAtIndexInPlace(Rational(m.numberOfColumns()), 1, 1);
|
||||
result.setDimensions(1, 2);
|
||||
return result;
|
||||
}
|
||||
if (!c.recursivelyMatches(Expression::IsMatrix)) {
|
||||
Matrix result;
|
||||
Matrix result = Matrix::Builder();
|
||||
result.addChildAtIndexInPlace(Rational(1), 0, 0);
|
||||
result.addChildAtIndexInPlace(Rational(1), 1, 1);
|
||||
result.setDimensions(1, 2);
|
||||
@@ -64,7 +64,7 @@ Expression MatrixDimension::shallowReduce() {
|
||||
return *this;
|
||||
#else
|
||||
if (c.type() != ExpressionNode::Type::Matrix) {
|
||||
Matrix result;
|
||||
Matrix result = Matrix::Builder();
|
||||
result.addChildAtIndexInPlace(Rational(1), 0, 0);
|
||||
result.addChildAtIndexInPlace(Rational(1), 1, 1);
|
||||
result.setDimensions(1, 2);
|
||||
|
||||
@@ -53,7 +53,7 @@ Expression MatrixInverse::shallowReduce(Context & context, Preferences::ComplexF
|
||||
#if MATRIX_EXACT_REDUCING
|
||||
#if 0
|
||||
if (!c.recursivelyMatches(Expression::IsMatrix)) {
|
||||
return Power(c, Rational(-1).shallowReduce(context, complexFormat, angleUnit, target);
|
||||
return Power::Builder(c, Rational(-1).shallowReduce(context, complexFormat, angleUnit, target);
|
||||
}
|
||||
if (c.type() == ExpressionNode::Type::Matrix) {
|
||||
Matrix mat = static_cast<Matrix&>(c);
|
||||
@@ -65,7 +65,7 @@ Expression MatrixInverse::shallowReduce(Context & context, Preferences::ComplexF
|
||||
#endif
|
||||
#else
|
||||
if (c.type() != ExpressionNode::Type::Matrix) {
|
||||
Expression result = Power(c, Rational(-1));
|
||||
Expression result = Power::Builder(c, Rational(-1));
|
||||
replaceWithInPlace(result);
|
||||
result = result.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
return result;
|
||||
|
||||
@@ -266,16 +266,4 @@ void MatrixLayoutNode::didReplaceChildAtIndex(int index, LayoutCursor * cursor,
|
||||
}
|
||||
}
|
||||
|
||||
MatrixLayout::MatrixLayout(const MatrixLayoutNode * n) : GridLayout(n) {}
|
||||
MatrixLayout::MatrixLayout() : GridLayout(TreePool::sharedPool()->createTreeNode<MatrixLayoutNode>()) {}
|
||||
MatrixLayout::MatrixLayout(Layout l1, Layout l2, Layout l3, Layout l4) :
|
||||
MatrixLayout()
|
||||
{
|
||||
addChildAtIndexInPlace(l1, 0, 0);
|
||||
addChildAtIndexInPlace(l2, 1, 1);
|
||||
addChildAtIndexInPlace(l3, 2, 2);
|
||||
addChildAtIndexInPlace(l4, 3, 3);
|
||||
setDimensions(2, 2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -108,8 +108,6 @@ Expression MultiplicationNode::denominator(Context & context, Preferences::Compl
|
||||
|
||||
/* Multiplication */
|
||||
|
||||
Multiplication::Multiplication() : NAryExpression(TreePool::sharedPool()->createTreeNode<MultiplicationNode>()) {}
|
||||
|
||||
template<typename T>
|
||||
void Multiplication::computeOnArrays(T * m, T * n, T * result, int mNumberOfColumns, int mNumberOfRows, int nNumberOfColumns) {
|
||||
for (int i = 0; i < mNumberOfRows; i++) {
|
||||
@@ -148,7 +146,7 @@ Expression Multiplication::shallowBeautify(Context & context, Preferences::Compl
|
||||
Expression noNegativeNumeral = makePositiveAnyNegativeNumeralFactor(context, complexFormat, angleUnit, target);
|
||||
// If one negative numeral factor was made positive, we turn the expression in an Opposite
|
||||
if (!noNegativeNumeral.isUninitialized()) {
|
||||
Opposite o = Opposite();
|
||||
Opposite o = Opposite::Builder();
|
||||
noNegativeNumeral.replaceWithInPlace(o);
|
||||
o.replaceChildAtIndexInPlace(0, noNegativeNumeral);
|
||||
return o;
|
||||
@@ -166,7 +164,7 @@ Expression Multiplication::shallowBeautify(Context & context, Preferences::Compl
|
||||
for (int i = 0; i < thisExp.numberOfChildren(); i++) {
|
||||
const Expression o = thisExp.childAtIndex(i);
|
||||
if (o.type() == ExpressionNode::Type::Addition) {
|
||||
Parenthesis p(o);
|
||||
Parenthesis p = Parenthesis::Builder(o);
|
||||
thisExp.replaceChildAtIndexInPlace(i, p);
|
||||
}
|
||||
}
|
||||
@@ -190,7 +188,7 @@ Expression Multiplication::shallowBeautify(Context & context, Preferences::Compl
|
||||
numeratorOperand = numeratorChild0;
|
||||
}
|
||||
Expression originalParent = numeratorOperand.parent();
|
||||
Division d;
|
||||
Division d = Division::Builder();
|
||||
numeratorOperand.replaceWithInPlace(d);
|
||||
d.replaceChildAtIndexInPlace(0, numeratorOperand);
|
||||
d.replaceChildAtIndexInPlace(1, denominatorOperand);
|
||||
@@ -218,18 +216,18 @@ int Multiplication::getPolynomialCoefficients(Context & context, const char * sy
|
||||
assert(degI <= Expression::k_maxPolynomialDegree);
|
||||
for (int j = deg; j > 0; j--) {
|
||||
// new coefficients[j] = b(0)*a(j)+b(1)*a(j-1)+b(2)*a(j-2)+...
|
||||
Addition a;
|
||||
Addition a = Addition::Builder();
|
||||
int jbis = j > degI ? degI : j;
|
||||
for (int l = 0; l <= jbis ; l++) {
|
||||
// Always copy the a and b coefficients are they are used multiple times
|
||||
a.addChildAtIndexInPlace(Multiplication(intermediateCoefficients[l].clone(), coefficients[j-l].clone()), a.numberOfChildren(), a.numberOfChildren());
|
||||
a.addChildAtIndexInPlace(Multiplication::Builder(intermediateCoefficients[l].clone(), coefficients[j-l].clone()), a.numberOfChildren(), a.numberOfChildren());
|
||||
}
|
||||
/* a(j) and b(j) are used only to compute coefficient at rank >= j, we
|
||||
* can delete them as we compute new coefficient by decreasing ranks. */
|
||||
coefficients[j] = a;
|
||||
}
|
||||
// new coefficients[0] = a(0)*b(0)
|
||||
coefficients[0] = Multiplication(coefficients[0], intermediateCoefficients[0]);
|
||||
coefficients[0] = Multiplication::Builder(coefficients[0], intermediateCoefficients[0]);
|
||||
}
|
||||
return deg;
|
||||
}
|
||||
@@ -322,7 +320,7 @@ Expression Multiplication::privateShallowReduce(Context & context, Preferences::
|
||||
int i2 = e%m;
|
||||
int i1 = e/m;
|
||||
for (int j = 0; j < n; j++) {
|
||||
Expression * mult = new Multiplication(currentMatrix->childAtIndex(j+om*i1), resultMatrix->childAtIndex(j*m+i2), true);
|
||||
Expression * mult = new Multiplication::Builder(currentMatrix->childAtIndex(j+om*i1), resultMatrix->childAtIndex(j*m+i2), true);
|
||||
static_cast<Addition *>(newMatrixOperands[e])->addOperand(mult);
|
||||
mult->shallowReduce(context, complexFormat, angleUnit, target);
|
||||
}
|
||||
@@ -538,8 +536,8 @@ void Multiplication::mergeMultiplicationChildrenInPlace() {
|
||||
|
||||
void Multiplication::factorizeBase(int i, int j, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) {
|
||||
/* This function factorizes two children which have a common base. For example
|
||||
* if this is Multiplication(pi^2, pi^3), then pi^2 and pi^3 could be merged
|
||||
* and this turned into Multiplication(pi^5). */
|
||||
* if this is Multiplication::Builder(pi^2, pi^3), then pi^2 and pi^3 could be merged
|
||||
* and this turned into Multiplication::Builder(pi^5). */
|
||||
|
||||
Expression e = childAtIndex(j);
|
||||
// Step 1: Get rid of the child j
|
||||
@@ -553,9 +551,9 @@ void Multiplication::mergeInChildByFactorizingBase(int i, Expression e, Context
|
||||
* and childAtIndex(i) are supposed to have a common base. */
|
||||
|
||||
// Step 1: Find the new exponent
|
||||
Expression s = Addition(CreateExponent(childAtIndex(i)), CreateExponent(e)); // pi^2*pi^3 -> pi^(2+3) -> pi^5
|
||||
Expression s = Addition::Builder(CreateExponent(childAtIndex(i)), CreateExponent(e)); // pi^2*pi^3 -> pi^(2+3) -> pi^5
|
||||
// Step 2: Create the new Power
|
||||
Expression p = Power(Base(childAtIndex(i)), s); // pi^2*pi^-2 -> pi^0 -> 1
|
||||
Expression p = Power::Builder(Base(childAtIndex(i)), s); // pi^2*pi^-2 -> pi^0 -> 1
|
||||
s.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
// Step 3: Replace one of the child
|
||||
replaceChildAtIndexInPlace(i, p);
|
||||
@@ -570,10 +568,10 @@ void Multiplication::mergeInChildByFactorizingBase(int i, Expression e, Context
|
||||
|
||||
void Multiplication::factorizeExponent(int i, int j, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) {
|
||||
/* This function factorizes children which share a common exponent. For
|
||||
* example, it turns Multiplication(2^x,3^x) into Multiplication(6^x). */
|
||||
* example, it turns Multiplication::Builder(2^x,3^x) into Multiplication::Builder(6^x). */
|
||||
|
||||
// Step 1: Find the new base
|
||||
Expression m = Multiplication(Base(childAtIndex(i)), Base(childAtIndex(j))); // 2^x*3^x -> (2*3)^x -> 6^x
|
||||
Expression m = Multiplication::Builder(Base(childAtIndex(i)), Base(childAtIndex(j))); // 2^x*3^x -> (2*3)^x -> 6^x
|
||||
// Step 2: Get rid of one of the children
|
||||
removeChildAtIndexInPlace(j);
|
||||
// Step 3: Replace the other child
|
||||
@@ -595,7 +593,7 @@ Expression Multiplication::distributeOnOperandAtIndex(int i, Context & context,
|
||||
assert(i >= 0 && i < numberOfChildren());
|
||||
assert(childAtIndex(i).type() == ExpressionNode::Type::Addition);
|
||||
|
||||
Addition a;
|
||||
Addition a = Addition::Builder();
|
||||
Expression childI = childAtIndex(i);
|
||||
int numberOfAdditionTerms = childI.numberOfChildren();
|
||||
for (int j = 0; j < numberOfAdditionTerms; j++) {
|
||||
@@ -635,13 +633,13 @@ void Multiplication::addMissingFactors(Expression factor, Context & context, Pre
|
||||
* base if any. Otherwise, we add it as an new child. */
|
||||
for (int i = 0; i < numberOfChildren(); i++) {
|
||||
if (TermsHaveIdenticalBase(childAtIndex(i), factor)) {
|
||||
Expression sub = Subtraction(CreateExponent(childAtIndex(i)), CreateExponent(factor)).deepReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User);
|
||||
Expression sub = Subtraction::Builder(CreateExponent(childAtIndex(i)), CreateExponent(factor)).deepReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User);
|
||||
if (sub.sign(&context) == ExpressionNode::Sign::Negative) { // index[0] < index[1]
|
||||
sub = Opposite(sub);
|
||||
sub = Opposite::Builder(sub);
|
||||
if (factor.type() == ExpressionNode::Type::Power) {
|
||||
factor.replaceChildAtIndexInPlace(1, sub);
|
||||
} else {
|
||||
factor = Power(factor, sub);
|
||||
factor = Power::Builder(factor, sub);
|
||||
}
|
||||
sub.shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User);
|
||||
mergeInChildByFactorizingBase(i, factor, context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User);
|
||||
@@ -677,20 +675,20 @@ void Multiplication::factorizeSineAndCosine(int i, int j, Context & context, Pre
|
||||
if (p.isRationalOne()) {
|
||||
replaceChildAtIndexInPlace(i, tan);
|
||||
} else {
|
||||
replaceChildAtIndexInPlace(i, Power(tan, p));
|
||||
replaceChildAtIndexInPlace(i, Power::Builder(tan, p));
|
||||
}
|
||||
childAtIndex(i).shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User);
|
||||
// Replace cos(x)^q by cos(x)^(p+q)
|
||||
replaceChildAtIndexInPlace(j, Power(Base(childAtIndex(j)), sumPQ));
|
||||
replaceChildAtIndexInPlace(j, Power::Builder(Base(childAtIndex(j)), sumPQ));
|
||||
childAtIndex(j).shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User);
|
||||
} else {
|
||||
// Replace cos(x)^q by tan(x)^(-q)
|
||||
Expression newPower = Power(tan, Number::Multiplication(q, Rational(-1)));
|
||||
Expression newPower = Power::Builder(tan, Number::Multiplication(q, Rational(-1)));
|
||||
newPower.childAtIndex(1).shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User);
|
||||
replaceChildAtIndexInPlace(j, newPower);
|
||||
newPower.shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User);
|
||||
// Replace sin(x)^p by sin(x)^(p+q)
|
||||
replaceChildAtIndexInPlace(i, Power(Base(childAtIndex(i)), sumPQ));
|
||||
replaceChildAtIndexInPlace(i, Power::Builder(Base(childAtIndex(i)), sumPQ));
|
||||
childAtIndex(i).shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User);
|
||||
}
|
||||
}
|
||||
@@ -745,7 +743,7 @@ bool Multiplication::TermHasNumeralExponent(const Expression & e) {
|
||||
Expression Multiplication::mergeNegativePower(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) {
|
||||
/* mergeNegativePower groups all factors that are power of form a^(-b) together
|
||||
* for instance, a^(-1)*b^(-c)*c = c*(a*b^c)^(-1) */
|
||||
Multiplication m;
|
||||
Multiplication m = Multiplication::Builder();
|
||||
// Special case for rational p/q: if q != 1, q should be at denominator
|
||||
if (childAtIndex(0).type() == ExpressionNode::Type::Rational && !childAtIndex(0).convert<Rational>().integerDenominator().isOne()) {
|
||||
Rational r = childAtIndex(0).convert<Rational>();
|
||||
@@ -780,7 +778,7 @@ Expression Multiplication::mergeNegativePower(Context & context, Preferences::Co
|
||||
return *this;
|
||||
}
|
||||
m.sortChildrenInPlace([](const ExpressionNode * e1, const ExpressionNode * e2, bool canBeInterrupted) { return ExpressionNode::SimplificationOrder(e1, e2, true, canBeInterrupted); }, true);
|
||||
Power p(m.squashUnaryHierarchyInPlace(), Rational(-1));
|
||||
Power p = Power::Builder(m.squashUnaryHierarchyInPlace(), Rational(-1));
|
||||
addChildAtIndexInPlace(p, 0, numberOfChildren());
|
||||
sortChildrenInPlace([](const ExpressionNode * e1, const ExpressionNode * e2, bool canBeInterrupted) { return ExpressionNode::SimplificationOrder(e1, e2, true, canBeInterrupted); }, true);
|
||||
return squashUnaryHierarchyInPlace();
|
||||
|
||||
@@ -19,7 +19,7 @@ constexpr Expression::FunctionHelper NthRoot::s_functionHelper;
|
||||
int NthRootNode::numberOfChildren() const { return NthRoot::s_functionHelper.numberOfChildren(); }
|
||||
|
||||
Layout NthRootNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return NthRootLayout(
|
||||
return NthRootLayout::Builder(
|
||||
childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits),
|
||||
childAtIndex(1)->createLayout(floatDisplayMode, numberOfSignificantDigits));
|
||||
}
|
||||
@@ -75,8 +75,8 @@ Expression NthRoot::shallowReduce(Context & context, Preferences::ComplexFormat
|
||||
return Undefined();
|
||||
}
|
||||
#endif
|
||||
Expression invIndex = Power(childAtIndex(1), Rational(-1));
|
||||
Power p = Power(childAtIndex(0), invIndex);
|
||||
Expression invIndex = Power::Builder(childAtIndex(1), Rational(-1));
|
||||
Power p = Power::Builder(childAtIndex(0), invIndex);
|
||||
invIndex.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
replaceWithInPlace(p);
|
||||
return p.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
|
||||
@@ -270,16 +270,4 @@ void NthRootLayoutNode::render(KDContext * ctx, KDPoint p, KDColor expressionCol
|
||||
}
|
||||
}
|
||||
|
||||
NthRootLayout::NthRootLayout(Layout radicand) : NthRootLayout() {
|
||||
replaceChildAtIndexInPlace(0, radicand);
|
||||
}
|
||||
|
||||
NthRootLayout::NthRootLayout(Layout radicand, Layout index) : NthRootLayout() {
|
||||
replaceChildAtIndexInPlace(0, radicand);
|
||||
addChildAtIndexInPlace(index, 1, 1);
|
||||
static_cast<NthRootLayoutNode *>(node())->setNumberOfChildren(2);
|
||||
}
|
||||
|
||||
NthRootLayout::NthRootLayout() : Layout(TreePool::sharedPool()->createTreeNode<NthRootLayoutNode>()) {}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ bool OppositeNode::childNeedsParenthesis(const TreeNode * child) const {
|
||||
}
|
||||
|
||||
Layout OppositeNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
HorizontalLayout result = HorizontalLayout(CharLayout('-'));
|
||||
HorizontalLayout result = HorizontalLayout::Builder(CharLayout('-'));
|
||||
if (childAtIndex(0)->type() == Type::Opposite) {
|
||||
result.addOrMergeChildAtIndex(LayoutHelper::Parentheses(childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits), false), 1, false);
|
||||
} else {
|
||||
@@ -69,8 +69,6 @@ Expression OppositeNode::shallowReduce(Context & context, Preferences::ComplexFo
|
||||
|
||||
/* Simplification */
|
||||
|
||||
Opposite::Opposite() : Expression(TreePool::sharedPool()->createTreeNode<OppositeNode>()) {}
|
||||
|
||||
Expression Opposite::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) {
|
||||
Expression result = Expression::defaultShallowReduce();
|
||||
if (result.isUndefined()) {
|
||||
@@ -79,7 +77,7 @@ Expression Opposite::shallowReduce(Context & context, Preferences::ComplexFormat
|
||||
Expression child = result.childAtIndex(0);
|
||||
#if MATRIX_EXACT_REDUCING
|
||||
#endif
|
||||
result = Multiplication(Rational(-1), child);
|
||||
result = Multiplication::Builder(Rational(-1), child);
|
||||
replaceWithInPlace(result);
|
||||
return result.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ void Parser::parseNumber(Expression & leftHandSide, Token::Type stoppingType) {
|
||||
void Parser::parsePlus(Expression & leftHandSide, Token::Type stoppingType) {
|
||||
Expression rightHandSide;
|
||||
if (parseBinaryOperator(leftHandSide, rightHandSide, Token::Plus)) {
|
||||
leftHandSide = Addition(leftHandSide, rightHandSide);
|
||||
leftHandSide = Addition::Builder(leftHandSide, rightHandSide);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,41 +173,41 @@ void Parser::parseMinus(Expression & leftHandSide, Token::Type stoppingType) {
|
||||
if (m_status != Status::Progress) {
|
||||
return;
|
||||
}
|
||||
leftHandSide = Opposite(rightHandSide);
|
||||
leftHandSide = Opposite::Builder(rightHandSide);
|
||||
} else {
|
||||
Expression rightHandSide = parseUntil(Token::Minus); // Subtraction is left-associative
|
||||
if (m_status != Status::Progress) {
|
||||
return;
|
||||
}
|
||||
leftHandSide = Subtraction(leftHandSide, rightHandSide);
|
||||
leftHandSide = Subtraction::Builder(leftHandSide, rightHandSide);
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::parseTimes(Expression & leftHandSide, Token::Type stoppingType) {
|
||||
Expression rightHandSide;
|
||||
if (parseBinaryOperator(leftHandSide, rightHandSide, Token::Times)) {
|
||||
leftHandSide = Multiplication(leftHandSide, rightHandSide);
|
||||
leftHandSide = Multiplication::Builder(leftHandSide, rightHandSide);
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::parseSlash(Expression & leftHandSide, Token::Type stoppingType) {
|
||||
Expression rightHandSide;
|
||||
if (parseBinaryOperator(leftHandSide, rightHandSide, Token::Slash)) {
|
||||
leftHandSide = Division(leftHandSide, rightHandSide);
|
||||
leftHandSide = Division::Builder(leftHandSide, rightHandSide);
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::parseImplicitTimes(Expression & leftHandSide, Token::Type stoppingType) {
|
||||
Expression rightHandSide;
|
||||
if (parseBinaryOperator(leftHandSide, rightHandSide, Token::Slash)) {
|
||||
leftHandSide = Multiplication(leftHandSide, rightHandSide);
|
||||
leftHandSide = Multiplication::Builder(leftHandSide, rightHandSide);
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::parseCaret(Expression & leftHandSide, Token::Type stoppingType) {
|
||||
Expression rightHandSide;
|
||||
if (parseBinaryOperator(leftHandSide, rightHandSide, Token::ImplicitTimes)) {
|
||||
leftHandSide = Power(leftHandSide, rightHandSide);
|
||||
leftHandSide = Power::Builder(leftHandSide, rightHandSide);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,7 +252,7 @@ void Parser::parseStore(Expression & leftHandSide, Token::Type stoppingType) {
|
||||
m_status = Status::Error; // Store expects a single symbol or function.
|
||||
return;
|
||||
}
|
||||
leftHandSide = Store(leftHandSide, static_cast<SymbolAbstract&>(rightHandSide));
|
||||
leftHandSide = Store::Builder(leftHandSide, static_cast<SymbolAbstract&>(rightHandSide));
|
||||
}
|
||||
|
||||
void Parser::parseLeftSuperscript(Expression & leftHandSide, Token::Type stoppingType) {
|
||||
@@ -268,7 +268,7 @@ void Parser::parseLeftSuperscript(Expression & leftHandSide, Token::Type stoppin
|
||||
m_status = Status::Error; // Right superscript marker missing.
|
||||
return;
|
||||
}
|
||||
leftHandSide = Power(leftHandSide, rightHandSide);
|
||||
leftHandSide = Power::Builder(leftHandSide, rightHandSide);
|
||||
isThereImplicitMultiplication();
|
||||
}
|
||||
|
||||
@@ -301,7 +301,7 @@ void Parser::parseLeftParenthesis(Expression & leftHandSide, Token::Type stoppin
|
||||
m_status = Status::Error; // Right parenthesis missing.
|
||||
return;
|
||||
}
|
||||
leftHandSide = Parenthesis(leftHandSide);
|
||||
leftHandSide = Parenthesis::Builder(leftHandSide);
|
||||
isThereImplicitMultiplication();
|
||||
}
|
||||
|
||||
@@ -309,7 +309,7 @@ void Parser::parseBang(Expression & leftHandSide, Token::Type stoppingType) {
|
||||
if (leftHandSide.isUninitialized()) {
|
||||
m_status = Status::Error; // Left-hand side missing
|
||||
} else {
|
||||
leftHandSide = Factorial(leftHandSide);
|
||||
leftHandSide = Factorial::Builder(leftHandSide);
|
||||
}
|
||||
isThereImplicitMultiplication();
|
||||
}
|
||||
@@ -363,7 +363,7 @@ void Parser::parseSequence(Expression & leftHandSide, const char name, Token::Ty
|
||||
} else if (rank.isIdenticalTo(Symbol("n",1))) {
|
||||
char sym[5] = {name, '(', 'n', ')', 0};
|
||||
leftHandSide = Symbol(sym, 4);
|
||||
} else if (rank.isIdenticalTo(Addition(Symbol("n",1),Rational("1")))) {
|
||||
} else if (rank.isIdenticalTo(Addition::Builder(Symbol("n",1),Rational("1")))) {
|
||||
char sym[7] = {name, '(', 'n', '+', '1', ')', 0};
|
||||
leftHandSide = Symbol(sym, 6);
|
||||
} else {
|
||||
@@ -459,7 +459,7 @@ Expression Parser::parseFunctionParameters() {
|
||||
return Expression();
|
||||
}
|
||||
if (popTokenIfType(Token::RightParenthesis)) {
|
||||
return Matrix(); // The function has no parameter.
|
||||
return Matrix::Builder(); // The function has no parameter.
|
||||
}
|
||||
Expression commaSeparatedList = parseCommaSeparatedList();
|
||||
if (m_status != Status::Progress) {
|
||||
@@ -477,7 +477,7 @@ void Parser::parseMatrix(Expression & leftHandSide, Token::Type stoppingType) {
|
||||
m_status = Status::Error; //FIXME
|
||||
return;
|
||||
}
|
||||
Matrix matrix;
|
||||
Matrix matrix = Matrix::Builder();
|
||||
int numberOfRows = 0;
|
||||
int numberOfColumns = 0;
|
||||
while (!popTokenIfType(Token::RightBracket)) {
|
||||
@@ -520,7 +520,7 @@ Expression Parser::parseVector() {
|
||||
}
|
||||
|
||||
Expression Parser::parseCommaSeparatedList() {
|
||||
Matrix commaSeparatedList;
|
||||
Matrix commaSeparatedList = Matrix::Builder();
|
||||
int length = 0;
|
||||
do {
|
||||
Expression item = parseUntil(Token::Comma);
|
||||
|
||||
@@ -134,9 +134,9 @@ Layout PowerNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int
|
||||
if (indiceOperand->type() == ExpressionNode::Type::Parenthesis) {
|
||||
indiceOperand = indiceOperand->childAtIndex(0);
|
||||
}
|
||||
HorizontalLayout result = HorizontalLayout();
|
||||
HorizontalLayout result = HorizontalLayout::Builder();
|
||||
result.addOrMergeChildAtIndex(childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits), 0, false);
|
||||
result.addChildAtIndex(VerticalOffsetLayout(
|
||||
result.addChildAtIndex(VerticalOffsetLayout::Builder(
|
||||
indiceOperand->createLayout(floatDisplayMode, numberOfSignificantDigits),
|
||||
VerticalOffsetLayoutNode::Type::Superscript),
|
||||
result.numberOfChildren(),
|
||||
@@ -235,15 +235,11 @@ template<typename T> MatrixComplex<T> PowerNode::computeOnMatrices(const MatrixC
|
||||
}
|
||||
|
||||
// Power
|
||||
Power::Power(Expression base, Expression exponent) : Expression(TreePool::sharedPool()->createTreeNode<PowerNode>()) {
|
||||
replaceChildAtIndexInPlace(0, base);
|
||||
replaceChildAtIndexInPlace(1, exponent);
|
||||
}
|
||||
|
||||
Expression Power::setSign(ExpressionNode::Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) {
|
||||
assert(s == ExpressionNode::Sign::Positive);
|
||||
if (childAtIndex(0).sign(context) == ExpressionNode::Sign::Negative) {
|
||||
Expression result = Power(childAtIndex(0).setSign(ExpressionNode::Sign::Positive, context, complexFormat, angleUnit, target), childAtIndex(1));
|
||||
Expression result = Power::Builder(childAtIndex(0).setSign(ExpressionNode::Sign::Positive, context, complexFormat, angleUnit, target), childAtIndex(1));
|
||||
replaceWithInPlace(result);
|
||||
return result.shallowReduce(*context, complexFormat, angleUnit, target);
|
||||
}
|
||||
@@ -321,7 +317,7 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co
|
||||
if (exp == 0) {
|
||||
return replaceWith(id, true);
|
||||
}
|
||||
Multiplication * result = new Multiplication(id, mat->clone());
|
||||
Multiplication * result = new Multiplication::Builder(id, mat->clone());
|
||||
// TODO: implement a quick exponentiation
|
||||
for (int k = 1; k < exp; k++) {
|
||||
result->addOperand(mat->clone());
|
||||
@@ -487,7 +483,7 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co
|
||||
if (childAtIndex(0).sign(&context) == ExpressionNode::Sign::Negative) {
|
||||
// (-inf)^x --> (-1)^x*inf
|
||||
Power p(Rational(-1), childAtIndex(1));
|
||||
result = Multiplication(p, result);
|
||||
result = Multiplication::Builder(p, result);
|
||||
p.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
}
|
||||
}
|
||||
@@ -524,7 +520,7 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co
|
||||
if (!m0.isUninitialized()) {
|
||||
replaceChildAtIndexInPlace(0, m0);
|
||||
// m0 doest not need to be shallowReduce as makePositiveAnyNegativeNumeralFactor returns a reduced expression
|
||||
Multiplication m1 = Multiplication();
|
||||
Multiplication m1;
|
||||
replaceWithInPlace(m1);
|
||||
// Multiply m1 by i complex
|
||||
Constant i(Ion::Charset::IComplex);
|
||||
@@ -546,9 +542,9 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co
|
||||
Expression cos = Cosine::Builder(m);
|
||||
m = m.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
Expression sin = Sine::Builder(m.clone());
|
||||
Expression complexPart = Multiplication(sin, i);
|
||||
Expression complexPart = Multiplication::Builder(sin, i);
|
||||
sin.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
Expression a = Addition(cos, complexPart);
|
||||
Expression a = Addition::Builder(cos, complexPart);
|
||||
cos.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
complexPart.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
replaceWithInPlace(a);
|
||||
@@ -624,11 +620,11 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co
|
||||
m.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
|
||||
// |a|^r
|
||||
Power p = Power(factor, rCopy);
|
||||
Power p = Power::Builder(factor, rCopy);
|
||||
|
||||
// |a|^r*(sign(a)*b*...)^r
|
||||
Power thisRef = *this;
|
||||
Multiplication root = Multiplication(p);
|
||||
Multiplication root = Multiplication::Builder(p);
|
||||
replaceWithInPlace(root);
|
||||
root.addChildAtIndexInPlace(thisRef, 1, 1);
|
||||
p.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
@@ -665,12 +661,12 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co
|
||||
if (RationalExponentShouldNotBeReduced(rationalBase, rationalIndex)) {
|
||||
return *this;
|
||||
}
|
||||
Power p1 = Power(childAtIndex(0).clone(), a.childAtIndex(0));
|
||||
Power p1 = Power::Builder(childAtIndex(0).clone(), a.childAtIndex(0));
|
||||
Power thisRef = *this;
|
||||
childAtIndex(1).convert<Addition>().removeChildAtIndexInPlace(0); // p2 = a^(c+...)
|
||||
// if addition had only 2 children
|
||||
childAtIndex(1).convert<Addition>().squashUnaryHierarchyInPlace();
|
||||
Multiplication m = Multiplication(p1);
|
||||
Multiplication m = Multiplication::Builder(p1);
|
||||
replaceWithInPlace(m);
|
||||
m.addChildAtIndexInPlace(thisRef, 1, 1);
|
||||
p1.simplifyRationalRationalPower(context, complexFormat, angleUnit, target);
|
||||
@@ -711,13 +707,13 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co
|
||||
// result = result * (a0+a1+...+a(m-1) in its expanded form
|
||||
if (result.type() == ExpressionNode::Type::Addition) {
|
||||
// We need a 'double' distribution and newA will hold the new expanded form
|
||||
Expression newA = Addition();
|
||||
Expression newA = Addition::Builder();
|
||||
for (int j = 0; j < a.numberOfChildren(); j++) {
|
||||
Expression m = Multiplication(result.clone(), a.childAtIndex(j).clone()).distributeOnOperandAtIndex(0, context, complexFormat, angleUnit, target);
|
||||
Expression m = Multiplication::Builder(result.clone(), a.childAtIndex(j).clone()).distributeOnOperandAtIndex(0, context, complexFormat, angleUnit, target);
|
||||
if (newA.type() == ExpressionNode::Type::Addition) {
|
||||
static_cast<Addition &>(newA).addChildAtIndexInPlace(m, newA.numberOfChildren(), newA.numberOfChildren());
|
||||
} else {
|
||||
newA = Addition(newA, m);
|
||||
newA = Addition::Builder(newA, m);
|
||||
}
|
||||
newA = newA.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
}
|
||||
@@ -725,7 +721,7 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co
|
||||
result = newA;
|
||||
} else {
|
||||
// Just distribute result on a
|
||||
Multiplication m = Multiplication(a.clone(), result.clone());
|
||||
Multiplication m = Multiplication::Builder(a.clone(), result.clone());
|
||||
Expression distributedM = m.distributeOnOperandAtIndex(0, context, complexFormat, angleUnit, target);
|
||||
result.replaceWithInPlace(distributedM);
|
||||
result = distributedM;
|
||||
@@ -757,10 +753,10 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co
|
||||
Addition * a = new Addition();
|
||||
for (int i = 0; i <= clippedN; i++) {
|
||||
Rational * r = new Rational(static_cast<int>(BinomialCoefficient::compute(static_cast<double>(i), static_cast<double>(clippedN))));
|
||||
Power * p0 = new Power(x0->clone(), new Rational(i), false);
|
||||
Power * p1 = new Power(x1->clone(), new Rational(clippedN-i), false);
|
||||
Power * p0 = new Power::Builder(x0->clone(), new Rational(i), false);
|
||||
Power * p1 = new Power::Builder(x1->clone(), new Rational(clippedN-i), false);
|
||||
const Expression * operands[3] = {r, p0, p1};
|
||||
Multiplication * m = new Multiplication(operands, 3, false);
|
||||
Multiplication * m = new Multiplication::Builder(operands, 3, false);
|
||||
p0->shallowReduce(context, complexFormat, angleUnit, target);
|
||||
p1->shallowReduce(context, complexFormat, angleUnit, target);
|
||||
a->addOperand(m);
|
||||
@@ -783,7 +779,7 @@ Expression Power::shallowBeautify(Context & context, Preferences::ComplexFormat
|
||||
Expression p = denominator(context, complexFormat, angleUnit);
|
||||
// If the denominator is initialized, the index of the power is of form -y
|
||||
if (!p.isUninitialized()) {
|
||||
Division d = Division(Rational(1), p);
|
||||
Division d = Division::Builder(Rational(1), p);
|
||||
p.shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User);
|
||||
replaceWithInPlace(d);
|
||||
return d.shallowBeautify(context, complexFormat, angleUnit, target);
|
||||
@@ -811,7 +807,7 @@ Expression Power::shallowBeautify(Context & context, Preferences::ComplexFormat
|
||||
Integer p = childAtIndex(1).convert<Rational>().signedIntegerNumerator();
|
||||
Integer q = childAtIndex(1).convert<Rational>().integerDenominator();
|
||||
Expression nthRoot = q.isOne() ? childAtIndex(0) : NthRoot::Builder(childAtIndex(0), Rational(q));
|
||||
Expression result = p.isOne() ? nthRoot : Power(nthRoot, Rational(p));
|
||||
Expression result = p.isOne() ? nthRoot : Power::Builder(nthRoot, Rational(p));
|
||||
replaceWithInPlace(result);
|
||||
return result;
|
||||
}
|
||||
@@ -820,7 +816,7 @@ Expression Power::shallowBeautify(Context & context, Preferences::ComplexFormat
|
||||
if (childAtIndex(0).type() == ExpressionNode::Type::Addition
|
||||
|| childAtIndex(0).type() == ExpressionNode::Type::Multiplication)
|
||||
{
|
||||
Parenthesis p = Parenthesis(childAtIndex(0));
|
||||
Parenthesis p = Parenthesis::Builder(childAtIndex(0));
|
||||
replaceChildAtIndexInPlace(0, p);
|
||||
}
|
||||
return *this;
|
||||
@@ -831,7 +827,7 @@ Expression Power::shallowBeautify(Context & context, Preferences::ComplexFormat
|
||||
// Simplification
|
||||
Expression Power::denominator(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const {
|
||||
// Clone the power
|
||||
Expression clone = Power(childAtIndex(0).clone(), childAtIndex(1).clone());
|
||||
Expression clone = Power::Builder(childAtIndex(0).clone(), childAtIndex(1).clone());
|
||||
// If the power is of form x^(-y), denominator should be x^y
|
||||
Expression positiveIndex = clone.childAtIndex(1).makePositiveAnyNegativeNumeralFactor(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User);
|
||||
if (!positiveIndex.isUninitialized()) {
|
||||
@@ -848,7 +844,7 @@ Expression Power::denominator(Context & context, Preferences::ComplexFormat comp
|
||||
Expression Power::simplifyPowerPower(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) {
|
||||
// this is p^e = (a^b)^e, we want a^(b*e)
|
||||
Expression p = childAtIndex(0);
|
||||
Multiplication m(p.childAtIndex(1), childAtIndex(1));
|
||||
Multiplication m = Multiplication::Builder(p.childAtIndex(1), childAtIndex(1));
|
||||
replaceChildAtIndexInPlace(0, p.childAtIndex(0));
|
||||
replaceChildAtIndexInPlace(1, m);
|
||||
m.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
@@ -860,7 +856,7 @@ Expression Power::simplifyPowerMultiplication(Context& context, Preferences::Com
|
||||
Expression m = childAtIndex(0);
|
||||
Expression r = childAtIndex(1);
|
||||
for (int index = 0; index < m.numberOfChildren(); index++) {
|
||||
Power p = Power(m.childAtIndex(index).clone(), r.clone()); // We copy r and factor to avoid inheritance issues
|
||||
Power p = Power::Builder(m.childAtIndex(index).clone(), r.clone()); // We copy r and factor to avoid inheritance issues
|
||||
m.replaceChildAtIndexInPlace(index, p);
|
||||
p.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
}
|
||||
@@ -875,7 +871,7 @@ Expression Power::simplifyRationalRationalPower(Context& context, Preferences::C
|
||||
if (b.integerDenominator().isOne()) {
|
||||
Rational r = Rational::IntegerPower(a, b.signedIntegerNumerator());
|
||||
if (r.numeratorOrDenominatorIsInfinity()) {
|
||||
return Power(a, b);
|
||||
return Power::Builder(a, b);
|
||||
}
|
||||
replaceWithInPlace(r);
|
||||
return r;
|
||||
@@ -890,7 +886,7 @@ Expression Power::simplifyRationalRationalPower(Context& context, Preferences::C
|
||||
n = CreateSimplifiedIntegerRationalPower(a.signedIntegerNumerator(), b, false, context, complexFormat, angleUnit, target);
|
||||
d = CreateSimplifiedIntegerRationalPower(a.integerDenominator(), b, true, context, complexFormat, angleUnit, target);
|
||||
}
|
||||
Multiplication m = Multiplication(n, d);
|
||||
Multiplication m = Multiplication::Builder(n, d);
|
||||
replaceWithInPlace(m);
|
||||
return m.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
}
|
||||
@@ -908,7 +904,7 @@ Expression Power::CreateSimplifiedIntegerRationalPower(Integer i, Rational r, bo
|
||||
/* We could not break i in prime factors (it might take either too many
|
||||
* factors or too much time). */
|
||||
Expression rClone = r.clone().setSign(isDenominator ? ExpressionNode::Sign::Negative : ExpressionNode::Sign::Positive, &context, complexFormat, angleUnit, target);
|
||||
return Power(Rational(i), rClone);
|
||||
return Power::Builder(Rational(i), rClone);
|
||||
}
|
||||
|
||||
Integer r1(1);
|
||||
@@ -921,19 +917,19 @@ Expression Power::CreateSimplifiedIntegerRationalPower(Integer i, Rational r, bo
|
||||
}
|
||||
if (r2.isOverflow() || r1.isOverflow()) {
|
||||
// we overflow Integer at one point: we abort
|
||||
return Power(Rational(i), r.clone());
|
||||
return Power::Builder(Rational(i), r.clone());
|
||||
}
|
||||
Rational p1 = Rational(r2);
|
||||
Integer oneExponent = isDenominator ? Integer(-1) : Integer(1);
|
||||
Integer rDenominator = r.integerDenominator();
|
||||
Rational p2 = Rational(oneExponent, rDenominator);
|
||||
Power p = Power(p1, p2);
|
||||
Power p = Power::Builder(p1, p2);
|
||||
if (r1.isEqualTo(Integer(1)) && !i.isNegative()) {
|
||||
return p;
|
||||
}
|
||||
Integer one(1);
|
||||
Rational r3 = isDenominator ? Rational(one, r1) : Rational(r1);
|
||||
Multiplication m;
|
||||
Multiplication m = Multiplication::Builder();
|
||||
m.addChildAtIndexInPlace(r3, 0, 0);
|
||||
if (!r2.isOne()) {
|
||||
m.addChildAtIndexInPlace(p, 1, 1);
|
||||
@@ -981,12 +977,12 @@ Expression Power::removeSquareRootsFromDenominator(Context & context, Preference
|
||||
if (pq.isOverflow()) {
|
||||
return result;
|
||||
}
|
||||
Power sqrt = Power(Rational(pq), Rational(1, 2));
|
||||
Power sqrt = Power::Builder(Rational(pq), Rational(1, 2));
|
||||
Integer one(1);
|
||||
if (castedChild1.isHalf()) {
|
||||
result = Multiplication(Rational(one, q), sqrt);
|
||||
result = Multiplication::Builder(Rational(one, q), sqrt);
|
||||
} else {
|
||||
result = Multiplication(Rational(one, p), sqrt); // We use here the assertion that p != 0
|
||||
result = Multiplication::Builder(Rational(one, p), sqrt); // We use here the assertion that p != 0
|
||||
}
|
||||
sqrt.shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User);
|
||||
}
|
||||
@@ -1036,29 +1032,29 @@ Expression Power::removeSquareRootsFromDenominator(Context & context, Preference
|
||||
// Compute the numerator
|
||||
Integer pq1 = Integer::Multiplication(p1, q1);
|
||||
Integer pq2 = Integer::Multiplication(p2, q2);
|
||||
Power sqrt1 = Power(Rational(pq1), Rational(1, 2));
|
||||
Power sqrt2 = Power(Rational(pq2), Rational(1, 2));
|
||||
Power sqrt1 = Power::Builder(Rational(pq1), Rational(1, 2));
|
||||
Power sqrt2 = Power::Builder(Rational(pq2), Rational(1, 2));
|
||||
Integer factor1 = Integer::Multiplication(
|
||||
Integer::Multiplication(n1, d1),
|
||||
Integer::Multiplication(Integer::Power(d2, Integer(2)), q2));
|
||||
Multiplication m1 = Multiplication(Rational(factor1), sqrt1);
|
||||
Multiplication m1 = Multiplication::Builder(Rational(factor1), sqrt1);
|
||||
Integer factor2 = Integer::Multiplication(
|
||||
Integer::Multiplication(n2, d2),
|
||||
Integer::Multiplication(Integer::Power(d1, Integer(2)), q1));
|
||||
Multiplication m2 = Multiplication(Rational(factor2), sqrt2);
|
||||
Multiplication m2 = Multiplication::Builder(Rational(factor2), sqrt2);
|
||||
Expression numerator;
|
||||
if (denominator.isNegative()) {
|
||||
numerator = Subtraction(m2, m1);
|
||||
numerator = Subtraction::Builder(m2, m1);
|
||||
denominator.setNegative(false);
|
||||
} else {
|
||||
numerator = Subtraction(m1, m2);
|
||||
numerator = Subtraction::Builder(m1, m2);
|
||||
}
|
||||
if (denominator.isOverflow() || factor1.isOverflow() || factor2.isOverflow() || pq1.isOverflow() || pq2.isOverflow()) {
|
||||
return result; // Escape
|
||||
}
|
||||
numerator = numerator.deepReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User);
|
||||
Integer one(1);
|
||||
result = Multiplication(numerator, Rational(one, denominator));
|
||||
result = Multiplication::Builder(numerator, Rational(one, denominator));
|
||||
}
|
||||
|
||||
if (!result.isUninitialized()) {
|
||||
@@ -1127,13 +1123,13 @@ bool Power::isNthRootOfUnity() const {
|
||||
Expression Power::equivalentExpressionUsingStandardExpression() const {
|
||||
if (childAtIndex(1).type() == ExpressionNode::Type::Rational) {
|
||||
if (childAtIndex(1).convert<Rational>().isMinusOne()) {
|
||||
return Division(Rational(1), childAtIndex(0).clone());
|
||||
return Division::Builder(Rational(1), childAtIndex(0).clone());
|
||||
}
|
||||
if (childAtIndex(1).convert<Rational>().isHalf()) {
|
||||
return SquareRoot::Builder(childAtIndex(0).clone());
|
||||
}
|
||||
if (childAtIndex(1).convert<Rational>().isMinusHalf()) {
|
||||
return Division(Rational(1), SquareRoot::Builder(childAtIndex(0).clone()));
|
||||
return Division::Builder(Rational(1), SquareRoot::Builder(childAtIndex(0).clone()));
|
||||
}
|
||||
}
|
||||
return Expression();
|
||||
@@ -1144,7 +1140,7 @@ Expression Power::CreateComplexExponent(const Expression & r, Context & context,
|
||||
const Constant exp = Constant(Ion::Charset::Exponential);
|
||||
Constant iComplex = Constant(Ion::Charset::IComplex);
|
||||
const Constant pi = Constant(Ion::Charset::SmallPi);
|
||||
Multiplication mExp = Multiplication(iComplex, pi, r.clone());
|
||||
Multiplication mExp = Multiplication::Builder(iComplex, pi, r.clone());
|
||||
iComplex.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
Power p(exp, mExp);
|
||||
mExp.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
@@ -1152,11 +1148,11 @@ Expression Power::CreateComplexExponent(const Expression & r, Context & context,
|
||||
#if 0
|
||||
const Constant iComplex = Constant(Ion::Charset::IComplex);
|
||||
const Constant pi = Constant(Ion::Charset::SmallPi);
|
||||
Expression op = Multiplication(pi, r).shallowReduce(context, complexFormat, angleUnit, false);
|
||||
Expression op = Multiplication::Builder(pi, r).shallowReduce(context, complexFormat, angleUnit, false);
|
||||
Cosine cos = Cosine(op).shallowReduce(context, complexFormat, angleUnit, false);;
|
||||
Sine sin = Sine(op).shallowReduce(context, complexFormat, angleUnit, false);
|
||||
Expression m = Multiplication(iComplex, sin);
|
||||
Expression a = Addition(cos, m);
|
||||
Expression m = Multiplication::Builder(iComplex, sin);
|
||||
Expression a = Addition::Builder(cos, m);
|
||||
const Expression * multExpOperands[3] = {pi, r->clone()};
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -95,11 +95,11 @@ Expression PredictionInterval::shallowReduce(Context & context, Preferences::Com
|
||||
return *this;
|
||||
}
|
||||
// Compute sqr = sqrt(r0*(1-r0)/r1)
|
||||
Expression sqr = Power(Division(numerator, r1), Rational(1, 2));
|
||||
Expression m = Multiplication(Rational(196, 100), sqr);
|
||||
Matrix matrix;
|
||||
matrix.addChildAtIndexInPlace(Addition(r0.clone(), Multiplication(Rational(-1), m.clone())), 0, 0);
|
||||
matrix.addChildAtIndexInPlace(Addition(r0.clone(), m), 1, 1);
|
||||
Expression sqr = Power::Builder(Division::Builder(numerator, r1), Rational(1, 2));
|
||||
Expression m = Multiplication::Builder(Rational(196, 100), sqr);
|
||||
Matrix matrix = Matrix::Builder();
|
||||
matrix.addChildAtIndexInPlace(Addition::Builder(r0.clone(), Multiplication::Builder(Rational(-1), m.clone())), 0, 0);
|
||||
matrix.addChildAtIndexInPlace(Addition::Builder(r0.clone(), m), 1, 1);
|
||||
matrix.setDimensions(1, 2);
|
||||
replaceWithInPlace(matrix);
|
||||
matrix.deepReduceChildren(context, complexFormat, angleUnit, target);
|
||||
|
||||
@@ -19,7 +19,7 @@ Expression ProductNode::replaceUnknown(const Symbol & symbol) {
|
||||
}
|
||||
|
||||
Layout ProductNode::createSequenceLayout(Layout argumentLayout, Layout symbolLayout, Layout subscriptLayout, Layout superscriptLayout) const {
|
||||
return ProductLayout(argumentLayout, symbolLayout, subscriptLayout, superscriptLayout);
|
||||
return ProductLayout::Builder(argumentLayout, symbolLayout, subscriptLayout, superscriptLayout);
|
||||
}
|
||||
|
||||
int ProductNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
|
||||
@@ -111,7 +111,7 @@ Layout RationalNode::createLayout(Preferences::PrintFloatMode floatDisplayMode,
|
||||
return numeratorLayout;
|
||||
}
|
||||
HorizontalLayout denominatorLayout = denominator().createLayout();
|
||||
return FractionLayout(numeratorLayout, denominatorLayout);
|
||||
return FractionLayout::Builder(numeratorLayout, denominatorLayout);
|
||||
}
|
||||
|
||||
// Approximation
|
||||
@@ -266,7 +266,7 @@ Expression Rational::shallowReduce() {
|
||||
Expression Rational::shallowBeautify() {
|
||||
if (sign() == ExpressionNode::Sign::Negative) {
|
||||
Expression abs = setSign(ExpressionNode::Sign::Positive);
|
||||
Opposite o;
|
||||
Opposite o = Opposite::Builder();
|
||||
replaceWithInPlace(o);
|
||||
o.replaceChildAtIndexInPlace(0, abs);
|
||||
return o;
|
||||
|
||||
@@ -59,6 +59,4 @@ void RightParenthesisLayoutNode::render(KDContext * ctx, KDPoint p, KDColor expr
|
||||
RenderWithChildHeight(ParenthesisLayoutNode::ChildHeightGivenLayoutHeight(layoutSize().height()), ctx, p, expressionColor, backgroundColor);
|
||||
}
|
||||
|
||||
RightParenthesisLayout::RightParenthesisLayout() : Layout(TreePool::sharedPool()->createTreeNode<RightParenthesisLayoutNode>()) {}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,6 +8,4 @@ void RightSquareBracketLayoutNode::render(KDContext * ctx, KDPoint p, KDColor ex
|
||||
ctx->fillRect(KDRect(p.x()+k_widthMargin-k_bracketWidth+1, p.y() + childHeight(), k_bracketWidth, k_lineThickness), expressionColor);
|
||||
}
|
||||
|
||||
RightSquareBracketLayout::RightSquareBracketLayout() : Layout(TreePool::sharedPool()->createTreeNode<RightSquareBracketLayoutNode>()) {}
|
||||
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ Expression SignFunction::shallowReduce(Context & context, Preferences::ComplexFo
|
||||
return *this;
|
||||
}
|
||||
Expression sign = *this;
|
||||
Multiplication m(Rational(-1));
|
||||
Multiplication m = Multiplication::Builder(Rational(-1));
|
||||
replaceWithInPlace(m);
|
||||
m.addChildAtIndexInPlace(sign, 1, 1); // sign does not need to be shallowReduced because -x = NAN --> x = NAN
|
||||
return m; // m does not need to be shallowReduced, -1*sign cannot be reduced
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Poincare {
|
||||
Expression SimplificationHelper::Map(const Expression & e, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) {
|
||||
assert(e->numberOfChildren() == 1 && e->childAtIndex(0)->type() == ExpressionNode::Type::Matrix);
|
||||
Expression c = e.childAtIndex(0);
|
||||
Matrix matrix;
|
||||
Matrix matrix = Matrix::Builder();
|
||||
for (int i = 0; i < c->numberOfChildren(); i++) {
|
||||
Expression f = e.replaceChildAtIndexInPlace(0, e.childAtIndex(0).childAtIndex(i));
|
||||
matrix.addChildAtIndexInPlace(f, i, i);
|
||||
|
||||
@@ -19,7 +19,7 @@ constexpr Expression::FunctionHelper SquareRoot::s_functionHelper;
|
||||
int SquareRootNode::numberOfChildren() const { return SquareRoot::s_functionHelper.numberOfChildren(); }
|
||||
|
||||
Layout SquareRootNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return NthRootLayout(childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits));
|
||||
return NthRootLayout::Builder(childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits));
|
||||
}
|
||||
|
||||
int SquareRootNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
@@ -54,7 +54,7 @@ Expression SquareRoot::shallowReduce(Context & context, Preferences::ComplexForm
|
||||
return SimplificationHelper::Map(this, context, angleUnit);
|
||||
}
|
||||
#endif
|
||||
Power p = Power(childAtIndex(0), Rational(1, 2));
|
||||
Power p = Power::Builder(childAtIndex(0), Rational(1, 2));
|
||||
replaceWithInPlace(p);
|
||||
return p.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ int StoreNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatM
|
||||
}
|
||||
|
||||
Layout StoreNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
HorizontalLayout result = HorizontalLayout();
|
||||
HorizontalLayout result = HorizontalLayout::Builder();
|
||||
result.addOrMergeChildAtIndex(childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits), 0, false);
|
||||
result.addChildAtIndex(CharLayout(Ion::Charset::Sto), result.numberOfChildren(), result.numberOfChildren(), nullptr);
|
||||
result.addOrMergeChildAtIndex(childAtIndex(1)->createLayout(floatDisplayMode, numberOfSignificantDigits), result.numberOfChildren(), false);
|
||||
|
||||
@@ -56,15 +56,13 @@ Expression SubtractionNode::shallowReduce(Context & context, Preferences::Comple
|
||||
return Subtraction(this).shallowReduce(context, complexFormat, angleUnit, target);
|
||||
}
|
||||
|
||||
Subtraction::Subtraction() : Expression(TreePool::sharedPool()->createTreeNode<SubtractionNode>()) {}
|
||||
|
||||
Expression Subtraction::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) {
|
||||
Expression e = Expression::defaultShallowReduce();
|
||||
if (e.isUndefined()) {
|
||||
return e;
|
||||
}
|
||||
Expression m = Multiplication(Rational(-1), childAtIndex(1));
|
||||
Addition a(childAtIndex(0), m);
|
||||
Expression m = Multiplication::Builder(Rational(-1), childAtIndex(1));
|
||||
Addition a = Addition::Builder(childAtIndex(0), m);
|
||||
m = m.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
replaceWithInPlace(a);
|
||||
return a.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
|
||||
@@ -19,7 +19,7 @@ Expression SumNode::replaceUnknown(const Symbol & symbol) {
|
||||
}
|
||||
|
||||
Layout SumNode::createSequenceLayout(Layout argumentLayout, Layout symbolLayout, Layout subscriptLayout, Layout superscriptLayout) const {
|
||||
return SumLayout(argumentLayout, symbolLayout, subscriptLayout, superscriptLayout);
|
||||
return SumLayout::Builder(argumentLayout, symbolLayout, subscriptLayout, superscriptLayout);
|
||||
}
|
||||
|
||||
int SumNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
|
||||
@@ -80,30 +80,30 @@ Layout SymbolNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, in
|
||||
return CharLayout(Symbol::k_unknownXReadableChar);
|
||||
}
|
||||
if (strcmp(m_name, "u(n)") == 0) {
|
||||
return HorizontalLayout(
|
||||
return HorizontalLayout::Builder(
|
||||
CharLayout('u'),
|
||||
VerticalOffsetLayout(
|
||||
VerticalOffsetLayout::Builder(
|
||||
CharLayout('n'),
|
||||
VerticalOffsetLayoutNode::Type::Subscript));
|
||||
}
|
||||
if (strcmp(m_name, "u(n+1)") == 0) {
|
||||
return HorizontalLayout(
|
||||
return HorizontalLayout::Builder(
|
||||
CharLayout('u'),
|
||||
VerticalOffsetLayout(
|
||||
VerticalOffsetLayout::Builder(
|
||||
LayoutHelper::String("n+1", 3),
|
||||
VerticalOffsetLayoutNode::Type::Subscript));
|
||||
}
|
||||
if (strcmp(m_name, "v(n)") == 0) {
|
||||
return HorizontalLayout(
|
||||
return HorizontalLayout::Builder(
|
||||
CharLayout('v'),
|
||||
VerticalOffsetLayout(
|
||||
VerticalOffsetLayout::Builder(
|
||||
CharLayout('n'),
|
||||
VerticalOffsetLayoutNode::Type::Subscript));
|
||||
}
|
||||
if (strcmp(m_name, "v(n+1)") == 0) {
|
||||
return HorizontalLayout(
|
||||
return HorizontalLayout::Builder(
|
||||
CharLayout('v'),
|
||||
VerticalOffsetLayout(
|
||||
VerticalOffsetLayout::Builder(
|
||||
LayoutHelper::String("n+1", 3),
|
||||
VerticalOffsetLayoutNode::Type::Subscript));
|
||||
}
|
||||
@@ -173,7 +173,7 @@ Expression Symbol::replaceSymbolWithExpression(const SymbolAbstract & symbol, co
|
||||
Expression value = expression.clone();
|
||||
Expression p = parent();
|
||||
if (!p.isUninitialized() && p.node()->childNeedsParenthesis(value.node())) {
|
||||
value = Parenthesis(value);
|
||||
value = Parenthesis::Builder(value);
|
||||
}
|
||||
replaceWithInPlace(value);
|
||||
return value;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user