图片解析应用
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.

603 lines
35 KiB

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