|
- //
- // Lol Engine — Unit tests
- //
- // Copyright © 2010—2014 Sam Hocevar <sam@hocevar.net>
- //
- // This program is free software. It comes without any warranty, to
- // the extent permitted by applicable law. You can redistribute it
- // and/or modify it under the terms of the Do What the Fuck You Want
- // to Public License, Version 2, as published by the WTFPL Task Force.
- // See http://www.wtfpl.net/ for more details.
- //
-
- #include <lol/engine-internal.h>
-
- #include <lolunit.h>
-
- namespace lol
- {
-
- lolunit_declare_fixture(PolynomialTest)
- {
- lolunit_declare_test(Declaration)
- {
- polynomial<float> p;
- polynomial<real> q;
- }
-
- lolunit_declare_test(Init)
- {
- polynomial<float> p { };
- lolunit_assert_equal(p[0], 0.f);
- lolunit_assert_equal(p[1], 0.f);
- lolunit_assert_equal(p[2], 0.f);
- lolunit_assert_equal(p.degree(), -1);
-
- polynomial<float> q { 1.f };
- lolunit_assert_equal(q[0], 1.f);
- lolunit_assert_equal(q[1], 0.f);
- lolunit_assert_equal(q[2], 0.f);
- lolunit_assert_equal(q.degree(), 0);
-
- polynomial<float> r { 1.f, 2.f };
- lolunit_assert_equal(r[0], 1.f);
- lolunit_assert_equal(r[1], 2.f);
- lolunit_assert_equal(r[2], 0.f);
- lolunit_assert_equal(r.degree(), 1);
-
- polynomial<float> s { 0.f };
- lolunit_assert_equal(s[0], 0.f);
- lolunit_assert_equal(s[1], 0.f);
- lolunit_assert_equal(s[2], 0.f);
- lolunit_assert_equal(s.degree(), -1);
- }
-
- lolunit_declare_test(Derive)
- {
- polynomial<float> p {};
- p = p.derive();
- lolunit_assert_equal(p.degree(), -1);
-
- polynomial<float> q { 1.f };
- q = q.derive();
- lolunit_assert_equal(q.degree(), -1);
-
- polynomial<float> r { 1.f, 2.f };
- r = r.derive();
- lolunit_assert_equal(r.degree(), 0);
- lolunit_assert_equal(r[0], 2.f);
-
- polynomial<float> s { 1.f, 2.f, 3.f, 4.f };
- s = s.derive();
- lolunit_assert_equal(s.degree(), 2);
- lolunit_assert_equal(s[0], 2.f);
- lolunit_assert_equal(s[1], 6.f);
- lolunit_assert_equal(s[2], 12.f);
- }
-
- lolunit_declare_test(Eval)
- {
- /* Special null polynomial */
- polynomial<float> p;
-
- float a = p.eval(42.f);
- lolunit_assert_equal(a, 0.f);
- }
-
- lolunit_declare_test(Eval0)
- {
- /* Constant polynomial p(x) = 1 */
- polynomial<float> p { 1.f };
-
- float a = p.eval(42.f);
- lolunit_assert_equal(a, 1.f);
- }
-
- lolunit_declare_test(Eval1)
- {
- /* p(x) = 1 + 2x */
- polynomial<float> p { 1.f, 2.f };
-
- float a = p.eval(0.f);
- lolunit_assert_equal(a, 1.f);
-
- float b = p.eval(1.f);
- lolunit_assert_equal(b, 3.f);
-
- float c = p.eval(2.f);
- lolunit_assert_equal(c, 5.f);
- }
-
- lolunit_declare_test(Eval2)
- {
- /* p(x) = 1 + 2x + 3x² */
- polynomial<float> p { 1.f, 2.f, 3.f };
-
- float a = p.eval(0.f);
- lolunit_assert_equal(a, 1.f);
-
- float b = p.eval(1.f);
- lolunit_assert_equal(b, 6.f);
-
- float c = p.eval(2.f);
- lolunit_assert_equal(c, 17.f);
- }
-
- lolunit_declare_test(UnaryPlusMinus)
- {
- /* p(x) = 1 + 2x + 3x² */
- polynomial<float> p { 1.f, 2.f, 3.f };
- polynomial<float> q = +p;
- polynomial<float> r = -p;
-
- lolunit_assert_equal(q[0], 1.f);
- lolunit_assert_equal(q[1], 2.f);
- lolunit_assert_equal(q[2], 3.f);
-
- lolunit_assert_equal(r[0], -1.f);
- lolunit_assert_equal(r[1], -2.f);
- lolunit_assert_equal(r[2], -3.f);
- }
-
- lolunit_declare_test(Addition)
- {
- /* p(x) = 1 + 2x + 3x² */
- /* q(x) = 4 + 5x */
- polynomial<float> p { 1.f, 2.f, 3.f };
- polynomial<float> q { 4.f, 5.f };
-
- /* r(x) = 5 + 7x + 3x² */
- polynomial<float> r = p + q;
- lolunit_assert_equal(r.degree(), 2);
- lolunit_assert_equal(r[0], 5.f);
- lolunit_assert_equal(r[1], 7.f);
- lolunit_assert_equal(r[2], 3.f);
- }
-
- lolunit_declare_test(Subtraction)
- {
- /* p(x) = 1 + 2x + 3x² */
- /* q(x) = 4 + 5x */
- polynomial<float> p { 1.f, 2.f, 3.f };
- polynomial<float> q { 4.f, 5.f };
-
- /* r(x) = -3 + -3x + 3x² */
- polynomial<float> r = p - q;
- lolunit_assert_equal(r.degree(), 2);
- lolunit_assert_equal(r[0], -3.f);
- lolunit_assert_equal(r[1], -3.f);
- lolunit_assert_equal(r[2], 3.f);
- }
-
- lolunit_declare_test(Multiplication)
- {
- /* p(x) = 1 + 2x + 3x² */
- /* q(x) = 4 + 5x */
- polynomial<float> p { 1.f, 2.f, 3.f };
- polynomial<float> q { 4.f, 5.f };
-
- /* r(x) = 4 + 13x + 22x² + 15x³ */
- polynomial<float> r = p * q;
- lolunit_assert_equal(r.degree(), 3);
- lolunit_assert_equal(r[0], 4.f);
- lolunit_assert_equal(r[1], 13.f);
- lolunit_assert_equal(r[2], 22.f);
- lolunit_assert_equal(r[3], 15.f);
- }
-
- lolunit_declare_test(Division)
- {
- /* p(x) = -4 - 2x² + x³ */
- /* q(x) = -3 + x */
- polynomial<float> p { -4.f, 0.f, -2.f, 1.f };
- polynomial<float> q { -3.f, 1.f };
-
- /* p(x) = r(x) q(x) + s(x)
- * r(x) = 3 + x + x²
- * s(x) = 5 */
- auto r = p / q;
- lolunit_assert_equal(r.m1.degree(), 2);
- lolunit_assert_doubles_equal(r.m1[0], 3.f, 1e-5f);
- lolunit_assert_doubles_equal(r.m1[1], 1.f, 1e-5f);
- lolunit_assert_doubles_equal(r.m1[2], 1.f, 1e-5f);
- lolunit_assert_equal(r.m2.degree(), 0);
- lolunit_assert_doubles_equal(r.m2[0], 5.f, 1e-5f);
- }
-
- lolunit_declare_test(Composition1)
- {
- /* p(x) = 1 + x² */
- polynomial<float> p({ 1, 0, 1 });
-
- /* q(x) = (p o p)(x) = 2 + 2x² + x⁴ */
- polynomial<float> q = p.eval(p);
- lolunit_assert_equal(q.degree(), 4);
- lolunit_assert_equal(q[0], 2.f);
- lolunit_assert_equal(q[1], 0.f);
- lolunit_assert_equal(q[2], 2.f);
- lolunit_assert_equal(q[3], 0.f);
- lolunit_assert_equal(q[4], 1.f);
- }
-
- lolunit_declare_test(Composition2)
- {
- /* p(x) = 1 + x */
- polynomial<float> p({ 1, 1 });
-
- /* q(x) = 1 + x + x² */
- polynomial<float> q({ 1, 1, 1 });
-
- /* r(x) = (q o p)(x) = 3 + 3x + x² */
- polynomial<float> r = q.eval(p);
- lolunit_assert_equal(r.degree(), 2);
- lolunit_assert_equal(r[0], 3.f);
- lolunit_assert_equal(r[1], 3.f);
- lolunit_assert_equal(r[2], 1.f);
- }
-
- lolunit_declare_test(RootsDegree0)
- {
- /* p(x) = 42 */
- polynomial<float> p { 42.f };
- auto roots = p.roots();
-
- lolunit_assert_equal(roots.count(), 0);
- }
-
- lolunit_declare_test(RootsDegree1)
- {
- /* p(x) = -6 + 2x */
- polynomial<float> p { -6.f, 2.f };
- auto roots = p.roots();
-
- lolunit_assert_equal(roots.count(), 1);
- lolunit_assert_equal(roots[0], 3.f);
- }
-
- lolunit_declare_test(RootsDegree2)
- {
- /* p(x) = 81 - 18x + x² */
- polynomial<float> p { 81.f, -18.f, 1.f };
- auto roots1 = p.roots();
-
- lolunit_assert_equal(roots1.count(), 1);
- lolunit_assert_equal(roots1[0], 9.f);
-
- /* p(x) = 42 - 20x + 2x² */
- polynomial<float> q { 42.f, -20.f, 2.f };
- auto roots2 = q.roots();
-
- lolunit_assert_equal(roots2.count(), 2);
- lolunit_assert_equal(roots2[0], 3.f);
- lolunit_assert_equal(roots2[1], 7.f);
- }
-
- #ifdef ENABLE_3SOLVE
- lolunit_declare_test(RootsDegree3TripleSolution)
- {
- polynomial<float> p { 1.f, 3.f, 3.f, 1.f };
- auto roots1 = p.roots();
-
- lolunit_assert_equal(roots1.count(), 3);
- }
-
- lolunit_declare_test(RootsDegree3DoubleSolution)
- {
- polynomial<float> p { 2.f, 5.f, 4.f, 1.f };
- auto roots1 = p.roots();
-
- lolunit_assert_equal(roots1.count(), 3);
- }
-
- lolunit_declare_test(RootsDegree3SingleSolutions)
- {
- polynomial<float> p { 6.f, 11.f, 6.f, 1.f };
- auto roots1 = p.roots();
-
- lolunit_assert_equal(roots1.count(), 3);
- }
- #endif
-
- lolunit_declare_test(Chebyshev)
- {
- polynomial<float> t0 = polynomial<float>::chebyshev(0);
- polynomial<float> t1 = polynomial<float>::chebyshev(1);
- polynomial<float> t2 = polynomial<float>::chebyshev(2);
- polynomial<float> t3 = polynomial<float>::chebyshev(3);
- polynomial<float> t4 = polynomial<float>::chebyshev(4);
-
- /* Taken from the sequence at http://oeis.org/A028297 */
- lolunit_assert_equal(t0.degree(), 0);
- lolunit_assert_equal(t0[0], 1.f);
-
- lolunit_assert_equal(t1.degree(), 1);
- lolunit_assert_equal(t1[0], 0.f);
- lolunit_assert_equal(t1[1], 1.f);
-
- lolunit_assert_equal(t2.degree(), 2);
- lolunit_assert_equal(t2[0], -1.f);
- lolunit_assert_equal(t2[1], 0.f);
- lolunit_assert_equal(t2[2], 2.f);
-
- lolunit_assert_equal(t3.degree(), 3);
- lolunit_assert_equal(t3[0], 0.f);
- lolunit_assert_equal(t3[1], -3.f);
- lolunit_assert_equal(t3[2], 0.f);
- lolunit_assert_equal(t3[3], 4.f);
-
- lolunit_assert_equal(t4.degree(), 4);
- lolunit_assert_equal(t4[0], 1.f);
- lolunit_assert_equal(t4[1], 0.f);
- lolunit_assert_equal(t4[2], -8.f);
- lolunit_assert_equal(t4[3], 0.f);
- lolunit_assert_equal(t4[4], 8.f);
- }
- };
-
- } /* namespace lol */
|