50 bool Multiplication::needParenthesisWithParent(
const Expression * e)
const {
52 return e->isOfType(types, 3);
55 ExpressionLayout * Multiplication::privateCreateLayout(
PrintFloat::Mode floatDisplayMode, ComplexFormat complexFormat)
const {
60 int Multiplication::writeTextInBuffer(
char * buffer,
int bufferSize,
int numberOfSignificantDigits)
const {
73 Expression * Multiplication::setSign(Sign s,
Context & context, AngleUnit angleUnit) {
80 return shallowReduce(context, angleUnit);
101 a += mEntry->
a()*nEntry->
a() - mEntry->
b()*nEntry->
b();
102 b += mEntry->
b()*nEntry->
a() + mEntry->
a()*nEntry->
b();
115 if (numberOfNonRationalFactors1 != numberOfNonRationalFactors2) {
120 for (
int i = 0; i < numberOfNonRationalFactors1; i++) {
128 static inline const Expression * Base(
const Expression * e) {
135 Expression * Multiplication::shallowReduce(Context& context, AngleUnit angleUnit) {
136 return privateShallowReduce(context, angleUnit,
true,
true);
139 Expression * Multiplication::privateShallowReduce(Context & context, AngleUnit angleUnit,
bool shouldExpand,
bool canBeInterrupted) {
140 Expression * e = Expression::shallowReduce(context, angleUnit);
146 mergeMultiplicationOperands();
159 #if MATRIX_EXACT_REDUCING 168 Matrix * resultMatrix =
static_cast<Matrix *
>(lastOperand);
170 n = resultMatrix->numberOfRows();
171 m = resultMatrix->numberOfColumns();
178 int on = currentMatrix->numberOfRows();
179 int om = currentMatrix->numberOfColumns();
204 for (
int e = 0; e < on*m; e++) {
205 newMatrixOperands[e] =
new Addition();
208 for (
int j = 0; j < n; j++) {
209 Expression * mult =
new Multiplication(currentMatrix->editableOperand(j+om*i1), resultMatrix->editableOperand(j*m+i2),
true);
211 mult->shallowReduce(context, angleUnit);
213 Reduce(&newMatrixOperands[e], context, angleUnit,
false);
217 resultMatrix =
static_cast<Matrix *
>(resultMatrix->replaceWith(
new Matrix(newMatrixOperands, n, m,
false),
true));
222 for (
int i = 0; i < n*m; i++) {
224 Expression * entryI = resultMatrix->editableOperand(i);
225 resultMatrix->replaceOperand(entryI, m,
false);
226 m->addOperand(entryI);
227 m->shallowReduce(context, angleUnit);
229 return replaceWith(resultMatrix,
true)->shallowReduce(context, angleUnit);
240 if (TermsHaveIdenticalBase(oi, oi1)) {
241 bool shouldFactorizeBase =
true;
242 if (TermHasRationalBase(oi)) {
249 if (shouldFactorizeBase) {
250 factorizeBase(oi, oi1, context, angleUnit);
253 }
else if (TermHasRationalBase(oi) && TermHasRationalBase(oi1) && TermsHaveIdenticalExponent(oi, oi1)) {
254 factorizeExponent(oi, oi1, context, angleUnit);
266 if (Base(o1)->
type() ==
Type::Sine && TermHasRationalExponent(o1)) {
273 factorizeSineAndCosine(o1, o2, context, angleUnit);
328 return distributeOnOperandAtIndex(i, context, angleUnit);
339 void Multiplication::mergeMultiplicationOperands() {
343 while (i < initialNumberOfOperands) {
353 void Multiplication::factorizeSineAndCosine(Expression * o1, Expression * o2, Context & context, AngleUnit angleUnit) {
354 assert(o1->parent() ==
this && o2->parent() ==
this);
362 if ((
int)p.sign()*(int)q.sign() > 0) {
373 o1->replaceOperand(o1->operand(0),
tan,
true);
378 o1->shallowReduce(context, angleUnit);
380 o2->replaceOperand(o2->operand(1),
new Rational(sumPQ),
true);
386 o2->shallowReduce(context, angleUnit);
390 o2->replaceOperand(o2->operand(0),
tan,
true);
396 o2->shallowReduce(context, angleUnit);
398 o1->replaceOperand(o1->operand(1),
new Rational(sumPQ),
true);
404 o1->shallowReduce(context, angleUnit);
408 void Multiplication::factorizeBase(Expression * e1, Expression * e2, Context & context, AngleUnit angleUnit) {
412 assert(TermsHaveIdenticalBase(e1, e2));
424 e1->replaceOperand(e1->operand(1), s,
true);
425 p =
static_cast<Power *
>(e1);
428 p =
new Power(e1, s,
false);
433 s->shallowReduce(context, angleUnit);
434 Expression * reducedP = p->shallowReduce(context, angleUnit);
439 mergeMultiplicationOperands();
443 void Multiplication::factorizeExponent(Expression * e1, Expression * e2, Context & context, AngleUnit angleUnit) {
446 assert(e1->parent() ==
this && e2->parent() ==
this);
448 const Expression * base1 = e1->operand(0)->clone();
450 e2->detachOperand(base2);
453 e1->replaceOperand(e1->operand(0), m,
true);
455 m->shallowReduce(context, angleUnit);
456 Expression * reducedE1 = e1->shallowReduce(context, angleUnit);
461 mergeMultiplicationOperands();
465 Expression * Multiplication::distributeOnOperandAtIndex(
int i, Context & context, AngleUnit angleUnit) {
470 for (
int j = 0; j < a->numberOfOperands(); j++) {
473 a->replaceOperand(termJ, m,
false);
474 m->addOperand(termJ);
475 m->shallowReduce(context, angleUnit);
478 return a->shallowReduce(context, angleUnit);
481 const Expression * Multiplication::CreateExponent(Expression * e) {
485 bool Multiplication::TermsHaveIdenticalBase(
const Expression * e1,
const Expression * e2) {
489 bool Multiplication::TermsHaveIdenticalExponent(
const Expression * e1,
const Expression * e2) {
492 return e1->type() ==
Type::Power && e2->type() ==
Type::Power && (e1->operand(1)->isIdenticalTo(e2->operand(1)));
495 bool Multiplication::TermHasRationalBase(
const Expression * e) {
499 bool Multiplication::TermHasRationalExponent(
const Expression * e) {
509 Expression * Multiplication::shallowBeautify(Context & context, AngleUnit angleUnit) {
518 if (static_cast<const Rational *>(
operand(0))->isMinusOne()) {
525 e->replaceWith(o,
true);
526 o->editableOperand(0)->shallowBeautify(context, angleUnit);
532 Expression * e = mergeNegativePower(context, angleUnit);
534 return e->shallowBeautify(context, angleUnit);
555 Expression * denominatorOperand = p->editableOperand(0);
556 p->detachOperand(denominatorOperand);
559 Expression * numeratorOperand = shallowReduce(context, angleUnit);
562 numeratorOperand = numeratorOperand->replaceWith(numeratorOperand->editableOperand(0),
true);
564 Expression * originalParent = numeratorOperand->parent();
566 originalParent->replaceOperand(numeratorOperand, d,
false);
567 return d->shallowBeautify(context, angleUnit);
573 Expression * Multiplication::cloneDenominator(Context & context, AngleUnit angleUnit)
const {
580 result =
static_cast<Power *
>(e)->cloneDenominator(context, angleUnit);
583 for (
int i = 0; i < e->numberOfOperands(); i++) {
585 if (e->operand(i)->type() ==
Type::Power && e->operand(i)->operand(1)->type() ==
Type::Rational &&
static_cast<const Rational *
>(e->operand(i)->operand(1))->isMinusOne()) {
586 Power * p =
static_cast<Power *
>(e->editableOperand(i));
587 result = p->editableOperand(0);
588 p->detachOperand((result));
592 root.detachOperand(e);
597 Expression * Multiplication::mergeNegativePower(Context & context, AngleUnit angleUnit) {
602 m->addOperand(
new Rational(r->denominator()));
603 if (r->numerator().isOne()) {
613 e->editableOperand(1)->setSign(
Sign::Positive, context, angleUnit);
616 e->shallowReduce(context, angleUnit);
621 if (m->numberOfOperands() == 0) {
627 m->squashUnaryHierarchy();
633 void Multiplication::addMissingFactors(Expression * factor, Context & context, AngleUnit angleUnit) {
635 for (
int j = 0; j < factor->numberOfOperands(); j++) {
636 addMissingFactors(factor->editableOperand(j), context, angleUnit);
646 assert(f->denominator().isOne());
647 assert(o->denominator().isOne());
648 Integer i = f->numerator();
649 Integer j = o->numerator();
656 if (TermsHaveIdenticalBase(
operand(i), factor)) {
658 Reduce((
Expression **)&sub, context, angleUnit);
661 factor->replaceOperand(factor->editableOperand(1),
new Opposite(sub,
true),
true);
665 factor->editableOperand(1)->shallowReduce(context, angleUnit);
676 mergeMultiplicationOperands();
685 template Matrix * Multiplication::computeOnComplexAndMatrix<float>(Complex<float>
const*,
const Matrix*);
686 template Matrix * Multiplication::computeOnComplexAndMatrix<double>(Complex<double>
const*,
const Matrix*);
687 template Complex<float> Multiplication::compute<float>(Complex<float>, Complex<float>);
688 template Complex<double> Multiplication::compute<double>(Complex<double>, Complex<double>);
int numberOfColumns() const
static int writeInfixExpressionTextInBuffer(const Expression *expression, char *buffer, int bufferSize, int numberOfDigits, const char *operatorName)
void removeOperand(const Expression *e, bool deleteAfterRemoval=true)
void addOperand(Expression *operand)
Expression * parent() const
static Integer LCM(const Integer *i, const Integer *j)
static Complex< T > Cartesian(T a, T b)
friend class Multiplication
Expression * replaceWith(Expression *newOperand, bool deleteAfterReplace=true)
static Matrix * computeOnMatrices(const Matrix *m, const Matrix *n)
friend class SimplificationRoot
static Rational Addition(const Rational &i, const Rational &j)
Expression * squashUnaryHierarchy()
Expression * clone() const override
Expression * editableOperand(int i)
void addOperandAtIndex(Expression *operand, int index)
static int SimplificationOrder(const Expression *e1, const Expression *e2, bool canBeInterrupted=false)
virtual int numberOfOperands() const =0
bool isIdenticalTo(const Expression *e) const
static int NaturalOrder(const Rational &i, const Rational &j)
friend class Multiplication
const Expression *const * operands() const override
void mergeOperands(DynamicHierarchy *d)
static ExpressionLayout * createInfixLayout(const Expression *expression, PrintFloat::Mode floatDisplayMode, Expression::ComplexFormat complexFormat, const char *operatorName)
Type type() const override
static Complex< T > compute(const Complex< T > c, const Complex< T > d)
virtual Sign sign() const
void sortOperands(ExpressionOrder order, bool canBeInterrupted)
int polynomialDegree(char symbolName) const override
Sign sign() const override
int numberOfOperands() const override
const Expression * operand(int i) const
virtual int polynomialDegree(char symbolName) const
virtual Type type() const =0
void replaceOperand(const Expression *oldOperand, Expression *newOperand, bool deleteOldOperand=true)