96 if (
c.a() == 0 &&
c.b() == 0) {
114 if (inverse ==
nullptr) {
118 Matrix * result = Power::computeOnMatrixAndComplex(inverse, &minusC);
124 for (
int k = 0; k < (int)power; k++) {
129 Matrix * mult = Multiplication::computeOnMatrices<T>(result, m);
136 bool Power::needParenthesisWithParent(
const Expression * e)
const {
138 return e->isOfType(types, 2);
141 ExpressionLayout * Power::privateCreateLayout(
PrintFloat::Mode floatDisplayMode, ComplexFormat complexFormat)
const {
152 int Power::simplificationOrderSameType(
const Expression * e,
bool canBeInterrupted)
const {
154 if (baseComparison != 0) {
155 return baseComparison;
160 int Power::simplificationOrderGreaterType(
const Expression * e,
bool canBeInterrupted)
const {
162 if (baseComparison != 0) {
163 return baseComparison;
169 Expression * Power::shallowReduce(Context& context, AngleUnit angleUnit) {
170 Expression * e = Expression::shallowReduce(context, angleUnit);
174 #if MATRIX_EXACT_REDUCING 184 Integer exponent =
static_cast<const Rational *
>(
operand(1))->numerator();
185 if (mat->numberOfRows() != mat->numberOfColumns()) {
188 if (exponent.isNegative()) {
190 Expression * newMatrix = shallowReduce(context, angleUnit);
199 int exp = exponent.extractedInt();
206 for (
int k = 1; k <
exp; k++) {
207 result->addOperand(mat->clone());
210 return result->shallowReduce(context, angleUnit);
218 bool bothOperandsComplexes = op0->b() != 0 && op1->b() != 0;
221 if (bothOperandsComplexes) {
266 Expression * r = removeSquareRootsFromDenominator(context, angleUnit);
276 return replaceWith(CreateNthRootOfUnity(r))->shallowReduce(context, angleUnit);
279 bool letPowerAtRoot = parentIsALogarithmOfSameBase();
287 if (RationalExponentShouldNotBeReduced(
exp)) {
290 return simplifyRationalRationalPower(
this, a,
exp, context, angleUnit);
294 if (!letPowerAtRoot && isNthRootOfUnity()) {
297 Expression * i = m->editableOperand(m->numberOfOperands()-1);
300 const Expression * pi = m->operand(m->numberOfOperands()-1);
301 m->replaceOperand(pi,
new Rational(180),
true);
304 m = m->shallowReduce(context, angleUnit);
307 sin->shallowReduce(context, angleUnit);
309 cos->shallowReduce(context, angleUnit);
310 complexPart->shallowReduce(context, angleUnit);
311 return replaceWith(a,
true)->shallowReduce(context, angleUnit);
340 return simplifyPowerMultiplication(m,
editableOperand(1), context, angleUnit);
343 for (
int i = 0; i < m->numberOfOperands(); i++) {
351 m->replaceOperand(factor,
new Rational(-1),
false);
354 m->removeOperand(factor,
false);
356 m->shallowReduce(context, angleUnit);
359 p->shallowReduce(context, angleUnit);
360 root->editableOperand(1)->shallowReduce(context, angleUnit);
362 return root->shallowReduce(context, angleUnit);
373 if (RationalExponentShouldNotBeReduced(static_cast<const Rational *>(a->operand(0)))) {
380 simplifyRationalRationalPower(p1, static_cast<Rational *>(p1->editableOperand(0)), static_cast<Rational *>(p1->editableOperand(1)->editableOperand(0)), context, angleUnit);
382 return m->shallowReduce(context, angleUnit);
390 Integer n = nr->numerator();
391 n.setNegative(
false);
394 if (Integer(k_maxNumberOfTermsInExpandedMultinome).isLowerThan(n) || n.isOne()) {
397 int clippedN = n.extractedInt();
403 if (k_maxNumberOfTermsInExpandedMultinome <
BinomialCoefficient::compute(static_cast<double>(clippedN), static_cast<double>(clippedN+m-1))) {
408 for (
int i = 2; i <= clippedN; i++) {
411 for (
int j = 0; j < a->numberOfOperands(); j++) {
414 Expression * expandM = m->distributeOnOperandAtIndex(0, context, angleUnit);
415 rootM.detachOperands();
417 static_cast<Addition *
>(a0)->addOperand(expandM);
419 a0 =
new Addition(a0, expandM,
false);
422 a0 = a0->shallowReduce(context, angleUnit);
423 rootA0.detachOperands();
425 result = result->replaceWith(a0,
true);
429 result = result->replaceWith(m->distributeOnOperandAtIndex(0, context, angleUnit),
true);
430 result = result->shallowReduce(context, angleUnit);
431 root.detachOperands();
436 nr->replaceWith(
new Rational(-1),
true);
437 return shallowReduce(context, angleUnit);
448 Integer n = nr->numerator();
449 n.setNegative(
false);
450 if (Integer(k_maxExpandedBinome).isLowerThan(n) || n.isOne()) {
453 int clippedN = n.extractedInt();
457 for (
int i = 0; i <= clippedN; i++) {
463 p0->shallowReduce(context, angleUnit);
464 p1->shallowReduce(context, angleUnit);
466 m->shallowReduce(context, angleUnit);
469 nr->replaceWith(
new Rational(-1),
true);
471 return shallowReduce(context, angleUnit);
473 return replaceWith(a,
true)->shallowReduce(context, angleUnit);
480 bool Power::parentIsALogarithmOfSameBase()
const {
501 Expression * Power::simplifyPowerPower(
Power * p, Expression * e, Context& context, AngleUnit angleUnit) {
508 m->shallowReduce(context, angleUnit);
509 return shallowReduce(context, angleUnit);
512 Expression * Power::simplifyPowerMultiplication(
Multiplication * m, Expression * r, Context& context, AngleUnit angleUnit) {
513 for (
int index = 0; index < m->numberOfOperands(); index++) {
514 Expression * factor = m->editableOperand(index);
516 m->replaceOperand(factor, p,
true);
517 p->shallowReduce(context, angleUnit);
520 return replaceWith(m,
true)->shallowReduce(context, angleUnit);
523 Expression * Power::simplifyRationalRationalPower(Expression * result, Rational * a, Rational * b, Context& context, AngleUnit angleUnit) {
524 if (b->denominator().isOne()) {
526 return result->replaceWith(
new Rational(r),
true);
532 n = CreateSimplifiedIntegerRationalPower(a->denominator(), b,
false, context, angleUnit);
533 d = CreateSimplifiedIntegerRationalPower(a->numerator(), b,
true, context, angleUnit);
535 n = CreateSimplifiedIntegerRationalPower(a->numerator(), b,
false, context, angleUnit);
536 d = CreateSimplifiedIntegerRationalPower(a->denominator(), b,
true, context, angleUnit);
539 result->replaceWith(m,
true);
540 return m->shallowReduce(context, angleUnit);
543 Expression * Power::CreateSimplifiedIntegerRationalPower(Integer i, Rational * r,
bool isDenominator, Context & context, AngleUnit angleUnit) {
550 absI.setNegative(
false);
555 if (coefficients[0].isMinusOne()) {
573 Integer
one = isDenominator ? Integer(-1) : Integer(1);
576 if (r1.isEqualTo(Integer(1)) && !i.isNegative()) {
584 if (i.isNegative()) {
585 Expression * nthRootOfUnity = CreateNthRootOfUnity(*r);
586 m->addOperand(nthRootOfUnity);
587 nthRootOfUnity->shallowReduce(context, angleUnit);
594 Expression * Power::CreateNthRootOfUnity(
const Rational r) {
607 op = op->shallowReduce(context, angleUnit);
610 sin->shallowReduce(context, angleUnit);
612 cos->shallowReduce(context, angleUnit);
613 const Expression * multExpOperands[3] = {pi, r->clone()};
617 Expression * Power::shallowBeautify(Context& context, AngleUnit angleUnit) {
620 Expression * p = cloneDenominator(context, angleUnit);
622 p->shallowReduce(context, angleUnit);
624 return d->shallowBeautify(context, angleUnit);
627 Integer index =
static_cast<const Rational *
>(
operand(1))->denominator();
628 if (index.isEqualTo(Integer(2))) {
646 Expression * Power::cloneDenominator(Context & context, AngleUnit angleUnit)
const {
659 bool Power::TermIsARationalSquareRootOrRational(
const Expression * e) {
672 const Rational * Power::RadicandInExpression(
const Expression * e) {
678 return static_cast<const Rational *
>(e->operand(0));
683 return static_cast<const Rational *
>(e->operand(1)->operand(0));
687 const Rational * Power::RationalFactorInExpression(
const Expression * e) {
689 return static_cast<const Rational *
>(e);
695 return static_cast<const Rational *
>(e->operand(0));
699 Expression * Power::removeSquareRootsFromDenominator(Context & context, AngleUnit angleUnit) {
710 if (!q.isOne() ||
static_cast<const Rational *
>(
operand(1))->isMinusHalf()) {
712 if (static_cast<const Rational *>(
operand(1))->isHalf()) {
717 sqrt->shallowReduce(context, angleUnit);
734 Integer n1 = (f1 ? f1->numerator() : Integer(1));
735 Integer d1 = (f1 ? f1->denominator() : Integer(1));
736 Integer p1 = (r1 ? r1->numerator() : Integer(1));
737 Integer q1 = (r1 ? r1->denominator() : Integer(1));
738 Integer n2 = (f2 ? f2->numerator() : Integer(1));
739 Integer d2 = (f2 ? f2->denominator() : Integer(1));
740 Integer p2 = (r2 ? r2->numerator() : Integer(1));
741 Integer q2 = (r2 ? r2->denominator() : Integer(1));
768 if (denominator.isNegative()) {
770 denominator.setNegative(
false);
776 numerator->deepReduce(context, angleUnit);
781 result = result->shallowReduce(context, angleUnit);
786 bool Power::isNthRootOfUnity()
const {
813 bool Power::RationalExponentShouldNotBeReduced(
const Rational * r) {
814 Integer maxIntegerExponent = r->numerator();
815 maxIntegerExponent.setNegative(
false);
822 template Complex<float> Power::compute<float>(Complex<float>, Complex<float>);
823 template Complex<double> Power::compute<double>(Complex<double>, Complex<double>);
int numberOfColumns() const
static bool shouldStopProcessing()
Expression * parent() const
static Integer Power(const Integer &i, const Integer &j)
Matrix * createInverse() const
friend class Multiplication
Expression * replaceWith(Expression *newOperand, bool deleteAfterReplace=true)
Expression * approximate(Context &context, AngleUnit angleUnit=AngleUnit::Default) const
static Matrix * createIdentity(int dim)
friend class SimplificationRoot
static Complex< T > Polar(T r, T theta)
const Expression *const * operands() const override
Sign sign() const override
friend class Multiplication
static Complex< T > compute(const Complex< T > c, AngleUnit angleUnit)
virtual Expression * clone() const =0
const Integer denominator() const
Sign sign() const override
int polynomialDegree(char symbolName) const override
Expression * editableOperand(int i)
static int SimplificationOrder(const Expression *e1, const Expression *e2, bool canBeInterrupted=false)
friend class Complex< float >
virtual int numberOfOperands() const =0
bool isIdenticalTo(const Expression *e) const
static constexpr int k_maxExtractableInteger
static void PrimeFactorization(const Integer *i, Integer *outputFactors, Integer *outputCoefficients, int outputLength)
const Expression * m_operands[T]
Expression * clone() const override
const Integer numerator() const
static constexpr int k_maxNumberOfPrimeFactors
ExpressionLayout * createLayout(PrintFloat::Mode floatDisplayMode=PrintFloat::Mode::Default, ComplexFormat complexFormat=ComplexFormat::Default) const
static int NaturalOrder(const Integer &i, const Integer &j)
static Complex< T > Float(T x)
static Integer Subtraction(const Integer &i, const Integer &j)
int numberOfOperands() const override
virtual Sign sign() const
static Complex< T > compute(const Complex< T > c, const Complex< T > d)
constexpr Event Multiplication
void detachOperand(const Expression *e)
friend class MatrixInverse
static Integer Multiplication(const Integer &i, const Integer &j)
const Expression * operand(int i) const
static IntegerDivision Division(const Integer &numerator, const Integer &denominator)
Type type() const override
virtual Type type() const =0
void replaceOperand(const Expression *oldOperand, Expression *newOperand, bool deleteOldOperand=true)
static T compute(T k, T n)