mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[poincare] Add test: do not expand multinome when reduction target is
System
This commit is contained in:
committed by
LeaNumworks
parent
11b8ed72a1
commit
ccf848a9eb
@@ -18,14 +18,14 @@ void Model::tidy() {
|
||||
Poincare::Expression Model::simplifiedExpression(double * modelCoefficients, Poincare::Context * context) {
|
||||
Expression e = expression(modelCoefficients);
|
||||
if (!e.isUninitialized()) {
|
||||
PoincareHelpers::Simplify(&e, context);
|
||||
PoincareHelpers::Simplify(&e, context, ExpressionNode::ReductionTarget::SystemForApproximation);
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
double Model::levelSet(double * modelCoefficients, double xMin, double step, double xMax, double y, Poincare::Context * context) {
|
||||
Expression yExpression = Number::DecimalNumber(y);
|
||||
PoincareHelpers::Simplify(&yExpression, context);
|
||||
PoincareHelpers::Simplify(&yExpression, context, ExpressionNode::ReductionTarget::SystemForApproximation);
|
||||
Expression modelExpression = simplifiedExpression(modelCoefficients, context);
|
||||
double result = PoincareHelpers::NextIntersection(modelExpression, "x", xMin, step, xMax, context, yExpression).x1();
|
||||
return result;
|
||||
|
||||
@@ -47,7 +47,7 @@ Expression ExpressionModel::expressionReduced(const Storage::Record * record, Po
|
||||
m_expression = Undefined::Builder();
|
||||
} else {
|
||||
m_expression = Expression::ExpressionFromAddress(expressionAddress(record), expressionSize(record));
|
||||
PoincareHelpers::Simplify(&m_expression, context);
|
||||
PoincareHelpers::Simplify(&m_expression, context, ExpressionNode::ReductionTarget::SystemForApproximation);
|
||||
// simplify might return an uninitialized Expression if interrupted
|
||||
if (m_expression.isUninitialized()) {
|
||||
m_expression = Expression::ExpressionFromAddress(expressionAddress(record), expressionSize(record));
|
||||
|
||||
@@ -62,10 +62,10 @@ inline Poincare::Expression ParseAndSimplify(const char * text, Poincare::Contex
|
||||
return Poincare::Expression::ParseAndSimplify(text, context, complexFormat, preferences->angleUnit(), symbolicComputation);
|
||||
}
|
||||
|
||||
inline void Simplify(Poincare::Expression * e, Poincare::Context * context, bool symbolicComputation = true) {
|
||||
inline void Simplify(Poincare::Expression * e, Poincare::Context * context, Poincare::ExpressionNode::ReductionTarget target, bool symbolicComputation = true) {
|
||||
Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences();
|
||||
Poincare::Preferences::ComplexFormat complexFormat = Poincare::Expression::UpdatedComplexFormatWithExpressionInput(preferences->complexFormat(), *e, context);
|
||||
*e = e->simplify(context, complexFormat, preferences->angleUnit(), symbolicComputation);
|
||||
*e = e->simplify(context, complexFormat, preferences->angleUnit(), target, symbolicComputation);
|
||||
}
|
||||
|
||||
inline void ParseAndSimplifyAndApproximate(const char * text, Poincare::Expression * simplifiedExpression, Poincare::Expression * approximateExpression, Poincare::Context * context, bool symbolicComputation = true) {
|
||||
|
||||
@@ -276,7 +276,7 @@ EquationStore::Error EquationStore::oneDimensialPolynomialSolve(Expression exact
|
||||
assert(degree == 2);
|
||||
// Compute delta = b*b-4ac
|
||||
Expression delta = Subtraction::Builder(Power::Builder(coefficients[1].clone(), Rational::Builder(2)), Multiplication::Builder(Rational::Builder(4), coefficients[0].clone(), coefficients[2].clone()));
|
||||
delta = delta.simplify(context, updatedComplexFormat(context), Poincare::Preferences::sharedPreferences()->angleUnit());
|
||||
delta = delta.simplify(context, updatedComplexFormat(context), Poincare::Preferences::sharedPreferences()->angleUnit(), ExpressionNode::ReductionTarget::SystemForApproximation);
|
||||
if (delta.isUninitialized()) {
|
||||
delta = Poincare::Undefined::Builder();
|
||||
}
|
||||
|
||||
@@ -221,11 +221,11 @@ public:
|
||||
* (For instance, in Polar mode, they return an expression of the form
|
||||
* r*e^(i*th) reduced and approximated.) */
|
||||
static Expression ParseAndSimplify(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation = true);
|
||||
Expression simplify(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation = true);
|
||||
Expression simplify(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation = true);
|
||||
|
||||
static void ParseAndSimplifyAndApproximate(const char * text, Expression * simplifiedExpression, Expression * approximateExpression, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation = true);
|
||||
void simplifyAndApproximate(Expression * simplifiedExpression, Expression * approximateExpression, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation = true);
|
||||
Expression reduce(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit);
|
||||
Expression reduce(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target = ExpressionNode::ReductionTarget::SystemForApproximation);
|
||||
|
||||
Expression mapOnMatrixFirstChild(ExpressionNode::ReductionContext reductionContext);
|
||||
static Expression ExpressionWithoutSymbols(Expression expressionWithSymbols, Context * context);
|
||||
|
||||
@@ -110,7 +110,15 @@ public:
|
||||
|
||||
/* Properties */
|
||||
enum class ReductionTarget {
|
||||
System = 0,
|
||||
/* Minimal reduction: this at least reduces rationals operations as
|
||||
* "1-0.3-0.7 --> 0" */
|
||||
SystemForApproximation = 0,
|
||||
/* Expansion of Newton multinome to be able to identify polynoms */
|
||||
SystemForAnalysis,
|
||||
/* Additional features as:
|
||||
* - factorizing on a common denominator
|
||||
* - turning complex expression into the form a+ib
|
||||
* - identifying tangent in cos/sin polynoms ... */
|
||||
User
|
||||
};
|
||||
enum class Sign {
|
||||
|
||||
@@ -46,7 +46,11 @@ Evaluation<T> EqualNode::templatedApproximate(Context * context, Preferences::Co
|
||||
|
||||
Expression Equal::standardEquation(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const {
|
||||
Expression sub = Subtraction::Builder(childAtIndex(0).clone(), childAtIndex(1).clone());
|
||||
return sub.reduce(context, complexFormat, angleUnit);
|
||||
/* When reducing the equation, we specify the reduction target to be
|
||||
* SystemForAnalysis. This enables to expand Newton multinom to be able to
|
||||
* detect polynom correctly ("(x=2)^2" in this form won't be detected
|
||||
* unless expanded). */
|
||||
return sub.reduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::SystemForAnalysis);
|
||||
}
|
||||
|
||||
Expression Equal::shallowReduce() {
|
||||
|
||||
@@ -519,7 +519,7 @@ Expression Expression::ParseAndSimplify(const char * text, Context * context, Pr
|
||||
if (exp.isUninitialized()) {
|
||||
return Undefined::Builder();
|
||||
}
|
||||
exp = exp.simplify(context, complexFormat, angleUnit, symbolicSimplification);
|
||||
exp = exp.simplify(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User, symbolicSimplification);
|
||||
/* simplify might have been interrupted, in which case the resulting
|
||||
* expression is uninitialized, so we need to check that. */
|
||||
if (exp.isUninitialized()) {
|
||||
@@ -547,9 +547,9 @@ void Expression::ParseAndSimplifyAndApproximate(const char * text, Expression *
|
||||
}
|
||||
}
|
||||
|
||||
Expression Expression::simplify(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation) {
|
||||
Expression Expression::simplify(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) {
|
||||
sSimplificationHasBeenInterrupted = false;
|
||||
ExpressionNode::ReductionContext c = ExpressionNode::ReductionContext(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::System, symbolicComputation);
|
||||
ExpressionNode::ReductionContext c = ExpressionNode::ReductionContext(context, complexFormat, angleUnit, target, symbolicComputation);
|
||||
Expression e = deepReduce(c);
|
||||
if (!sSimplificationHasBeenInterrupted) {
|
||||
e = e.deepBeautify(c);
|
||||
@@ -618,7 +618,7 @@ void Expression::simplifyAndApproximate(Expression * simplifiedExpression, Expre
|
||||
Expression e = clone().deepReduce(userReductionContext);
|
||||
if (sSimplificationHasBeenInterrupted) {
|
||||
sSimplificationHasBeenInterrupted = false;
|
||||
ExpressionNode::ReductionContext systemReductionContext = ExpressionNode::ReductionContext(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::System, symbolicComputation);
|
||||
ExpressionNode::ReductionContext systemReductionContext = ExpressionNode::ReductionContext(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::SystemForApproximation, symbolicComputation);
|
||||
e = deepReduce(systemReductionContext);
|
||||
}
|
||||
*simplifiedExpression = Expression();
|
||||
@@ -730,9 +730,9 @@ Expression Expression::angleUnitToRadian(Preferences::AngleUnit angleUnit) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
Expression Expression::reduce(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) {
|
||||
Expression Expression::reduce(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) {
|
||||
sSimplificationHasBeenInterrupted = false;
|
||||
return deepReduce(ExpressionNode::ReductionContext(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::System, true));
|
||||
return deepReduce(ExpressionNode::ReductionContext(context, complexFormat, angleUnit, target, true));
|
||||
}
|
||||
|
||||
Expression Expression::deepReduce(ExpressionNode::ReductionContext reductionContext) {
|
||||
|
||||
@@ -115,7 +115,7 @@ void Matrix::addChildrenAsRowInPlace(TreeHandle t, int i) {
|
||||
|
||||
int Matrix::rank(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool inPlace) {
|
||||
Matrix m = inPlace ? *this : clone().convert<Matrix>();
|
||||
ExpressionNode::ReductionContext systemReductionContext = ExpressionNode::ReductionContext(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::System);
|
||||
ExpressionNode::ReductionContext systemReductionContext = ExpressionNode::ReductionContext(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::SystemForApproximation);
|
||||
m = m.rowCanonize(systemReductionContext, nullptr);
|
||||
int rank = m.numberOfRows();
|
||||
int i = rank-1;
|
||||
|
||||
@@ -744,11 +744,11 @@ Expression Power::shallowReduce(ExpressionNode::ReductionContext reductionContex
|
||||
|
||||
/* Step 13: (a0+a1+...am)^n with n integer
|
||||
* -> a^n+?a^(n-1)*b+?a^(n-2)*b^2+...+b^n (Multinome)
|
||||
* We apply this rule only when the target is the User. Indeed, developing
|
||||
* the multinome is likely to increase the numbers of operations and to
|
||||
* lead to precision loss. */
|
||||
* We don't apply this rule when the target is the SystemForApproximation.
|
||||
* Indeed, developing the multinome is likely to increase the numbers of
|
||||
* operations and lead to precision loss. */
|
||||
if (!letPowerAtRoot
|
||||
&& reductionContext.target() == ExpressionNode::ReductionTarget::User
|
||||
&& reductionContext.target() != ExpressionNode::ReductionTarget::SystemForApproximation
|
||||
&& indexType == ExpressionNode::Type::Rational
|
||||
&& !static_cast<Rational &>(index).signedIntegerNumerator().isZero()
|
||||
&& static_cast<Rational &>(index).isInteger()
|
||||
@@ -871,12 +871,12 @@ Expression Power::shallowBeautify(ExpressionNode::ReductionContext reductionCont
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Optional Step 3: if the ReductionTarget is the System, turn a^(p/q) into
|
||||
* (root(a, q))^p
|
||||
/* Optional Step 3: if the ReductionTarget is the SystemForApproximation,
|
||||
* turn a^(p/q) into (root(a, q))^p
|
||||
* Indeed, root(a, q) can have a real root which is not the principale angle
|
||||
* but that we want to return in real complex format. This special case is
|
||||
* handled in NthRoot approximation but not in Power approximation. */
|
||||
if (reductionContext.target() == ExpressionNode::ReductionTarget::System && childAtIndex(1).type() == ExpressionNode::Type::Rational) {
|
||||
if (reductionContext.target() != ExpressionNode::ReductionTarget::User && childAtIndex(1).type() == ExpressionNode::Type::Rational) {
|
||||
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::Builder(q));
|
||||
|
||||
@@ -311,7 +311,7 @@ QUIZ_CASE(poincare_preperties_get_variables) {
|
||||
void assert_reduced_expression_has_polynomial_coefficient(const char * expression, const char * symbolName, const char ** coefficients, Preferences::ComplexFormat complexFormat = Cartesian, Preferences::AngleUnit angleUnit = Radian) {
|
||||
Shared::GlobalContext globalContext;
|
||||
Expression e = parse_expression(expression, false);
|
||||
e = e.reduce(&globalContext, complexFormat, angleUnit);
|
||||
e = e.reduce(&globalContext, complexFormat, angleUnit, SystemForAnalysis);
|
||||
Expression coefficientBuffer[Poincare::Expression::k_maxNumberOfPolynomialCoefficients];
|
||||
int d = e.getPolynomialReducedCoefficients(symbolName, coefficientBuffer, &globalContext, complexFormat, Radian);
|
||||
for (int i = 0; i <= d; i++) {
|
||||
|
||||
@@ -54,11 +54,11 @@ Poincare::Expression parse_expression(const char * expression, bool addParenthes
|
||||
return result;
|
||||
}
|
||||
|
||||
void assert_simplify(const char * expression, Preferences::AngleUnit angleUnit, Preferences::ComplexFormat complexFormat) {
|
||||
void assert_simplify(const char * expression, Preferences::AngleUnit angleUnit, Preferences::ComplexFormat complexFormat, ExpressionNode::ReductionTarget target) {
|
||||
Shared::GlobalContext globalContext;
|
||||
Expression e = parse_expression(expression, false);
|
||||
quiz_assert_print_if_failure(!e.isUninitialized(), expression);
|
||||
e = e.simplify(&globalContext, complexFormat, angleUnit);
|
||||
e = e.simplify(&globalContext, complexFormat, angleUnit, target);
|
||||
quiz_assert_print_if_failure(!(e.isUninitialized()), expression);
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ void assert_parsed_expression_simplify_to(const char * expression, const char *
|
||||
if (target == ExpressionNode::ReductionTarget::User) {
|
||||
copy.simplifyAndApproximate(©, nullptr, context, complexFormat, angleUnit, symbolicComputation);
|
||||
} else {
|
||||
copy = copy.simplify(context, complexFormat, angleUnit, symbolicComputation);
|
||||
copy = copy.simplify(context, complexFormat, angleUnit, target, symbolicComputation);
|
||||
}
|
||||
if (copy.isUninitialized()) {
|
||||
return e;
|
||||
@@ -81,7 +81,7 @@ template<typename T>
|
||||
void assert_expression_approximates_to(const char * expression, const char * approximation, Preferences::AngleUnit angleUnit, Preferences::ComplexFormat complexFormat, int numberOfSignificantDigits) {
|
||||
int numberOfDigits = sizeof(T) == sizeof(double) ? PrintFloat::k_numberOfStoredSignificantDigits : PrintFloat::k_numberOfPrintedSignificantDigits;
|
||||
numberOfDigits = numberOfSignificantDigits > 0 ? numberOfSignificantDigits : numberOfDigits;
|
||||
assert_parsed_expression_process_to(expression, approximation, ExpressionNode::ReductionTarget::System, complexFormat, angleUnit, false, [](Expression e, Context * context, ExpressionNode::ReductionTarget target, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation) {
|
||||
assert_parsed_expression_process_to(expression, approximation, ExpressionNode::ReductionTarget::SystemForApproximation, complexFormat, angleUnit, false, [](Expression e, Context * context, ExpressionNode::ReductionTarget target, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation) {
|
||||
return e.approximate<T>(context, complexFormat, angleUnit);
|
||||
}, numberOfDigits);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,8 @@ const char * MaxIntegerString(); // (2^32)^k_maxNumberOfDigits-1
|
||||
const char * OverflowedIntegerString(); // (2^32)^k_maxNumberOfDigits
|
||||
const char * BigOverflowedIntegerString(); // OverflowedIntegerString with a 2 on first digit
|
||||
|
||||
constexpr Poincare::ExpressionNode::ReductionTarget System = Poincare::ExpressionNode::ReductionTarget::System;
|
||||
constexpr Poincare::ExpressionNode::ReductionTarget SystemForApproximation = Poincare::ExpressionNode::ReductionTarget::SystemForApproximation;
|
||||
constexpr Poincare::ExpressionNode::ReductionTarget SystemForAnalysis = Poincare::ExpressionNode::ReductionTarget::SystemForAnalysis;
|
||||
constexpr Poincare::ExpressionNode::ReductionTarget User = Poincare::ExpressionNode::ReductionTarget::User;
|
||||
constexpr Poincare::Preferences::AngleUnit Degree = Poincare::Preferences::AngleUnit::Degree;
|
||||
constexpr Poincare::Preferences::AngleUnit Radian = Poincare::Preferences::AngleUnit::Radian;
|
||||
@@ -30,7 +31,7 @@ Poincare::Expression parse_expression(const char * expression, bool addParenthes
|
||||
|
||||
// Simplification
|
||||
|
||||
void assert_simplify(const char * expression, Poincare::Preferences::AngleUnit angleUnit = Radian, Poincare::Preferences::ComplexFormat complexFormat = Cartesian);
|
||||
void assert_simplify(const char * expression, Poincare::Preferences::AngleUnit angleUnit = Radian, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, Poincare::ExpressionNode::ReductionTarget target = User);
|
||||
|
||||
void assert_parsed_expression_simplify_to(const char * expression, const char * simplifiedExpression, Poincare::ExpressionNode::ReductionTarget target = User, Poincare::Preferences::AngleUnit angleUnit = Radian, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, bool symbolicComputation = true);
|
||||
|
||||
|
||||
@@ -959,36 +959,54 @@ QUIZ_CASE(poincare_simplification_complex_format) {
|
||||
}
|
||||
|
||||
QUIZ_CASE(poincare_simplification_reduction_target) {
|
||||
assert_parsed_expression_simplify_to("1/π+1/x", "1/x+1/π", System);
|
||||
// Factorize on the same denominator only for ReductionTarget = User
|
||||
assert_parsed_expression_simplify_to("1/π+1/x", "1/x+1/π", SystemForAnalysis);
|
||||
assert_parsed_expression_simplify_to("1/π+1/x", "1/x+1/π", SystemForApproximation);
|
||||
assert_parsed_expression_simplify_to("1/π+1/x", "\u0012x+π\u0013/\u0012π×x\u0013", User);
|
||||
|
||||
assert_parsed_expression_simplify_to("1/(1+𝐢)", "1/\u0012𝐢+1\u0013", System);
|
||||
// Display in the form a+ib only for ReductionTarget = User
|
||||
assert_parsed_expression_simplify_to("1/(1+𝐢)", "1/\u0012𝐢+1\u0013", SystemForAnalysis);
|
||||
assert_parsed_expression_simplify_to("1/(1+𝐢)", "1/\u0012𝐢+1\u0013", SystemForApproximation);
|
||||
assert_parsed_expression_simplify_to("1/(1+𝐢)", "1/2-1/2×𝐢", User);
|
||||
|
||||
assert_parsed_expression_simplify_to("sin(x)/(cos(x)×cos(x))", "sin(x)/cos(x)^2", System);
|
||||
// Replace sin/cos-->tan for ReductionTarget = User
|
||||
assert_parsed_expression_simplify_to("sin(x)/(cos(x)×cos(x))", "sin(x)/cos(x)^2", SystemForAnalysis);
|
||||
assert_parsed_expression_simplify_to("sin(x)/(cos(x)×cos(x))", "sin(x)/cos(x)^2", SystemForApproximation);
|
||||
assert_parsed_expression_simplify_to("sin(x)/(cos(x)×cos(x))", "tan(x)/cos(x)", User);
|
||||
|
||||
assert_parsed_expression_simplify_to("x^0", "x^0", System);
|
||||
// Apply rule x^0 --> 1 for ReductionTarget = User (because this is not always true)
|
||||
assert_parsed_expression_simplify_to("x^0", "x^0", SystemForAnalysis);
|
||||
assert_parsed_expression_simplify_to("x^0", "x^0", SystemForApproximation);
|
||||
assert_parsed_expression_simplify_to("x^0", "1", User);
|
||||
assert_parsed_expression_simplify_to("(1+x)/(1+x)", "(x+1)^0", SystemForApproximation);
|
||||
assert_parsed_expression_simplify_to("(1+x)/(1+x)", "1", User);
|
||||
|
||||
assert_parsed_expression_simplify_to("x^(2/3)", "root(x,3)^2", System);
|
||||
// Apply rule x^(2/3) --> root(x,3)^2 for ReductionTarget = System
|
||||
assert_parsed_expression_simplify_to("x^(2/3)", "root(x,3)^2", SystemForApproximation);
|
||||
assert_parsed_expression_simplify_to("x^(2/3)", "root(x,3)^2", SystemForAnalysis);
|
||||
assert_parsed_expression_simplify_to("x^(2/3)", "x^\u00122/3\u0013", User);
|
||||
assert_parsed_expression_simplify_to("x^(1/3)", "root(x,3)", System);
|
||||
assert_parsed_expression_simplify_to("x^(1/3)", "root(x,3)", System);
|
||||
assert_parsed_expression_simplify_to("x^2", "x^2", System);
|
||||
assert_parsed_expression_simplify_to("x^(1/3)", "root(x,3)", SystemForApproximation);
|
||||
assert_parsed_expression_simplify_to("x^(1/3)", "root(x,3)", SystemForAnalysis);
|
||||
assert_parsed_expression_simplify_to("x^(1/3)", "root(x,3)", User);
|
||||
assert_parsed_expression_simplify_to("x^2", "x^2", SystemForApproximation);
|
||||
assert_parsed_expression_simplify_to("x^2", "x^2", User);
|
||||
|
||||
assert_parsed_expression_simplify_to("1/(√(2)+√(3))", "1/\u0012√(3)+√(2)\u0013", System);
|
||||
// Remove square root at denominator for ReductionTarget = User
|
||||
assert_parsed_expression_simplify_to("1/(√(2)+√(3))", "1/\u0012√(3)+√(2)\u0013", SystemForApproximation);
|
||||
assert_parsed_expression_simplify_to("1/(√(2)+√(3))", "√(3)-√(2)", User);
|
||||
|
||||
assert_parsed_expression_simplify_to("sign(abs(x))", "sign(abs(x))", System);
|
||||
// Always reduce sign for ReductionTarget = User
|
||||
assert_parsed_expression_simplify_to("sign(abs(x))", "sign(abs(x))", SystemForApproximation);
|
||||
assert_parsed_expression_simplify_to("sign(abs(x))", "1", User);
|
||||
|
||||
assert_parsed_expression_simplify_to("atan(1/x)", "atan(1/x)", System);
|
||||
// Apply rule atan(1/x)-> (π×sign(x)-2×atan(x))/2 for ReductionTarget = User (as it is not always true)
|
||||
assert_parsed_expression_simplify_to("atan(1/x)", "atan(1/x)", SystemForApproximation);
|
||||
assert_parsed_expression_simplify_to("atan(1/x)", "\u0012π×sign(x)-2×atan(x)\u0013/2", User);
|
||||
|
||||
assert_parsed_expression_simplify_to("(1+x)/(1+x)", "(x+1)^0", System);
|
||||
assert_parsed_expression_simplify_to("(1+x)/(1+x)", "1", User);
|
||||
// Expand multinome when ReductionTarget is not SystemForApproximation as it increases precision loss
|
||||
assert_parsed_expression_simplify_to("(2+x)^2", "(x+2)^2", SystemForApproximation);
|
||||
assert_parsed_expression_simplify_to("(2+x)^2", "x^2+4×x+4", SystemForAnalysis);
|
||||
assert_parsed_expression_simplify_to("(2+x)^2", "x^2+4×x+4", User);
|
||||
}
|
||||
|
||||
QUIZ_CASE(poincare_simplification_mix) {
|
||||
|
||||
Reference in New Issue
Block a user