mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[solver] Take into account the complexFormat Real
This commit is contained in:
@@ -43,6 +43,10 @@ Expression Equation::standardForm(Context * context) const {
|
||||
return m_standardForm;
|
||||
}
|
||||
|
||||
bool Equation::containsIComplex() const {
|
||||
return strchr(text(), Ion::Charset::IComplex) != nullptr;
|
||||
}
|
||||
|
||||
void Equation::tidyStandardForm() {
|
||||
// Free the pool of the m_standardForm
|
||||
m_standardForm = Expression();
|
||||
|
||||
@@ -14,6 +14,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
Poincare::Expression standardForm(Poincare::Context * context) const;
|
||||
bool containsIComplex() const;
|
||||
private:
|
||||
void tidyStandardForm();
|
||||
mutable Poincare::Expression m_standardForm;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "../shared/poincare_helpers.h"
|
||||
#include <limits.h>
|
||||
|
||||
#include <poincare/constant.h>
|
||||
#include <poincare/symbol.h>
|
||||
#include <poincare/matrix.h>
|
||||
#include <poincare/rational.h>
|
||||
@@ -170,21 +171,39 @@ EquationStore::Error EquationStore::exactSolve(Poincare::Context * context) {
|
||||
}
|
||||
}
|
||||
/* Turn the results in layouts */
|
||||
for (int i = 0; i < k_maxNumberOfExactSolutions; i++) {
|
||||
int solutionIndex = 0;
|
||||
int initialNumberOfSolutions = m_numberOfSolutions;
|
||||
// We iterate through the solutions and the potential delta
|
||||
for (int i = 0; i < initialNumberOfSolutions+1; i++) {
|
||||
if (!exactSolutions[i].isUninitialized()) {
|
||||
m_exactSolutionExactLayouts[i] = PoincareHelpers::CreateLayout(exactSolutions[i]);
|
||||
m_exactSolutionApproximateLayouts[i] = PoincareHelpers::CreateLayout(exactSolutionsApproximations[i]);
|
||||
/* Discard complex solutions if ComplexFormat is Real and the equation
|
||||
* system was not explicitly complex. */
|
||||
if (Preferences::sharedPreferences()->complexFormat() == Preferences::ComplexFormat::Real && !isExplictlyComplex() && exactSolutionsApproximations[i].recursivelyMatches([](const Expression e, Context & context, bool replaceSymbols) { return e.type() == ExpressionNode::Type::Constant && static_cast<const Poincare::Constant &>(e).isIComplex(); }, *context, false)) {
|
||||
if (i < initialNumberOfSolutions) {
|
||||
// Discard the solution
|
||||
m_numberOfSolutions--;
|
||||
continue;
|
||||
} else {
|
||||
assert( i == initialNumberOfSolutions);
|
||||
// Delta is not real
|
||||
exactSolutions[i] = Undefined();
|
||||
exactSolutionsApproximations[i] = Undefined();
|
||||
}
|
||||
}
|
||||
m_exactSolutionExactLayouts[solutionIndex] = PoincareHelpers::CreateLayout(exactSolutions[i]);
|
||||
m_exactSolutionApproximateLayouts[solutionIndex] = PoincareHelpers::CreateLayout(exactSolutionsApproximations[i]);
|
||||
/* Check for identity between exact and approximate layouts */
|
||||
char exactBuffer[Shared::ExpressionModel::k_expressionBufferSize];
|
||||
char approximateBuffer[Shared::ExpressionModel::k_expressionBufferSize];
|
||||
m_exactSolutionExactLayouts[i].serializeForParsing(exactBuffer, Shared::ExpressionModel::k_expressionBufferSize);
|
||||
m_exactSolutionApproximateLayouts[i].serializeForParsing(approximateBuffer, Shared::ExpressionModel::k_expressionBufferSize);
|
||||
m_exactSolutionIdentity[i] = strcmp(exactBuffer, approximateBuffer) == 0;
|
||||
m_exactSolutionExactLayouts[solutionIndex].serializeForParsing(exactBuffer, Shared::ExpressionModel::k_expressionBufferSize);
|
||||
m_exactSolutionApproximateLayouts[solutionIndex].serializeForParsing(approximateBuffer, Shared::ExpressionModel::k_expressionBufferSize);
|
||||
m_exactSolutionIdentity[solutionIndex] = strcmp(exactBuffer, approximateBuffer) == 0;
|
||||
/* Check for equality between exact and approximate layouts */
|
||||
if (!m_exactSolutionIdentity[i]) {
|
||||
if (!m_exactSolutionIdentity[solutionIndex]) {
|
||||
char buffer[Shared::ExpressionModel::k_expressionBufferSize];
|
||||
m_exactSolutionEquality[i] = exactSolutions[i].isEqualToItsApproximationLayout(exactSolutionsApproximations[i], buffer, Shared::ExpressionModel::k_expressionBufferSize, preferences->angleUnit(), preferences->displayMode(), preferences->numberOfSignificantDigits(), *context);
|
||||
m_exactSolutionEquality[solutionIndex] = exactSolutions[i].isEqualToItsApproximationLayout(exactSolutionsApproximations[i], buffer, Shared::ExpressionModel::k_expressionBufferSize, preferences->angleUnit(), preferences->displayMode(), preferences->numberOfSignificantDigits(), *context);
|
||||
}
|
||||
solutionIndex++;
|
||||
}
|
||||
}
|
||||
return error;
|
||||
@@ -337,4 +356,13 @@ void EquationStore::tidySolution() {
|
||||
}
|
||||
}
|
||||
|
||||
bool EquationStore::isExplictlyComplex() {
|
||||
for (int i = 0; i < numberOfDefinedModels(); i++) {
|
||||
if (definedModelAtIndex(i)->containsIComplex()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@ private:
|
||||
Error resolveLinearSystem(Poincare::Expression solutions[k_maxNumberOfExactSolutions], Poincare::Expression solutionApproximations[k_maxNumberOfExactSolutions], Poincare::Expression coefficients[k_maxNumberOfEquations][Poincare::Expression::k_maxNumberOfVariables], Poincare::Expression constants[k_maxNumberOfEquations], Poincare::Context * context);
|
||||
Error oneDimensialPolynomialSolve(Poincare::Expression solutions[k_maxNumberOfExactSolutions], Poincare::Expression solutionApproximations[k_maxNumberOfExactSolutions], Poincare::Expression polynomialCoefficients[Poincare::Expression::k_maxNumberOfPolynomialCoefficients], int degree, Poincare::Context * context);
|
||||
void tidySolution();
|
||||
bool isExplictlyComplex();
|
||||
|
||||
Equation m_equations[k_maxNumberOfEquations];
|
||||
Type m_type;
|
||||
|
||||
@@ -169,4 +169,59 @@ QUIZ_CASE(equation_solve) {
|
||||
assert_equation_system_exact_solve_to(equations19, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variablesBig1Big2, solutions19, 2);
|
||||
}
|
||||
|
||||
QUIZ_CASE(equation_solve_complex_format) {
|
||||
Poincare::Preferences::sharedPreferences()->setComplexFormat(Poincare::Preferences::ComplexFormat::Real);
|
||||
const char * variablesx[] = {"x", ""};
|
||||
// x+I = 0 --> x = -I
|
||||
const char * equations0[] = {"x+I=0", 0};
|
||||
const char * solutions0[] = {"-I"};
|
||||
assert_equation_system_exact_solve_to(equations0, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variablesx, solutions0, 1);
|
||||
|
||||
// x+R(-1) = 0 --> pas de solution dans R
|
||||
const char * equations1[] = {"x+R(-1)=0", 0};
|
||||
assert_equation_system_exact_solve_to(equations1, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variablesx, nullptr, 0);
|
||||
|
||||
// x^2+x+1=0 --> pas de solution dans R
|
||||
const char * equations2[] = {"x^2+x+1=0", 0};
|
||||
const char * delta2[] = {"-3"};
|
||||
assert_equation_system_exact_solve_to(equations2, EquationStore::Error::NoError, EquationStore::Type::PolynomialMonovariable, (const char **)variablesx, delta2, 0);
|
||||
|
||||
// x^2-R(-1)=0 --> pas de solution dans R
|
||||
const char * equations3[] = {"x^2-R(-1)=0", 0};
|
||||
const char * delta3[] = {"undef"};
|
||||
assert_equation_system_exact_solve_to(equations3, EquationStore::Error::NoError, EquationStore::Type::PolynomialMonovariable, (const char **)variablesx, delta3, 0);
|
||||
|
||||
Poincare::Preferences::sharedPreferences()->setComplexFormat(Poincare::Preferences::ComplexFormat::Cartesian);
|
||||
// x+I = 0 --> x = -I
|
||||
assert_equation_system_exact_solve_to(equations0, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variablesx, solutions0, 1);
|
||||
|
||||
// x+R(-1) = 0 --> x = -I
|
||||
assert_equation_system_exact_solve_to(equations1, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variablesx, solutions0, 1);
|
||||
|
||||
// x^2+x+1=0
|
||||
const char * solutions2[] = {"-(1)/(2)-(R(3))/(2)*I","-(1)/(2)+(R(3))/(2)*I", "-3"};
|
||||
assert_equation_system_exact_solve_to(equations2, EquationStore::Error::NoError, EquationStore::Type::PolynomialMonovariable, (const char **)variablesx, solutions2, 2);
|
||||
|
||||
// x^2-R(-1)=0
|
||||
const char * solutions3[] = {"-(R(2))/(2)-(R(2))/(2)*I", "(R(2))/(2)+(R(2))/(2)*I","4*I"};
|
||||
assert_equation_system_exact_solve_to(equations3, EquationStore::Error::NoError, EquationStore::Type::PolynomialMonovariable, (const char **)variablesx, solutions3, 2);
|
||||
|
||||
Poincare::Preferences::sharedPreferences()->setComplexFormat(Poincare::Preferences::ComplexFormat::Polar);
|
||||
// x+I = 0 --> x = e^(-pi/2*i)
|
||||
const char * solutions0Polar[] = {"X$-(P)/(2)*I#"};
|
||||
assert_equation_system_exact_solve_to(equations0, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variablesx, solutions0Polar, 1);
|
||||
|
||||
// x+R(-1) = 0 --> x = e^(-pi/2*i)
|
||||
assert_equation_system_exact_solve_to(equations1, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variablesx, solutions0Polar, 1);
|
||||
|
||||
// x^2+x+1=0
|
||||
const char * solutions2Polar[] = {"X$-(2*P)/(3)*I#","X$(2*P)/(3)*I#", "3*X$P*I#"};
|
||||
assert_equation_system_exact_solve_to(equations2, EquationStore::Error::NoError, EquationStore::Type::PolynomialMonovariable, (const char **)variablesx, solutions2Polar, 2);
|
||||
|
||||
// x^2-R(-1)=0
|
||||
const char * solutions3Polar[] = {"X$-(3*P)/(4)*I#", "X$(P)/(4)*I#", "4*X$(P)/(2)*I#"};
|
||||
assert_equation_system_exact_solve_to(equations3, EquationStore::Error::NoError, EquationStore::Type::PolynomialMonovariable, (const char **)variablesx, solutions3Polar, 2);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user