[solver][poincare] Fix tests

This commit is contained in:
Émilie Feral
2018-05-31 11:42:49 +02:00
parent 1610caf8ea
commit 0f89de63f3
6 changed files with 118 additions and 77 deletions

View File

@@ -18,4 +18,10 @@ i18n_files += $(addprefix apps/solver/,\
base.pt.i18n\
)
tests += $(addprefix apps/solver/test/,\
equation_store.cpp\
)
test_objs += $(addprefix apps/solver/, equation.o equation_store.o)
test_objs += $(addprefix apps/shared/, expression_model.o expression_model_store.o)
app_images += apps/solver/solver_icon.png

View File

@@ -0,0 +1,106 @@
#include <quiz.h>
#include <string.h>
#include <assert.h>
#include <limits.h>
#include <cmath>
#include "../equation_store.h"
#include "../../../poincare/test/helper.h"
using namespace Poincare;
namespace Solver {
void assert_equation_system_exact_solve_to(const char * equations[], EquationStore::Error error, EquationStore::Type type, const char * variables, const char * solutions[], int numberOfSolutions) {
GlobalContext globalContext;
EquationStore equationStore;
int index = 0;
while (equations[index] != 0) {
Shared::ExpressionModel * e = equationStore.addEmptyModel();
e->setContent(equations[index++]);
}
EquationStore::Error err = equationStore.exactSolve(&globalContext);
assert(err == error);
if (err != EquationStore::Error::NoError) {
return;
}
assert(equationStore.type() == type);
assert(equationStore.numberOfSolutions() == numberOfSolutions);
if (numberOfSolutions == INT_MAX) {
return;
}
if (type == EquationStore::Type::LinearSystem) {
for (int i = 0; i < numberOfSolutions; i++) {
assert(equationStore.variableAtIndex(i) == variables[i]);
}
} else {
assert(equationStore.variableAtIndex(0) == variables[0]);
}
char buffer[200];
int n = type == EquationStore::Type::PolynomialMonovariable ? numberOfSolutions+1 : numberOfSolutions; // Check Delta for PolynomialMonovariable
for (int i = 0; i < n; i++) {
equationStore.exactSolutionLayoutAtIndex(i, true)->writeTextInBuffer(buffer, 200);
translate_in_ASCII_chars(buffer);
assert(strcmp(buffer, solutions[i]) == 0);
}
}
QUIZ_CASE(equation_solve) {
// x+y+z+a+b+c+d = 0
const char * equations0[] = {"x+y+z+a+b+c+d=0", 0};
assert_equation_system_exact_solve_to(equations0, EquationStore::Error::TooManyVariables, EquationStore::Type::LinearSystem, nullptr, nullptr, 0);
// x^2+y = 0
const char * equations1[] = {"x^2+y=0", 0};
assert_equation_system_exact_solve_to(equations1, EquationStore::Error::NonLinearSystem, EquationStore::Type::LinearSystem, nullptr, nullptr, 0);
// cos(x) = 0
const char * equations2[] = {"cos(x)=0", 0};
assert_equation_system_exact_solve_to(equations2, EquationStore::Error::RequireApproximateSolution, EquationStore::Type::LinearSystem, nullptr, nullptr, 0);
// 2 = 0
const char * equations3[] = {"2=0", 0};
//assert_equation_system_exact_solve_to("2=0", EquationStore::Error::NoError, EquationStore::Type::LinearSystem, "", nullptr, 0);
// 0 = 0
const char * equations4[] = {"0=0", 0};
//assert_equation_system_exact_solve_to(equations4, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, "", nullptr, INT_MAX);
// x-x+2 = 0
const char * equations5[] = {"x-x+2=0", 0};
//assert_equation_system_exact_solve_to(equations5, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, "", nullptr, 0);
// x-x= 0
const char * equations6[] = {"x-x=0", 0};
//assert_equation_system_exact_solve_to(equations5, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, "", nullptr, INT_MAX);
// 2x+3=4
const char * equations7[] = {"2x+3=4", 0};
//assert_equation_system_exact_solve_to(equations7, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, "x", {"1/2"}, 1);
// 3x^2-4x+4=2
const char * equations8[] = {"3x^2-4x+4=2", 0};
const char * solutions8[] = {"(2-R(2)*I)/(3)","(2+R(2)*I)/(3)", "-8"};
assert_equation_system_exact_solve_to(equations8, EquationStore::Error::NoError, EquationStore::Type::PolynomialMonovariable, "x", solutions8, 2);
// 2*x^2-4*x+4=3
const char * equations9[] = {"2*x^2-4*x+4=3", 0};
const char * solutions9[] = {"(2-R(2))/(2)","(2+R(2))/(2)", "8"};
assert_equation_system_exact_solve_to(equations9, EquationStore::Error::NoError, EquationStore::Type::PolynomialMonovariable, "x", solutions9, 2);
// 2*x^2-4*x+2=0
const char * equations10[] = {"2*x^2-4*x+2=0", 0};
const char * solutions10[] = {"1", "0"};
assert_equation_system_exact_solve_to(equations10, EquationStore::Error::NoError, EquationStore::Type::PolynomialMonovariable, "x", solutions10, 1);
// TODO
// x^3 - 4x^2 + 6x - 24 = 0
//const char * equations10[] = {"2*x^2-4*x+4=3", 0};
//assert_equation_system_exact_solve_to(equations10, EquationStore::Error::NoError, EquationStore::Type::PolynomialMonovariable, "x", {"4", "I*R(6)", "-I*R(6)", "-11616"}, 3);
//x^3+x^2+1=0
// x^3-3x-2=0
// Linear System
}
}

