Files
Upsilon/apps/solver/test/equation_store.cpp
Gabriel Ozouf 1e7babadb8 [solver] Change angle unit before test
A test in equation_solve relies on the angle unit being set to Degree,
but doesn't actually set it. Changing the angle unit to another one in a
test prior would break this test.

Change-Id: I6785b087f171d46226d484ebaa3ebdc9e791cedc
2020-12-07 15:58:56 +01:00

190 lines
5.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <quiz.h>
#include "helpers.h"
QUIZ_CASE(equation_solve) {
assert_solves_to_error("x+y+z+a+b+c+d=0", TooManyVariables);
assert_solves_to_error("x^2+y=0", NonLinearSystem);
assert_solves_to_error("cos(x)=0", RequireApproximateSolution);
assert_solves_to_no_solution("2=0");
assert_solves_to_no_solution("x-x+2=0");
assert_solves_to_infinite_solutions("0=0");
assert_solves_to_infinite_solutions("x-x=0");
assert_solves_to("2x+3=4", "x=1/2");
assert_solves_to("3×x^2-4x+4=2", {"x=2/3-(√(2)/3)𝐢", "x=2/3+(√(2)/3)𝐢", "delta=-8"});
assert_solves_to("2×x^2-4×x+4=3", {"x=(-√(2)+2)/2", "x=(√(2)+2)/2", "delta=8"});
assert_solves_to("2×x^2-4×x+2=0", {"x=1", "delta=0"});
assert_solves_to(
"x^2+x+1=3×x^2+π×x-√(5)",
{
"x=(√(π^2-2π+8√(5)+9)-π+1)/4",
"x=(-√(π^2-2π+8×√(5)+9)-π+1)/4",
"delta=π^2-2π+8√(5)+9"
}
);
assert_solves_to("(x-3)^2=0", {"x=3", "delta=0"});
/* TODO: Cubic
* x^3-4x^2+6x-24=0
* x^3+x^2+1=0
* x^3-3x-2=0 */
// Linear System
assert_solves_to_infinite_solutions("x+y=0");
assert_solves_to({"x+y=0", "3x+y=-5"}, {"x=-5/2", "y=5/2"});
assert_solves_to(
{
"x+y=0",
"3x+y+z=-5",
"4z-π=0"
},
{
"x=(-π-20)/8",
"y=(π+20)/8",
"z=π/4"
}
);
assert_solves_to(
{
"x+y=0",
"3x+y+z=-5",
"4z-π=0",
"a+b+c=0",
"a=3",
"c=a+2"
},
{
"x=(-π-20)/8",
"y=(π+20)/8",
"z=π/4",
"a=3",
"b=-8",
"c=5"
}
);
/* This test case needs the user defined variable. Indeed, in the equation
* store, m_variables is just before m_userVariables, so bad fetching in
* m_variables might fetch into m_userVariables and create problems. */
set("x", "0");
assert_solves_to_infinite_solutions({
"b=0",
"D=0",
"e=0",
"x+y+z+t=0"
});
unset("x");
// Monovariable non-polynomial equation
Poincare::Preferences::sharedPreferences()->setAngleUnit(Degree);
assert_solves_numerically_to("cos(x)=0", -100, 100, {-90.0, 90.0});
assert_solves_numerically_to("cos(x)=0", -900, 1000, {-810.0, -630.0, -450.0, -270.0, -90.0, 90.0, 270.0, 450.0, 630.0, 810.0});
assert_solves_numerically_to("√(y)=0", -900, 1000, {0}, "y");
// Long variable names
assert_solves_to("2abcde+3=4", "abcde=1/2");
assert_solves_to({"Big1+Big2=0", "3Big1+Big2=-5"}, {"Big1=-5/2", "Big2=5/2"});
// conj(x)*x+1 = 0
assert_solves_to_error("conj(x)*x+1=0", RequireApproximateSolution);
assert_solves_numerically_to("conj(x)*x+1=0", -100, 100, {});
assert_solves_to_error("(x-10)^7=0", RequireApproximateSolution);
assert_solves_numerically_to("(x-10)^7=0", -100, 100, {10});
}
QUIZ_CASE(equation_solve_complex_real) {
set_complex_format(Real);
assert_solves_to("x+𝐢=0", "x=-𝐢"); // We still want complex solutions if the input has some complex value
assert_solves_to_error("x+√(-1)=0", EquationUnreal);
assert_solves_to("x^2+x+1=0", {"delta=-3"});
assert_solves_to_error("x^2-√(-1)=0", EquationUnreal);
assert_solves_to_error("x+√(-1)×√(-1)=0", EquationUnreal);
assert_solves_to("root(-8,3)*x+3=0", "x=3/2");
reset_complex_format();
}
QUIZ_CASE(equation_solve_complex_cartesian) {
set_complex_format(Cartesian);
assert_solves_to("x+𝐢=0", "x=-𝐢");
assert_solves_to("x+√(-1)=0", "x=-𝐢");
assert_solves_to({"x^2+x+1=0"}, {"x=-1/2-((√(3))/2)𝐢", "x=-1/2+((√(3))/2)𝐢", "delta=-3"});
assert_solves_to("x^2-√(-1)=0", {"x=-√(2)/2-(√(2)/2)𝐢", "x=√(2)/2+(√(2)/2)𝐢", "delta=4𝐢"});
assert_solves_to("x+√(-1)×√(-1)=0", "x=1");
assert_solves_to("root(-8,3)*x+3=0", "x=-3/4+(3√(3)/4)*𝐢");
reset_complex_format();
}
QUIZ_CASE(equation_solve_complex_polar) {
set_complex_format(Polar);
assert_solves_to("x+𝐢=0", "x=^(-(π/2)𝐢)");
assert_solves_to("x+√(-1)=0", "x=^(-(π/2)𝐢)");
assert_solves_to("x^2+x+1=0", {"x=^(-(2π/3)𝐢)", "x=^((2π/3)𝐢)", "delta=3^(π𝐢)"});
assert_solves_to("x^2-√(-1)=0", {"x=^(-(3π/4)𝐢)", "x=^((π/4)𝐢)", "delta=4^((π/2)𝐢)"});
assert_solves_to("root(-8,3)*x+3=0", "x=3/2×^((2π/3)𝐢)");
reset_complex_format();
}
QUIZ_CASE(equation_and_symbolic_computation) {
assert_solves_to_infinite_solutions("x+a=0");
set("a", "-3");
assert_solves_to("x+a=0", "x=3");
assert_solves_to("a=0", "a=0");
/* The equation has no solution since the user defined a = -3. So a is not
* replaced with its context value, and the solution is a = 0. */
set("b", "-4");
assert_solves_to_infinite_solutions("a+b=0");
/* The equation has no solution since the user defined a = -3 and b = -4.
* So neither a nor b are replaced with their context values. Therefore the
* solution is an infinity of solutions. */
assert_solves_to("a+b+c=0", "c=7");
assert_solves_to({"a+c=0", "a=3"}, {"a=3", "c=-3"});
/* The system has no solution since the user defined a = -3. So a is not
* replaced with its context value, and the solution is a = 3 and c = -3. */
set("f(x)", "x+1");
assert_solves_to("f(x)=0", "x=-1");
assert_solves_to("f(a)=0", "a=-1");
/* The equation has no solution since the user defined a = -3. So a is not
* replaced with its context value, and the solution is a = -1. */
set("g(x)", "a+x+2");
assert_solves_to("g(x)=0", "x=1");
assert_solves_to("g(a)=0", "a=-1");
/* The equation has no solution since the user defined a = -3. So a is not
* replaced with its context value, and the equation becomes a + a + 2 = 0.
* The solution is therefore a = -1. */
set("d", "5");
set("c", "d");
set("h(x)", "c+d+3");
assert_solves_to({"h(x)=0", "c=-3"}, {"c=-3", "d=0"});
// c and d context values should not be used
assert_solves_to({"c+d=5", "c-d=1"}, {"c=3", "d=2"});
set("e", "8_g");
assert_solves_to({"e+1=0"}, {"e=-1"});
unset("a");
unset("b");
unset("c");
unset("d");
unset("e");
unset("f");
unset("g");
unset("h");
}