test_intpoly.py 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  1. from sympy.functions.elementary.complexes import Abs
  2. from sympy.functions.elementary.miscellaneous import sqrt
  3. from sympy.core import S, Rational
  4. from sympy.integrals.intpoly import (decompose, best_origin, distance_to_side,
  5. polytope_integrate, point_sort,
  6. hyperplane_parameters, main_integrate3d,
  7. main_integrate, polygon_integrate,
  8. lineseg_integrate, integration_reduction,
  9. integration_reduction_dynamic, is_vertex)
  10. from sympy.geometry.line import Segment2D
  11. from sympy.geometry.polygon import Polygon
  12. from sympy.geometry.point import Point, Point2D
  13. from sympy.abc import x, y, z
  14. from sympy.testing.pytest import slow
  15. def test_decompose():
  16. assert decompose(x) == {1: x}
  17. assert decompose(x**2) == {2: x**2}
  18. assert decompose(x*y) == {2: x*y}
  19. assert decompose(x + y) == {1: x + y}
  20. assert decompose(x**2 + y) == {1: y, 2: x**2}
  21. assert decompose(8*x**2 + 4*y + 7) == {0: 7, 1: 4*y, 2: 8*x**2}
  22. assert decompose(x**2 + 3*y*x) == {2: x**2 + 3*x*y}
  23. assert decompose(9*x**2 + y + 4*x + x**3 + y**2*x + 3) ==\
  24. {0: 3, 1: 4*x + y, 2: 9*x**2, 3: x**3 + x*y**2}
  25. assert decompose(x, True) == {x}
  26. assert decompose(x ** 2, True) == {x**2}
  27. assert decompose(x * y, True) == {x * y}
  28. assert decompose(x + y, True) == {x, y}
  29. assert decompose(x ** 2 + y, True) == {y, x ** 2}
  30. assert decompose(8 * x ** 2 + 4 * y + 7, True) == {7, 4*y, 8*x**2}
  31. assert decompose(x ** 2 + 3 * y * x, True) == {x ** 2, 3 * x * y}
  32. assert decompose(9 * x ** 2 + y + 4 * x + x ** 3 + y ** 2 * x + 3, True) == \
  33. {3, y, 4*x, 9*x**2, x*y**2, x**3}
  34. def test_best_origin():
  35. expr1 = y ** 2 * x ** 5 + y ** 5 * x ** 7 + 7 * x + x ** 12 + y ** 7 * x
  36. l1 = Segment2D(Point(0, 3), Point(1, 1))
  37. l2 = Segment2D(Point(S(3) / 2, 0), Point(S(3) / 2, 3))
  38. l3 = Segment2D(Point(0, S(3) / 2), Point(3, S(3) / 2))
  39. l4 = Segment2D(Point(0, 2), Point(2, 0))
  40. l5 = Segment2D(Point(0, 2), Point(1, 1))
  41. l6 = Segment2D(Point(2, 0), Point(1, 1))
  42. assert best_origin((2, 1), 3, l1, expr1) == (0, 3)
  43. # XXX: Should these return exact Rational output? Maybe best_origin should
  44. # sympify its arguments...
  45. assert best_origin((2, 0), 3, l2, x ** 7) == (1.5, 0)
  46. assert best_origin((0, 2), 3, l3, x ** 7) == (0, 1.5)
  47. assert best_origin((1, 1), 2, l4, x ** 7 * y ** 3) == (0, 2)
  48. assert best_origin((1, 1), 2, l4, x ** 3 * y ** 7) == (2, 0)
  49. assert best_origin((1, 1), 2, l5, x ** 2 * y ** 9) == (0, 2)
  50. assert best_origin((1, 1), 2, l6, x ** 9 * y ** 2) == (2, 0)
  51. @slow
  52. def test_polytope_integrate():
  53. # Convex 2-Polytopes
  54. # Vertex representation
  55. assert polytope_integrate(Polygon(Point(0, 0), Point(0, 2),
  56. Point(4, 0)), 1) == 4
  57. assert polytope_integrate(Polygon(Point(0, 0), Point(0, 1),
  58. Point(1, 1), Point(1, 0)), x * y) ==\
  59. Rational(1, 4)
  60. assert polytope_integrate(Polygon(Point(0, 3), Point(5, 3), Point(1, 1)),
  61. 6*x**2 - 40*y) == Rational(-935, 3)
  62. assert polytope_integrate(Polygon(Point(0, 0), Point(0, sqrt(3)),
  63. Point(sqrt(3), sqrt(3)),
  64. Point(sqrt(3), 0)), 1) == 3
  65. hexagon = Polygon(Point(0, 0), Point(-sqrt(3) / 2, S.Half),
  66. Point(-sqrt(3) / 2, S(3) / 2), Point(0, 2),
  67. Point(sqrt(3) / 2, S(3) / 2), Point(sqrt(3) / 2, S.Half))
  68. assert polytope_integrate(hexagon, 1) == S(3*sqrt(3)) / 2
  69. # Hyperplane representation
  70. assert polytope_integrate([((-1, 0), 0), ((1, 2), 4),
  71. ((0, -1), 0)], 1) == 4
  72. assert polytope_integrate([((-1, 0), 0), ((0, 1), 1),
  73. ((1, 0), 1), ((0, -1), 0)], x * y) == Rational(1, 4)
  74. assert polytope_integrate([((0, 1), 3), ((1, -2), -1),
  75. ((-2, -1), -3)], 6*x**2 - 40*y) == Rational(-935, 3)
  76. assert polytope_integrate([((-1, 0), 0), ((0, sqrt(3)), 3),
  77. ((sqrt(3), 0), 3), ((0, -1), 0)], 1) == 3
  78. hexagon = [((Rational(-1, 2), -sqrt(3) / 2), 0),
  79. ((-1, 0), sqrt(3) / 2),
  80. ((Rational(-1, 2), sqrt(3) / 2), sqrt(3)),
  81. ((S.Half, sqrt(3) / 2), sqrt(3)),
  82. ((1, 0), sqrt(3) / 2),
  83. ((S.Half, -sqrt(3) / 2), 0)]
  84. assert polytope_integrate(hexagon, 1) == S(3*sqrt(3)) / 2
  85. # Non-convex polytopes
  86. # Vertex representation
  87. assert polytope_integrate(Polygon(Point(-1, -1), Point(-1, 1),
  88. Point(1, 1), Point(0, 0),
  89. Point(1, -1)), 1) == 3
  90. assert polytope_integrate(Polygon(Point(-1, -1), Point(-1, 1),
  91. Point(0, 0), Point(1, 1),
  92. Point(1, -1), Point(0, 0)), 1) == 2
  93. # Hyperplane representation
  94. assert polytope_integrate([((-1, 0), 1), ((0, 1), 1), ((1, -1), 0),
  95. ((1, 1), 0), ((0, -1), 1)], 1) == 3
  96. assert polytope_integrate([((-1, 0), 1), ((1, 1), 0), ((-1, 1), 0),
  97. ((1, 0), 1), ((-1, -1), 0),
  98. ((1, -1), 0)], 1) == 2
  99. # Tests for 2D polytopes mentioned in Chin et al(Page 10):
  100. # http://dilbert.engr.ucdavis.edu/~suku/quadrature/cls-integration.pdf
  101. fig1 = Polygon(Point(1.220, -0.827), Point(-1.490, -4.503),
  102. Point(-3.766, -1.622), Point(-4.240, -0.091),
  103. Point(-3.160, 4), Point(-0.981, 4.447),
  104. Point(0.132, 4.027))
  105. assert polytope_integrate(fig1, x**2 + x*y + y**2) ==\
  106. S(2031627344735367)/(8*10**12)
  107. fig2 = Polygon(Point(4.561, 2.317), Point(1.491, -1.315),
  108. Point(-3.310, -3.164), Point(-4.845, -3.110),
  109. Point(-4.569, 1.867))
  110. assert polytope_integrate(fig2, x**2 + x*y + y**2) ==\
  111. S(517091313866043)/(16*10**11)
  112. fig3 = Polygon(Point(-2.740, -1.888), Point(-3.292, 4.233),
  113. Point(-2.723, -0.697), Point(-0.643, -3.151))
  114. assert polytope_integrate(fig3, x**2 + x*y + y**2) ==\
  115. S(147449361647041)/(8*10**12)
  116. fig4 = Polygon(Point(0.211, -4.622), Point(-2.684, 3.851),
  117. Point(0.468, 4.879), Point(4.630, -1.325),
  118. Point(-0.411, -1.044))
  119. assert polytope_integrate(fig4, x**2 + x*y + y**2) ==\
  120. S(180742845225803)/(10**12)
  121. # Tests for many polynomials with maximum degree given(2D case).
  122. tri = Polygon(Point(0, 3), Point(5, 3), Point(1, 1))
  123. polys = []
  124. expr1 = x**9*y + x**7*y**3 + 2*x**2*y**8
  125. expr2 = x**6*y**4 + x**5*y**5 + 2*y**10
  126. expr3 = x**10 + x**9*y + x**8*y**2 + x**5*y**5
  127. polys.extend((expr1, expr2, expr3))
  128. result_dict = polytope_integrate(tri, polys, max_degree=10)
  129. assert result_dict[expr1] == Rational(615780107, 594)
  130. assert result_dict[expr2] == Rational(13062161, 27)
  131. assert result_dict[expr3] == Rational(1946257153, 924)
  132. tri = Polygon(Point(0, 3), Point(5, 3), Point(1, 1))
  133. expr1 = x**7*y**1 + 2*x**2*y**6
  134. expr2 = x**6*y**4 + x**5*y**5 + 2*y**10
  135. expr3 = x**10 + x**9*y + x**8*y**2 + x**5*y**5
  136. polys.extend((expr1, expr2, expr3))
  137. assert polytope_integrate(tri, polys, max_degree=9) == \
  138. {x**7*y + 2*x**2*y**6: Rational(489262, 9)}
  139. # Tests when all integral of all monomials up to a max_degree is to be
  140. # calculated.
  141. assert polytope_integrate(Polygon(Point(0, 0), Point(0, 1),
  142. Point(1, 1), Point(1, 0)),
  143. max_degree=4) == {0: 0, 1: 1, x: S.Half,
  144. x ** 2 * y ** 2: S.One / 9,
  145. x ** 4: S.One / 5,
  146. y ** 4: S.One / 5,
  147. y: S.Half,
  148. x * y ** 2: S.One / 6,
  149. y ** 2: S.One / 3,
  150. x ** 3: S.One / 4,
  151. x ** 2 * y: S.One / 6,
  152. x ** 3 * y: S.One / 8,
  153. x * y: S.One / 4,
  154. y ** 3: S.One / 4,
  155. x ** 2: S.One / 3,
  156. x * y ** 3: S.One / 8}
  157. # Tests for 3D polytopes
  158. cube1 = [[(0, 0, 0), (0, 6, 6), (6, 6, 6), (3, 6, 0),
  159. (0, 6, 0), (6, 0, 6), (3, 0, 0), (0, 0, 6)],
  160. [1, 2, 3, 4], [3, 2, 5, 6], [1, 7, 5, 2], [0, 6, 5, 7],
  161. [1, 4, 0, 7], [0, 4, 3, 6]]
  162. assert polytope_integrate(cube1, 1) == S(162)
  163. # 3D Test cases in Chin et al(2015)
  164. cube2 = [[(0, 0, 0), (0, 0, 5), (0, 5, 0), (0, 5, 5), (5, 0, 0),
  165. (5, 0, 5), (5, 5, 0), (5, 5, 5)],
  166. [3, 7, 6, 2], [1, 5, 7, 3], [5, 4, 6, 7], [0, 4, 5, 1],
  167. [2, 0, 1, 3], [2, 6, 4, 0]]
  168. cube3 = [[(0, 0, 0), (5, 0, 0), (5, 4, 0), (3, 2, 0), (3, 5, 0),
  169. (0, 5, 0), (0, 0, 5), (5, 0, 5), (5, 4, 5), (3, 2, 5),
  170. (3, 5, 5), (0, 5, 5)],
  171. [6, 11, 5, 0], [1, 7, 6, 0], [5, 4, 3, 2, 1, 0], [11, 10, 4, 5],
  172. [10, 9, 3, 4], [9, 8, 2, 3], [8, 7, 1, 2], [7, 8, 9, 10, 11, 6]]
  173. cube4 = [[(0, 0, 0), (1, 0, 0), (0, 1, 0), (0, 0, 1),
  174. (S.One / 4, S.One / 4, S.One / 4)],
  175. [0, 2, 1], [1, 3, 0], [4, 2, 3], [4, 3, 1],
  176. [0, 1, 2], [2, 4, 1], [0, 3, 2]]
  177. assert polytope_integrate(cube2, x ** 2 + y ** 2 + x * y + z ** 2) ==\
  178. Rational(15625, 4)
  179. assert polytope_integrate(cube3, x ** 2 + y ** 2 + x * y + z ** 2) ==\
  180. S(33835) / 12
  181. assert polytope_integrate(cube4, x ** 2 + y ** 2 + x * y + z ** 2) ==\
  182. S(37) / 960
  183. # Test cases from Mathematica's PolyhedronData library
  184. octahedron = [[(S.NegativeOne / sqrt(2), 0, 0), (0, S.One / sqrt(2), 0),
  185. (0, 0, S.NegativeOne / sqrt(2)), (0, 0, S.One / sqrt(2)),
  186. (0, S.NegativeOne / sqrt(2), 0), (S.One / sqrt(2), 0, 0)],
  187. [3, 4, 5], [3, 5, 1], [3, 1, 0], [3, 0, 4], [4, 0, 2],
  188. [4, 2, 5], [2, 0, 1], [5, 2, 1]]
  189. assert polytope_integrate(octahedron, 1) == sqrt(2) / 3
  190. great_stellated_dodecahedron =\
  191. [[(-0.32491969623290634095, 0, 0.42532540417601993887),
  192. (0.32491969623290634095, 0, -0.42532540417601993887),
  193. (-0.52573111211913359231, 0, 0.10040570794311363956),
  194. (0.52573111211913359231, 0, -0.10040570794311363956),
  195. (-0.10040570794311363956, -0.3090169943749474241, 0.42532540417601993887),
  196. (-0.10040570794311363956, 0.30901699437494742410, 0.42532540417601993887),
  197. (0.10040570794311363956, -0.3090169943749474241, -0.42532540417601993887),
  198. (0.10040570794311363956, 0.30901699437494742410, -0.42532540417601993887),
  199. (-0.16245984811645317047, -0.5, 0.10040570794311363956),
  200. (-0.16245984811645317047, 0.5, 0.10040570794311363956),
  201. (0.16245984811645317047, -0.5, -0.10040570794311363956),
  202. (0.16245984811645317047, 0.5, -0.10040570794311363956),
  203. (-0.42532540417601993887, -0.3090169943749474241, -0.10040570794311363956),
  204. (-0.42532540417601993887, 0.30901699437494742410, -0.10040570794311363956),
  205. (-0.26286555605956679615, 0.1909830056250525759, -0.42532540417601993887),
  206. (-0.26286555605956679615, -0.1909830056250525759, -0.42532540417601993887),
  207. (0.26286555605956679615, 0.1909830056250525759, 0.42532540417601993887),
  208. (0.26286555605956679615, -0.1909830056250525759, 0.42532540417601993887),
  209. (0.42532540417601993887, -0.3090169943749474241, 0.10040570794311363956),
  210. (0.42532540417601993887, 0.30901699437494742410, 0.10040570794311363956)],
  211. [12, 3, 0, 6, 16], [17, 7, 0, 3, 13],
  212. [9, 6, 0, 7, 8], [18, 2, 1, 4, 14],
  213. [15, 5, 1, 2, 19], [11, 4, 1, 5, 10],
  214. [8, 19, 2, 18, 9], [10, 13, 3, 12, 11],
  215. [16, 14, 4, 11, 12], [13, 10, 5, 15, 17],
  216. [14, 16, 6, 9, 18], [19, 8, 7, 17, 15]]
  217. # Actual volume is : 0.163118960624632
  218. assert Abs(polytope_integrate(great_stellated_dodecahedron, 1) -\
  219. 0.163118960624632) < 1e-12
  220. expr = x **2 + y ** 2 + z ** 2
  221. octahedron_five_compound = [[(0, -0.7071067811865475244, 0),
  222. (0, 0.70710678118654752440, 0),
  223. (0.1148764602736805918,
  224. -0.35355339059327376220, -0.60150095500754567366),
  225. (0.1148764602736805918, 0.35355339059327376220,
  226. -0.60150095500754567366),
  227. (0.18587401723009224507,
  228. -0.57206140281768429760, 0.37174803446018449013),
  229. (0.18587401723009224507, 0.57206140281768429760,
  230. 0.37174803446018449013),
  231. (0.30075047750377283683, -0.21850801222441053540,
  232. 0.60150095500754567366),
  233. (0.30075047750377283683, 0.21850801222441053540,
  234. 0.60150095500754567366),
  235. (0.48662449473386508189, -0.35355339059327376220,
  236. -0.37174803446018449013),
  237. (0.48662449473386508189, 0.35355339059327376220,
  238. -0.37174803446018449013),
  239. (-0.60150095500754567366, 0, -0.37174803446018449013),
  240. (-0.30075047750377283683, -0.21850801222441053540,
  241. -0.60150095500754567366),
  242. (-0.30075047750377283683, 0.21850801222441053540,
  243. -0.60150095500754567366),
  244. (0.60150095500754567366, 0, 0.37174803446018449013),
  245. (0.4156269377774534286, -0.57206140281768429760, 0),
  246. (0.4156269377774534286, 0.57206140281768429760, 0),
  247. (0.37174803446018449013, 0, -0.60150095500754567366),
  248. (-0.4156269377774534286, -0.57206140281768429760, 0),
  249. (-0.4156269377774534286, 0.57206140281768429760, 0),
  250. (-0.67249851196395732696, -0.21850801222441053540, 0),
  251. (-0.67249851196395732696, 0.21850801222441053540, 0),
  252. (0.67249851196395732696, -0.21850801222441053540, 0),
  253. (0.67249851196395732696, 0.21850801222441053540, 0),
  254. (-0.37174803446018449013, 0, 0.60150095500754567366),
  255. (-0.48662449473386508189, -0.35355339059327376220,
  256. 0.37174803446018449013),
  257. (-0.48662449473386508189, 0.35355339059327376220,
  258. 0.37174803446018449013),
  259. (-0.18587401723009224507, -0.57206140281768429760,
  260. -0.37174803446018449013),
  261. (-0.18587401723009224507, 0.57206140281768429760,
  262. -0.37174803446018449013),
  263. (-0.11487646027368059176, -0.35355339059327376220,
  264. 0.60150095500754567366),
  265. (-0.11487646027368059176, 0.35355339059327376220,
  266. 0.60150095500754567366)],
  267. [0, 10, 16], [23, 10, 0], [16, 13, 0],
  268. [0, 13, 23], [16, 10, 1], [1, 10, 23],
  269. [1, 13, 16], [23, 13, 1], [2, 4, 19],
  270. [22, 4, 2], [2, 19, 27], [27, 22, 2],
  271. [20, 5, 3], [3, 5, 21], [26, 20, 3],
  272. [3, 21, 26], [29, 19, 4], [4, 22, 29],
  273. [5, 20, 28], [28, 21, 5], [6, 8, 15],
  274. [17, 8, 6], [6, 15, 25], [25, 17, 6],
  275. [14, 9, 7], [7, 9, 18], [24, 14, 7],
  276. [7, 18, 24], [8, 12, 15], [17, 12, 8],
  277. [14, 11, 9], [9, 11, 18], [11, 14, 24],
  278. [24, 18, 11], [25, 15, 12], [12, 17, 25],
  279. [29, 27, 19], [20, 26, 28], [28, 26, 21],
  280. [22, 27, 29]]
  281. assert Abs(polytope_integrate(octahedron_five_compound, expr)) - 0.353553\
  282. < 1e-6
  283. cube_five_compound = [[(-0.1624598481164531631, -0.5, -0.6881909602355867691),
  284. (-0.1624598481164531631, 0.5, -0.6881909602355867691),
  285. (0.1624598481164531631, -0.5, 0.68819096023558676910),
  286. (0.1624598481164531631, 0.5, 0.68819096023558676910),
  287. (-0.52573111211913359231, 0, -0.6881909602355867691),
  288. (0.52573111211913359231, 0, 0.68819096023558676910),
  289. (-0.26286555605956679615, -0.8090169943749474241,
  290. -0.1624598481164531631),
  291. (-0.26286555605956679615, 0.8090169943749474241,
  292. -0.1624598481164531631),
  293. (0.26286555605956680301, -0.8090169943749474241,
  294. 0.1624598481164531631),
  295. (0.26286555605956680301, 0.8090169943749474241,
  296. 0.1624598481164531631),
  297. (-0.42532540417601993887, -0.3090169943749474241,
  298. 0.68819096023558676910),
  299. (-0.42532540417601993887, 0.30901699437494742410,
  300. 0.68819096023558676910),
  301. (0.42532540417601996609, -0.3090169943749474241,
  302. -0.6881909602355867691),
  303. (0.42532540417601996609, 0.30901699437494742410,
  304. -0.6881909602355867691),
  305. (-0.6881909602355867691, -0.5, 0.1624598481164531631),
  306. (-0.6881909602355867691, 0.5, 0.1624598481164531631),
  307. (0.68819096023558676910, -0.5, -0.1624598481164531631),
  308. (0.68819096023558676910, 0.5, -0.1624598481164531631),
  309. (-0.85065080835203998877, 0, -0.1624598481164531631),
  310. (0.85065080835203993218, 0, 0.1624598481164531631)],
  311. [18, 10, 3, 7], [13, 19, 8, 0], [18, 0, 8, 10],
  312. [3, 19, 13, 7], [18, 7, 13, 0], [8, 19, 3, 10],
  313. [6, 2, 11, 18], [1, 9, 19, 12], [11, 9, 1, 18],
  314. [6, 12, 19, 2], [1, 12, 6, 18], [11, 2, 19, 9],
  315. [4, 14, 11, 7], [17, 5, 8, 12], [4, 12, 8, 14],
  316. [11, 5, 17, 7], [4, 7, 17, 12], [8, 5, 11, 14],
  317. [6, 10, 15, 4], [13, 9, 5, 16], [15, 9, 13, 4],
  318. [6, 16, 5, 10], [13, 16, 6, 4], [15, 10, 5, 9],
  319. [14, 15, 1, 0], [16, 17, 3, 2], [14, 2, 3, 15],
  320. [1, 17, 16, 0], [14, 0, 16, 2], [3, 17, 1, 15]]
  321. assert Abs(polytope_integrate(cube_five_compound, expr) - 1.25) < 1e-12
  322. echidnahedron = [[(0, 0, -2.4898982848827801995),
  323. (0, 0, 2.4898982848827802734),
  324. (0, -4.2360679774997896964, -2.4898982848827801995),
  325. (0, -4.2360679774997896964, 2.4898982848827802734),
  326. (0, 4.2360679774997896964, -2.4898982848827801995),
  327. (0, 4.2360679774997896964, 2.4898982848827802734),
  328. (-4.0287400534704067567, -1.3090169943749474241, -2.4898982848827801995),
  329. (-4.0287400534704067567, -1.3090169943749474241, 2.4898982848827802734),
  330. (-4.0287400534704067567, 1.3090169943749474241, -2.4898982848827801995),
  331. (-4.0287400534704067567, 1.3090169943749474241, 2.4898982848827802734),
  332. (4.0287400534704069747, -1.3090169943749474241, -2.4898982848827801995),
  333. (4.0287400534704069747, -1.3090169943749474241, 2.4898982848827802734),
  334. (4.0287400534704069747, 1.3090169943749474241, -2.4898982848827801995),
  335. (4.0287400534704069747, 1.3090169943749474241, 2.4898982848827802734),
  336. (-2.4898982848827801995, -3.4270509831248422723, -2.4898982848827801995),
  337. (-2.4898982848827801995, -3.4270509831248422723, 2.4898982848827802734),
  338. (-2.4898982848827801995, 3.4270509831248422723, -2.4898982848827801995),
  339. (-2.4898982848827801995, 3.4270509831248422723, 2.4898982848827802734),
  340. (2.4898982848827802734, -3.4270509831248422723, -2.4898982848827801995),
  341. (2.4898982848827802734, -3.4270509831248422723, 2.4898982848827802734),
  342. (2.4898982848827802734, 3.4270509831248422723, -2.4898982848827801995),
  343. (2.4898982848827802734, 3.4270509831248422723, 2.4898982848827802734),
  344. (-4.7169310137059934362, -0.8090169943749474241, -1.1135163644116066184),
  345. (-4.7169310137059934362, 0.8090169943749474241, -1.1135163644116066184),
  346. (4.7169310137059937438, -0.8090169943749474241, 1.11351636441160673519),
  347. (4.7169310137059937438, 0.8090169943749474241, 1.11351636441160673519),
  348. (-4.2916056095299737777, -2.1180339887498948482, 1.11351636441160673519),
  349. (-4.2916056095299737777, 2.1180339887498948482, 1.11351636441160673519),
  350. (4.2916056095299737777, -2.1180339887498948482, -1.1135163644116066184),
  351. (4.2916056095299737777, 2.1180339887498948482, -1.1135163644116066184),
  352. (-3.6034146492943870399, 0, -3.3405490932348205213),
  353. (3.6034146492943870399, 0, 3.3405490932348202056),
  354. (-3.3405490932348205213, -3.4270509831248422723, 1.11351636441160673519),
  355. (-3.3405490932348205213, 3.4270509831248422723, 1.11351636441160673519),
  356. (3.3405490932348202056, -3.4270509831248422723, -1.1135163644116066184),
  357. (3.3405490932348202056, 3.4270509831248422723, -1.1135163644116066184),
  358. (-2.9152236890588002395, -2.1180339887498948482, 3.3405490932348202056),
  359. (-2.9152236890588002395, 2.1180339887498948482, 3.3405490932348202056),
  360. (2.9152236890588002395, -2.1180339887498948482, -3.3405490932348205213),
  361. (2.9152236890588002395, 2.1180339887498948482, -3.3405490932348205213),
  362. (-2.2270327288232132368, 0, -1.1135163644116066184),
  363. (-2.2270327288232132368, -4.2360679774997896964, -1.1135163644116066184),
  364. (-2.2270327288232132368, 4.2360679774997896964, -1.1135163644116066184),
  365. (2.2270327288232134704, 0, 1.11351636441160673519),
  366. (2.2270327288232134704, -4.2360679774997896964, 1.11351636441160673519),
  367. (2.2270327288232134704, 4.2360679774997896964, 1.11351636441160673519),
  368. (-1.8017073246471935200, -1.3090169943749474241, 1.11351636441160673519),
  369. (-1.8017073246471935200, 1.3090169943749474241, 1.11351636441160673519),
  370. (1.8017073246471935043, -1.3090169943749474241, -1.1135163644116066184),
  371. (1.8017073246471935043, 1.3090169943749474241, -1.1135163644116066184),
  372. (-1.3763819204711735382, 0, -4.7169310137059934362),
  373. (-1.3763819204711735382, 0, 0.26286555605956679615),
  374. (1.37638192047117353821, 0, 4.7169310137059937438),
  375. (1.37638192047117353821, 0, -0.26286555605956679615),
  376. (-1.1135163644116066184, -3.4270509831248422723, -3.3405490932348205213),
  377. (-1.1135163644116066184, -0.8090169943749474241, 4.7169310137059937438),
  378. (-1.1135163644116066184, -0.8090169943749474241, -0.26286555605956679615),
  379. (-1.1135163644116066184, 0.8090169943749474241, 4.7169310137059937438),
  380. (-1.1135163644116066184, 0.8090169943749474241, -0.26286555605956679615),
  381. (-1.1135163644116066184, 3.4270509831248422723, -3.3405490932348205213),
  382. (1.11351636441160673519, -3.4270509831248422723, 3.3405490932348202056),
  383. (1.11351636441160673519, -0.8090169943749474241, -4.7169310137059934362),
  384. (1.11351636441160673519, -0.8090169943749474241, 0.26286555605956679615),
  385. (1.11351636441160673519, 0.8090169943749474241, -4.7169310137059934362),
  386. (1.11351636441160673519, 0.8090169943749474241, 0.26286555605956679615),
  387. (1.11351636441160673519, 3.4270509831248422723, 3.3405490932348202056),
  388. (-0.85065080835203998877, 0, 1.11351636441160673519),
  389. (0.85065080835203993218, 0, -1.1135163644116066184),
  390. (-0.6881909602355867691, -0.5, -1.1135163644116066184),
  391. (-0.6881909602355867691, 0.5, -1.1135163644116066184),
  392. (-0.6881909602355867691, -4.7360679774997896964, -1.1135163644116066184),
  393. (-0.6881909602355867691, -2.1180339887498948482, -1.1135163644116066184),
  394. (-0.6881909602355867691, 2.1180339887498948482, -1.1135163644116066184),
  395. (-0.6881909602355867691, 4.7360679774997896964, -1.1135163644116066184),
  396. (0.68819096023558676910, -0.5, 1.11351636441160673519),
  397. (0.68819096023558676910, 0.5, 1.11351636441160673519),
  398. (0.68819096023558676910, -4.7360679774997896964, 1.11351636441160673519),
  399. (0.68819096023558676910, -2.1180339887498948482, 1.11351636441160673519),
  400. (0.68819096023558676910, 2.1180339887498948482, 1.11351636441160673519),
  401. (0.68819096023558676910, 4.7360679774997896964, 1.11351636441160673519),
  402. (-0.42532540417601993887, -1.3090169943749474241, -4.7169310137059934362),
  403. (-0.42532540417601993887, -1.3090169943749474241, 0.26286555605956679615),
  404. (-0.42532540417601993887, 1.3090169943749474241, -4.7169310137059934362),
  405. (-0.42532540417601993887, 1.3090169943749474241, 0.26286555605956679615),
  406. (-0.26286555605956679615, -0.8090169943749474241, 1.11351636441160673519),
  407. (-0.26286555605956679615, 0.8090169943749474241, 1.11351636441160673519),
  408. (0.26286555605956679615, -0.8090169943749474241, -1.1135163644116066184),
  409. (0.26286555605956679615, 0.8090169943749474241, -1.1135163644116066184),
  410. (0.42532540417601996609, -1.3090169943749474241, 4.7169310137059937438),
  411. (0.42532540417601996609, -1.3090169943749474241, -0.26286555605956679615),
  412. (0.42532540417601996609, 1.3090169943749474241, 4.7169310137059937438),
  413. (0.42532540417601996609, 1.3090169943749474241, -0.26286555605956679615)],
  414. [9, 66, 47], [44, 62, 77], [20, 91, 49], [33, 47, 83],
  415. [3, 77, 84], [12, 49, 53], [36, 84, 66], [28, 53, 62],
  416. [73, 83, 91], [15, 84, 46], [25, 64, 43], [16, 58, 72],
  417. [26, 46, 51], [11, 43, 74], [4, 72, 91], [60, 74, 84],
  418. [35, 91, 64], [23, 51, 58], [19, 74, 77], [79, 83, 78],
  419. [6, 56, 40], [76, 77, 81], [21, 78, 75], [8, 40, 58],
  420. [31, 75, 74], [42, 58, 83], [41, 81, 56], [13, 75, 43],
  421. [27, 51, 47], [2, 89, 71], [24, 43, 62], [17, 47, 85],
  422. [14, 71, 56], [65, 85, 75], [22, 56, 51], [34, 62, 89],
  423. [5, 85, 78], [32, 81, 46], [10, 53, 48], [45, 78, 64],
  424. [7, 46, 66], [18, 48, 89], [37, 66, 85], [70, 89, 81],
  425. [29, 64, 53], [88, 74, 1], [38, 67, 48], [42, 83, 72],
  426. [57, 1, 85], [34, 48, 62], [59, 72, 87], [19, 62, 74],
  427. [63, 87, 67], [17, 85, 83], [52, 75, 1], [39, 87, 49],
  428. [22, 51, 40], [55, 1, 66], [29, 49, 64], [30, 40, 69],
  429. [13, 64, 75], [82, 69, 87], [7, 66, 51], [90, 85, 1],
  430. [59, 69, 72], [70, 81, 71], [88, 1, 84], [73, 72, 83],
  431. [54, 71, 68], [5, 83, 85], [50, 68, 69], [3, 84, 81],
  432. [57, 66, 1], [30, 68, 40], [28, 62, 48], [52, 1, 74],
  433. [23, 40, 51], [38, 48, 86], [9, 51, 66], [80, 86, 68],
  434. [11, 74, 62], [55, 84, 1], [54, 86, 71], [35, 64, 49],
  435. [90, 1, 75], [41, 71, 81], [39, 49, 67], [15, 81, 84],
  436. [61, 67, 86], [21, 75, 64], [24, 53, 43], [50, 69, 0],
  437. [37, 85, 47], [31, 43, 75], [61, 0, 67], [27, 47, 58],
  438. [10, 67, 53], [8, 58, 69], [90, 75, 85], [45, 91, 78],
  439. [80, 68, 0], [36, 66, 46], [65, 78, 85], [63, 0, 87],
  440. [32, 46, 56], [20, 87, 91], [14, 56, 68], [57, 85, 66],
  441. [33, 58, 47], [61, 86, 0], [60, 84, 77], [37, 47, 66],
  442. [82, 0, 69], [44, 77, 89], [16, 69, 58], [18, 89, 86],
  443. [55, 66, 84], [26, 56, 46], [63, 67, 0], [31, 74, 43],
  444. [36, 46, 84], [50, 0, 68], [25, 43, 53], [6, 68, 56],
  445. [12, 53, 67], [88, 84, 74], [76, 89, 77], [82, 87, 0],
  446. [65, 75, 78], [60, 77, 74], [80, 0, 86], [79, 78, 91],
  447. [2, 86, 89], [4, 91, 87], [52, 74, 75], [21, 64, 78],
  448. [18, 86, 48], [23, 58, 40], [5, 78, 83], [28, 48, 53],
  449. [6, 40, 68], [25, 53, 64], [54, 68, 86], [33, 83, 58],
  450. [17, 83, 47], [12, 67, 49], [41, 56, 71], [9, 47, 51],
  451. [35, 49, 91], [2, 71, 86], [79, 91, 83], [38, 86, 67],
  452. [26, 51, 56], [7, 51, 46], [4, 87, 72], [34, 89, 48],
  453. [15, 46, 81], [42, 72, 58], [10, 48, 67], [27, 58, 51],
  454. [39, 67, 87], [76, 81, 89], [3, 81, 77], [8, 69, 40],
  455. [29, 53, 49], [19, 77, 62], [22, 40, 56], [20, 49, 87],
  456. [32, 56, 81], [59, 87, 69], [24, 62, 53], [11, 62, 43],
  457. [14, 68, 71], [73, 91, 72], [13, 43, 64], [70, 71, 89],
  458. [16, 72, 69], [44, 89, 62], [30, 69, 68], [45, 64, 91]]
  459. # Actual volume is : 51.405764746872634
  460. assert Abs(polytope_integrate(echidnahedron, 1) - 51.4057647468726) < 1e-12
  461. assert Abs(polytope_integrate(echidnahedron, expr) - 253.569603474519) <\
  462. 1e-12
  463. # Tests for many polynomials with maximum degree given(2D case).
  464. assert polytope_integrate(cube2, [x**2, y*z], max_degree=2) == \
  465. {y * z: 3125 / S(4), x ** 2: 3125 / S(3)}
  466. assert polytope_integrate(cube2, max_degree=2) == \
  467. {1: 125, x: 625 / S(2), x * z: 3125 / S(4), y: 625 / S(2),
  468. y * z: 3125 / S(4), z ** 2: 3125 / S(3), y ** 2: 3125 / S(3),
  469. z: 625 / S(2), x * y: 3125 / S(4), x ** 2: 3125 / S(3)}
  470. def test_point_sort():
  471. assert point_sort([Point(0, 0), Point(1, 0), Point(1, 1)]) == \
  472. [Point2D(1, 1), Point2D(1, 0), Point2D(0, 0)]
  473. fig6 = Polygon((0, 0), (1, 0), (1, 1))
  474. assert polytope_integrate(fig6, x*y) == Rational(-1, 8)
  475. assert polytope_integrate(fig6, x*y, clockwise = True) == Rational(1, 8)
  476. def test_polytopes_intersecting_sides():
  477. fig5 = Polygon(Point(-4.165, -0.832), Point(-3.668, 1.568),
  478. Point(-3.266, 1.279), Point(-1.090, -2.080),
  479. Point(3.313, -0.683), Point(3.033, -4.845),
  480. Point(-4.395, 4.840), Point(-1.007, -3.328))
  481. assert polytope_integrate(fig5, x**2 + x*y + y**2) ==\
  482. S(1633405224899363)/(24*10**12)
  483. fig6 = Polygon(Point(-3.018, -4.473), Point(-0.103, 2.378),
  484. Point(-1.605, -2.308), Point(4.516, -0.771),
  485. Point(4.203, 0.478))
  486. assert polytope_integrate(fig6, x**2 + x*y + y**2) ==\
  487. S(88161333955921)/(3*10**12)
  488. def test_max_degree():
  489. polygon = Polygon((0, 0), (0, 1), (1, 1), (1, 0))
  490. polys = [1, x, y, x*y, x**2*y, x*y**2]
  491. assert polytope_integrate(polygon, polys, max_degree=3) == \
  492. {1: 1, x: S.Half, y: S.Half, x*y: Rational(1, 4), x**2*y: Rational(1, 6), x*y**2: Rational(1, 6)}
  493. assert polytope_integrate(polygon, polys, max_degree=2) == \
  494. {1: 1, x: S.Half, y: S.Half, x*y: Rational(1, 4)}
  495. assert polytope_integrate(polygon, polys, max_degree=1) == \
  496. {1: 1, x: S.Half, y: S.Half}
  497. def test_main_integrate3d():
  498. cube = [[(0, 0, 0), (0, 0, 5), (0, 5, 0), (0, 5, 5), (5, 0, 0),\
  499. (5, 0, 5), (5, 5, 0), (5, 5, 5)],\
  500. [2, 6, 7, 3], [3, 7, 5, 1], [7, 6, 4, 5], [1, 5, 4, 0],\
  501. [3, 1, 0, 2], [0, 4, 6, 2]]
  502. vertices = cube[0]
  503. faces = cube[1:]
  504. hp_params = hyperplane_parameters(faces, vertices)
  505. assert main_integrate3d(1, faces, vertices, hp_params) == -125
  506. assert main_integrate3d(1, faces, vertices, hp_params, max_degree=1) == \
  507. {1: -125, y: Rational(-625, 2), z: Rational(-625, 2), x: Rational(-625, 2)}
  508. def test_main_integrate():
  509. triangle = Polygon((0, 3), (5, 3), (1, 1))
  510. facets = triangle.sides
  511. hp_params = hyperplane_parameters(triangle)
  512. assert main_integrate(x**2 + y**2, facets, hp_params) == Rational(325, 6)
  513. assert main_integrate(x**2 + y**2, facets, hp_params, max_degree=1) == \
  514. {0: 0, 1: 5, y: Rational(35, 3), x: 10}
  515. def test_polygon_integrate():
  516. cube = [[(0, 0, 0), (0, 0, 5), (0, 5, 0), (0, 5, 5), (5, 0, 0),\
  517. (5, 0, 5), (5, 5, 0), (5, 5, 5)],\
  518. [2, 6, 7, 3], [3, 7, 5, 1], [7, 6, 4, 5], [1, 5, 4, 0],\
  519. [3, 1, 0, 2], [0, 4, 6, 2]]
  520. facet = cube[1]
  521. facets = cube[1:]
  522. vertices = cube[0]
  523. assert polygon_integrate(facet, [(0, 1, 0), 5], 0, facets, vertices, 1, 0) == -25
  524. def test_distance_to_side():
  525. point = (0, 0, 0)
  526. assert distance_to_side(point, [(0, 0, 1), (0, 1, 0)], (1, 0, 0)) == -sqrt(2)/2
  527. def test_lineseg_integrate():
  528. polygon = [(0, 5, 0), (5, 5, 0), (5, 5, 5), (0, 5, 5)]
  529. line_seg = [(0, 5, 0), (5, 5, 0)]
  530. assert lineseg_integrate(polygon, 0, line_seg, 1, 0) == 5
  531. assert lineseg_integrate(polygon, 0, line_seg, 0, 0) == 0
  532. def test_integration_reduction():
  533. triangle = Polygon(Point(0, 3), Point(5, 3), Point(1, 1))
  534. facets = triangle.sides
  535. a, b = hyperplane_parameters(triangle)[0]
  536. assert integration_reduction(facets, 0, a, b, 1, (x, y), 0) == 5
  537. assert integration_reduction(facets, 0, a, b, 0, (x, y), 0) == 0
  538. def test_integration_reduction_dynamic():
  539. triangle = Polygon(Point(0, 3), Point(5, 3), Point(1, 1))
  540. facets = triangle.sides
  541. a, b = hyperplane_parameters(triangle)[0]
  542. x0 = facets[0].points[0]
  543. monomial_values = [[0, 0, 0, 0], [1, 0, 0, 5],\
  544. [y, 0, 1, 15], [x, 1, 0, None]]
  545. assert integration_reduction_dynamic(facets, 0, a, b, x, 1, (x, y), 1,\
  546. 0, 1, x0, monomial_values, 3) == Rational(25, 2)
  547. assert integration_reduction_dynamic(facets, 0, a, b, 0, 1, (x, y), 1,\
  548. 0, 1, x0, monomial_values, 3) == 0
  549. def test_is_vertex():
  550. assert is_vertex(2) is False
  551. assert is_vertex((2, 3)) is True
  552. assert is_vertex(Point(2, 3)) is True
  553. assert is_vertex((2, 3, 4)) is True
  554. assert is_vertex((2, 3, 4, 5)) is False
  555. def test_issue_19234():
  556. polygon = Polygon(Point(0, 0), Point(0, 1), Point(1, 1), Point(1, 0))
  557. polys = [ 1, x, y, x*y, x**2*y, x*y**2]
  558. assert polytope_integrate(polygon, polys) == \
  559. {1: 1, x: S.Half, y: S.Half, x*y: Rational(1, 4), x**2*y: Rational(1, 6), x*y**2: Rational(1, 6)}
  560. polys = [ 1, x, y, x*y, 3 + x**2*y, x + x*y**2]
  561. assert polytope_integrate(polygon, polys) == \
  562. {1: 1, x: S.Half, y: S.Half, x*y: Rational(1, 4), x**2*y + 3: Rational(19, 6), x*y**2 + x: Rational(2, 3)}