View File

@@ -140,7 +140,6 @@ tests += $(addprefix poincare/test/,\
properties.cpp\
rational.cpp\
simplify_mix.cpp\
solver.cpp\
subtraction.cpp\
symbol.cpp\
store.cpp\

View File

@@ -36,6 +36,7 @@ void translate_in_ASCII_chars(char * expression) {
case Ion::Charset::Root: *c = 'R'; break;
case Ion::Charset::SmallPi: *c = 'P'; break;
case Ion::Charset::MultiplicationSign: *c = '*'; break;
case Ion::Charset::MiddleDot: *c = '*'; break;
case Ion::Charset::Sto: *c = '>'; break;
}
}

View File

@@ -126,6 +126,9 @@ QUIZ_CASE(poincare_get_polynomial_coefficients) {
assert_parsed_expression_has_polynomial_coefficient("x^2+x+2", 'x', coefficient0);
const char * coefficient1[] = {"12+(-6)*P", "12", "3", 0}; //3*x^2+12*x-6*π+12
assert_parsed_expression_has_polynomial_coefficient("3*(x+2)^2-6*P", 'x', coefficient1);
const char * coefficient2[] = {"2+32*x", "2", "6", "2", 0}; //2*n^3+6*n^2-2*n+2+32*x
assert_parsed_expression_has_polynomial_coefficient("2*(n+1)^3-4n+32*x", 'n', coefficient2);
// TODO: decomment when enable 3-degree polynomes
//const char * coefficient2[] = {"2+32*x", "2", "6", "2", 0}; //2*n^3+6*n^2+2*n+2+32*x
//assert_parsed_expression_has_polynomial_coefficient("2*(n+1)^3-4n+32*x", 'n', coefficient2);
const char * coefficient3[] = {"1", "-P", "1", 0}; //x^2-Pi*x+1
assert_parsed_expression_has_polynomial_coefficient("x^2-P*x+1", 'x', coefficient3);
}

View File

@@ -1,74 +0,0 @@
#include <quiz.h>
#include <poincare.h>
#include <ion.h>
#include <assert.h>
#include <limits.h>
#include "helper.h"
using namespace Poincare;
void assert_equation_solve_to(const char * expression, int expectedNumberOfSolution, const char ** solutions, const char * delta, Expression::AngleUnit angleUnit = Expression::AngleUnit::Degree) {
GlobalContext globalContext;
Expression * e = parse_expression(expression);
assert(e->type() == Expression::Type::Equal);
Expression * solutionBuffer[Poincare::Expression::k_maxNumberOfVariables];
Expression * deltaBuffer[1] = {nullptr};
int numberOfSolutions = static_cast<Equal *>(e)->solve(solutionBuffer, deltaBuffer, globalContext, angleUnit);
assert(numberOfSolutions == expectedNumberOfSolution);
if (numberOfSolutions >= 0 && numberOfSolutions < INT_MAX) {
for (int i = 0; i < numberOfSolutions; i++) {
Expression * f = parse_expression(solutions[i]);
Expression::Simplify(&f, globalContext, angleUnit);
assert(solutionBuffer[i]->isIdenticalTo(f));
delete f;
delete solutionBuffer[i];
}
assert(solutions[numberOfSolutions] == 0);
if (delta) {
Expression * deltaExpression = parse_expression(delta);
Expression::Simplify(&deltaExpression, globalContext, angleUnit);
assert(deltaBuffer[0]->isIdenticalTo(deltaExpression));
delete deltaBuffer[0];
delete deltaExpression;
}
}
delete e;
}
QUIZ_CASE(poincare_solve_equations) {
// x+y+z+a+b+c+d = 0
assert_equation_solve_to("x+y+z+a+b+c+d=0", -10, nullptr, nullptr);
// 2 = 0
assert_equation_solve_to("2=0", -1, nullptr, nullptr);
// 0 = 0
assert_equation_solve_to("0=0", INT_MAX, nullptr, nullptr);
// cos(x) = 0
// TODO
// x-x+2 = 0
assert_equation_solve_to("x-x+2=0", -1, nullptr, nullptr);
// x-x= 0
assert_equation_solve_to("x-x=0", INT_MAX, nullptr, nullptr);
// 2x+3=4
const char * solutions0[] = {"1/2", 0};
assert_equation_solve_to("2*x+3=4", 1, solutions0, nullptr);
// 3x^2-4x+4=2
const char * solutions1[] = {"1-R(2)/2", "1+R(2)/2", 0};
const char * delta1 = "8";
assert_equation_solve_to("2*x^2-4*x+4=3", 2, solutions1, delta1);
// 3x^2-4x+2=0
const char * solutions2[] = {"1", 0};
const char * delta2 = "0";
assert_equation_solve_to("2*x^2-4*x+2=0", 1, solutions2, delta2);
#if 0
// x^3 - 4x^2 + 6x - 24 = 0
const char * solutions3[] = {"4", "I*R(6)", "-I*R(6)", 0};
const char * delta3 = "-11616";
assert_equation_solve_to("x^3+x^2+1=0", 3, solutions3, delta3);
// x^3-3x-2=0
const char * solutions4[] = {"-1", "2", 0};
const char * delta4 = "0";
assert_equation_solve_to("x^3-3x-2=0", 2, solutions4, delta4);
// TODO: polynome degree 3, 4
#endif
// TODO: linear system
}