mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
94 lines
3.5 KiB
C++
94 lines
3.5 KiB
C++
#include <poincare/factor.h>
|
|
#include <poincare/undefined.h>
|
|
#include <poincare/arithmetic.h>
|
|
#include <poincare/power.h>
|
|
#include <poincare/division.h>
|
|
#include <poincare/opposite.h>
|
|
#include <poincare/layout_helper.h>
|
|
#include <poincare/serialization_helper.h>
|
|
extern "C" {
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
}
|
|
#include <cmath>
|
|
|
|
namespace Poincare {
|
|
|
|
constexpr Expression::FunctionHelper Factor::s_functionHelper;
|
|
|
|
int FactorNode::numberOfChildren() const { return Factor::s_functionHelper.numberOfChildren(); }
|
|
|
|
Layout FactorNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
|
return LayoutHelper::Prefix(Factor(this), floatDisplayMode, numberOfSignificantDigits, Factor::s_functionHelper.name());
|
|
}
|
|
|
|
int FactorNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
|
return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Factor::s_functionHelper.name());
|
|
}
|
|
|
|
Expression FactorNode::shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) {
|
|
return Factor(this).shallowBeautify(context, complexFormat, angleUnit);
|
|
}
|
|
|
|
Expression Factor::shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) {
|
|
Expression c = childAtIndex(0);
|
|
if (c.type() != ExpressionNode::Type::Rational) {
|
|
Expression result = Undefined();
|
|
replaceWithInPlace(result);
|
|
return result;
|
|
}
|
|
Rational r = static_cast<Rational &>(c);
|
|
if (r.isZero()) {
|
|
replaceWithInPlace(r);
|
|
return r;
|
|
}
|
|
Multiplication numeratorDecomp = createMultiplicationOfIntegerPrimeDecomposition(r.unsignedIntegerNumerator(), context, complexFormat, angleUnit);
|
|
if (numeratorDecomp.numberOfChildren() == 0) {
|
|
Expression result = Undefined();
|
|
replaceWithInPlace(result);
|
|
return result;
|
|
}
|
|
Expression result = numeratorDecomp.squashUnaryHierarchyInPlace();
|
|
if (!r.integerDenominator().isOne()) {
|
|
Multiplication denominatorDecomp = createMultiplicationOfIntegerPrimeDecomposition(r.integerDenominator(), context, complexFormat, angleUnit);
|
|
if (denominatorDecomp.numberOfChildren() == 0) {
|
|
Expression result = Undefined();
|
|
replaceWithInPlace(result);
|
|
return result;
|
|
}
|
|
result = Division(result, denominatorDecomp.squashUnaryHierarchyInPlace());
|
|
}
|
|
if (r.sign() == ExpressionNode::Sign::Negative) {
|
|
result = Opposite(result);
|
|
}
|
|
replaceWithInPlace(result);
|
|
return result;
|
|
}
|
|
|
|
Multiplication Factor::createMultiplicationOfIntegerPrimeDecomposition(Integer i, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const {
|
|
assert(!i.isZero());
|
|
assert(!i.isNegative());
|
|
Multiplication m;
|
|
Integer factors[Arithmetic::k_maxNumberOfPrimeFactors];
|
|
Integer coefficients[Arithmetic::k_maxNumberOfPrimeFactors];
|
|
int numberOfPrimeFactors = Arithmetic::PrimeFactorization(i, factors, coefficients, Arithmetic::k_maxNumberOfPrimeFactors);
|
|
if (numberOfPrimeFactors == 0) {
|
|
m.addChildAtIndexInPlace(Rational(i), 0, 0);
|
|
return m;
|
|
}
|
|
if (numberOfPrimeFactors < 0) {
|
|
// Exception: the decomposition failed
|
|
return m;
|
|
}
|
|
for (int index = 0; index < numberOfPrimeFactors; index++) {
|
|
Expression factor = Rational(factors[index]);
|
|
if (!coefficients[index].isOne()) {
|
|
factor = Power(factor, Rational(coefficients[index]));
|
|
}
|
|
m.addChildAtIndexInPlace(factor, m.numberOfChildren(), m.numberOfChildren());
|
|
}
|
|
return m;
|
|
}
|
|
|
|
}
|