You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

308 lines
8.5 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2014 Sam Hocevar <sam@hocevar.net>
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the Do What The Fuck You Want To
  7. // Public License, Version 2, as published by Sam Hocevar. See
  8. // http://www.wtfpl.net/ for more details.
  9. //
  10. #include <lol/engine-internal.h>
  11. #include <lolunit.h>
  12. namespace lol
  13. {
  14. lolunit_declare_fixture(PolynomialTest)
  15. {
  16. lolunit_declare_test(Declaration)
  17. {
  18. polynomial<float> p;
  19. polynomial<real> q;
  20. }
  21. lolunit_declare_test(Init)
  22. {
  23. polynomial<float> p { };
  24. lolunit_assert_equal(p[0], 0.f);
  25. lolunit_assert_equal(p[1], 0.f);
  26. lolunit_assert_equal(p[2], 0.f);
  27. lolunit_assert_equal(p.degree(), -1);
  28. polynomial<float> q { 1.f };
  29. lolunit_assert_equal(q[0], 1.f);
  30. lolunit_assert_equal(q[1], 0.f);
  31. lolunit_assert_equal(q[2], 0.f);
  32. lolunit_assert_equal(q.degree(), 0);
  33. polynomial<float> r { 1.f, 2.f };
  34. lolunit_assert_equal(r[0], 1.f);
  35. lolunit_assert_equal(r[1], 2.f);
  36. lolunit_assert_equal(r[2], 0.f);
  37. lolunit_assert_equal(r.degree(), 1);
  38. polynomial<float> s { 0.f };
  39. lolunit_assert_equal(s[0], 0.f);
  40. lolunit_assert_equal(s[1], 0.f);
  41. lolunit_assert_equal(s[2], 0.f);
  42. lolunit_assert_equal(s.degree(), -1);
  43. }
  44. lolunit_declare_test(Derive)
  45. {
  46. polynomial<float> p {};
  47. p = p.derive();
  48. lolunit_assert_equal(p.degree(), -1);
  49. polynomial<float> q { 1.f };
  50. q = q.derive();
  51. lolunit_assert_equal(q.degree(), -1);
  52. polynomial<float> r { 1.f, 2.f };
  53. r = r.derive();
  54. lolunit_assert_equal(r.degree(), 0);
  55. lolunit_assert_equal(r[0], 2.f);
  56. polynomial<float> s { 1.f, 2.f, 3.f, 4.f };
  57. s = s.derive();
  58. lolunit_assert_equal(s.degree(), 2);
  59. lolunit_assert_equal(s[0], 2.f);
  60. lolunit_assert_equal(s[1], 6.f);
  61. lolunit_assert_equal(s[2], 12.f);
  62. }
  63. lolunit_declare_test(Eval)
  64. {
  65. /* Special null polynomial */
  66. polynomial<float> p;
  67. float a = p.eval(42.f);
  68. lolunit_assert_equal(a, 0.f);
  69. }
  70. lolunit_declare_test(Eval0)
  71. {
  72. /* Constant polynomial p(x) = 1 */
  73. polynomial<float> p { 1.f };
  74. float a = p.eval(42.f);
  75. lolunit_assert_equal(a, 1.f);
  76. }
  77. lolunit_declare_test(Eval1)
  78. {
  79. /* p(x) = 1 + 2x */
  80. polynomial<float> p { 1.f, 2.f };
  81. float a = p.eval(0.f);
  82. lolunit_assert_equal(a, 1.f);
  83. float b = p.eval(1.f);
  84. lolunit_assert_equal(b, 3.f);
  85. float c = p.eval(2.f);
  86. lolunit_assert_equal(c, 5.f);
  87. }
  88. lolunit_declare_test(Eval2)
  89. {
  90. /* p(x) = 1 + 2x + 3x² */
  91. polynomial<float> p { 1.f, 2.f, 3.f };
  92. float a = p.eval(0.f);
  93. lolunit_assert_equal(a, 1.f);
  94. float b = p.eval(1.f);
  95. lolunit_assert_equal(b, 6.f);
  96. float c = p.eval(2.f);
  97. lolunit_assert_equal(c, 17.f);
  98. }
  99. lolunit_declare_test(UnaryPlusMinus)
  100. {
  101. /* p(x) = 1 + 2x + 3x² */
  102. polynomial<float> p { 1.f, 2.f, 3.f };
  103. polynomial<float> q = +p;
  104. polynomial<float> r = -p;
  105. lolunit_assert_equal(q[0], 1.f);
  106. lolunit_assert_equal(q[1], 2.f);
  107. lolunit_assert_equal(q[2], 3.f);
  108. lolunit_assert_equal(r[0], -1.f);
  109. lolunit_assert_equal(r[1], -2.f);
  110. lolunit_assert_equal(r[2], -3.f);
  111. }
  112. lolunit_declare_test(Addition)
  113. {
  114. /* p(x) = 1 + 2x + 3x² */
  115. /* q(x) = 4 + 5x */
  116. polynomial<float> p { 1.f, 2.f, 3.f };
  117. polynomial<float> q { 4.f, 5.f };
  118. /* r(x) = 5 + 7x + 3x² */
  119. polynomial<float> r = p + q;
  120. lolunit_assert_equal(r.degree(), 2);
  121. lolunit_assert_equal(r[0], 5.f);
  122. lolunit_assert_equal(r[1], 7.f);
  123. lolunit_assert_equal(r[2], 3.f);
  124. }
  125. lolunit_declare_test(Subtraction)
  126. {
  127. /* p(x) = 1 + 2x + 3x² */
  128. /* q(x) = 4 + 5x */
  129. polynomial<float> p { 1.f, 2.f, 3.f };
  130. polynomial<float> q { 4.f, 5.f };
  131. /* r(x) = -3 + -3x + 3x² */
  132. polynomial<float> r = p - q;
  133. lolunit_assert_equal(r.degree(), 2);
  134. lolunit_assert_equal(r[0], -3.f);
  135. lolunit_assert_equal(r[1], -3.f);
  136. lolunit_assert_equal(r[2], 3.f);
  137. }
  138. lolunit_declare_test(Multiplication)
  139. {
  140. /* p(x) = 1 + 2x + 3x² */
  141. /* q(x) = 4 + 5x */
  142. polynomial<float> p { 1.f, 2.f, 3.f };
  143. polynomial<float> q { 4.f, 5.f };
  144. /* r(x) = 4 + 13x + 22x² + 15x³ */
  145. polynomial<float> r = p * q;
  146. lolunit_assert_equal(r.degree(), 3);
  147. lolunit_assert_equal(r[0], 4.f);
  148. lolunit_assert_equal(r[1], 13.f);
  149. lolunit_assert_equal(r[2], 22.f);
  150. lolunit_assert_equal(r[3], 15.f);
  151. }
  152. lolunit_declare_test(Division)
  153. {
  154. /* p(x) = -4 - 2x² + x³ */
  155. /* q(x) = -3 + x */
  156. polynomial<float> p { -4.f, 0.f, -2.f, 1.f };
  157. polynomial<float> q { -3.f, 1.f };
  158. auto r = p / q;
  159. lolunit_assert_equal(r.m1.degree(), 2);
  160. lolunit_assert_doubles_equal(r.m1[0], 3.f, 1e-5f);
  161. lolunit_assert_doubles_equal(r.m1[1], 1.f, 1e-5f);
  162. lolunit_assert_doubles_equal(r.m1[2], 1.f, 1e-5f);
  163. lolunit_assert_equal(r.m2.degree(), 0);
  164. lolunit_assert_doubles_equal(r.m2[0], 5.f, 1e-5f);
  165. }
  166. lolunit_declare_test(Composition1)
  167. {
  168. /* p(x) = 1 + x² */
  169. polynomial<float> p({ 1, 0, 1 });
  170. /* q(x) = (p o p)(x) = 2 + 2x² + x⁴ */
  171. polynomial<float> q = p.eval(p);
  172. lolunit_assert_equal(q.degree(), 4);
  173. lolunit_assert_equal(q[0], 2.f);
  174. lolunit_assert_equal(q[1], 0.f);
  175. lolunit_assert_equal(q[2], 2.f);
  176. lolunit_assert_equal(q[3], 0.f);
  177. lolunit_assert_equal(q[4], 1.f);
  178. }
  179. lolunit_declare_test(Composition2)
  180. {
  181. /* p(x) = 1 + x */
  182. polynomial<float> p({ 1, 1 });
  183. /* q(x) = 1 + x + x² */
  184. polynomial<float> q({ 1, 1, 1 });
  185. /* r(x) = (q o p)(x) = 3 + 3x + x² */
  186. polynomial<float> r = q.eval(p);
  187. lolunit_assert_equal(r.degree(), 2);
  188. lolunit_assert_equal(r[0], 3.f);
  189. lolunit_assert_equal(r[1], 3.f);
  190. lolunit_assert_equal(r[2], 1.f);
  191. }
  192. lolunit_declare_test(RootsDegree0)
  193. {
  194. /* p(x) = 42 */
  195. polynomial<float> p { 42.f };
  196. auto roots = p.roots();
  197. lolunit_assert_equal(roots.Count(), 0);
  198. }
  199. lolunit_declare_test(RootsDegree1)
  200. {
  201. /* p(x) = -6 + 2x */
  202. polynomial<float> p { -6.f, 2.f };
  203. auto roots = p.roots();
  204. lolunit_assert_equal(roots.Count(), 1);
  205. lolunit_assert_equal(roots[0], 3.f);
  206. }
  207. lolunit_declare_test(RootsDegree2)
  208. {
  209. /* p(x) = 81 - 18x + x² */
  210. polynomial<float> p { 81.f, -18.f, 1.f };
  211. auto roots1 = p.roots();
  212. lolunit_assert_equal(roots1.Count(), 1);
  213. lolunit_assert_equal(roots1[0], 9.f);
  214. /* p(x) = 42 - 20x + 2x² */
  215. polynomial<float> q { 42.f, -20.f, 2.f };
  216. auto roots2 = q.roots();
  217. lolunit_assert_equal(roots2.Count(), 2);
  218. lolunit_assert_equal(roots2[0], 3.f);
  219. lolunit_assert_equal(roots2[1], 7.f);
  220. }
  221. lolunit_declare_test(Chebyshev)
  222. {
  223. polynomial<float> t0 = polynomial<float>::chebyshev(0);
  224. polynomial<float> t1 = polynomial<float>::chebyshev(1);
  225. polynomial<float> t2 = polynomial<float>::chebyshev(2);
  226. polynomial<float> t3 = polynomial<float>::chebyshev(3);
  227. polynomial<float> t4 = polynomial<float>::chebyshev(4);
  228. /* Taken from the sequence at http://oeis.org/A028297 */
  229. lolunit_assert_equal(t0.degree(), 0);
  230. lolunit_assert_equal(t0[0], 1.f);
  231. lolunit_assert_equal(t1.degree(), 1);
  232. lolunit_assert_equal(t1[0], 0.f);
  233. lolunit_assert_equal(t1[1], 1.f);
  234. lolunit_assert_equal(t2.degree(), 2);
  235. lolunit_assert_equal(t2[0], -1.f);
  236. lolunit_assert_equal(t2[1], 0.f);
  237. lolunit_assert_equal(t2[2], 2.f);
  238. lolunit_assert_equal(t3.degree(), 3);
  239. lolunit_assert_equal(t3[0], 0.f);
  240. lolunit_assert_equal(t3[1], -3.f);
  241. lolunit_assert_equal(t3[2], 0.f);
  242. lolunit_assert_equal(t3[3], 4.f);
  243. lolunit_assert_equal(t4.degree(), 4);
  244. lolunit_assert_equal(t4[0], 1.f);
  245. lolunit_assert_equal(t4[1], 0.f);
  246. lolunit_assert_equal(t4[2], -8.f);
  247. lolunit_assert_equal(t4[3], 0.f);
  248. lolunit_assert_equal(t4[4], 8.f);
  249. }
  250. };
  251. } /* namespace lol */