test_rootisolation.py 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823
  1. """Tests for real and complex root isolation and refinement algorithms. """
  2. from sympy.polys.rings import ring
  3. from sympy.polys.domains import ZZ, QQ, ZZ_I, EX
  4. from sympy.polys.polyerrors import DomainError, RefinementFailed, PolynomialError
  5. from sympy.polys.rootisolation import (
  6. dup_cauchy_upper_bound, dup_cauchy_lower_bound,
  7. dup_mignotte_sep_bound_squared,
  8. )
  9. from sympy.testing.pytest import raises
  10. def test_dup_sturm():
  11. R, x = ring("x", QQ)
  12. assert R.dup_sturm(5) == [1]
  13. assert R.dup_sturm(x) == [x, 1]
  14. f = x**3 - 2*x**2 + 3*x - 5
  15. assert R.dup_sturm(f) == [f, 3*x**2 - 4*x + 3, -QQ(10,9)*x + QQ(13,3), -QQ(3303,100)]
  16. def test_dup_cauchy_upper_bound():
  17. raises(PolynomialError, lambda: dup_cauchy_upper_bound([], QQ))
  18. raises(PolynomialError, lambda: dup_cauchy_upper_bound([QQ(1)], QQ))
  19. raises(DomainError, lambda: dup_cauchy_upper_bound([ZZ_I(1), ZZ_I(1)], ZZ_I))
  20. assert dup_cauchy_upper_bound([QQ(1), QQ(0), QQ(0)], QQ) == QQ.zero
  21. assert dup_cauchy_upper_bound([QQ(1), QQ(0), QQ(-2)], QQ) == QQ(3)
  22. def test_dup_cauchy_lower_bound():
  23. raises(PolynomialError, lambda: dup_cauchy_lower_bound([], QQ))
  24. raises(PolynomialError, lambda: dup_cauchy_lower_bound([QQ(1)], QQ))
  25. raises(PolynomialError, lambda: dup_cauchy_lower_bound([QQ(1), QQ(0), QQ(0)], QQ))
  26. raises(DomainError, lambda: dup_cauchy_lower_bound([ZZ_I(1), ZZ_I(1)], ZZ_I))
  27. assert dup_cauchy_lower_bound([QQ(1), QQ(0), QQ(-2)], QQ) == QQ(2, 3)
  28. def test_dup_mignotte_sep_bound_squared():
  29. raises(PolynomialError, lambda: dup_mignotte_sep_bound_squared([], QQ))
  30. raises(PolynomialError, lambda: dup_mignotte_sep_bound_squared([QQ(1)], QQ))
  31. assert dup_mignotte_sep_bound_squared([QQ(1), QQ(0), QQ(-2)], QQ) == QQ(3, 5)
  32. def test_dup_refine_real_root():
  33. R, x = ring("x", ZZ)
  34. f = x**2 - 2
  35. assert R.dup_refine_real_root(f, QQ(1), QQ(1), steps=1) == (QQ(1), QQ(1))
  36. assert R.dup_refine_real_root(f, QQ(1), QQ(1), steps=9) == (QQ(1), QQ(1))
  37. raises(ValueError, lambda: R.dup_refine_real_root(f, QQ(-2), QQ(2)))
  38. s, t = QQ(1, 1), QQ(2, 1)
  39. assert R.dup_refine_real_root(f, s, t, steps=0) == (QQ(1, 1), QQ(2, 1))
  40. assert R.dup_refine_real_root(f, s, t, steps=1) == (QQ(1, 1), QQ(3, 2))
  41. assert R.dup_refine_real_root(f, s, t, steps=2) == (QQ(4, 3), QQ(3, 2))
  42. assert R.dup_refine_real_root(f, s, t, steps=3) == (QQ(7, 5), QQ(3, 2))
  43. assert R.dup_refine_real_root(f, s, t, steps=4) == (QQ(7, 5), QQ(10, 7))
  44. s, t = QQ(1, 1), QQ(3, 2)
  45. assert R.dup_refine_real_root(f, s, t, steps=0) == (QQ(1, 1), QQ(3, 2))
  46. assert R.dup_refine_real_root(f, s, t, steps=1) == (QQ(4, 3), QQ(3, 2))
  47. assert R.dup_refine_real_root(f, s, t, steps=2) == (QQ(7, 5), QQ(3, 2))
  48. assert R.dup_refine_real_root(f, s, t, steps=3) == (QQ(7, 5), QQ(10, 7))
  49. assert R.dup_refine_real_root(f, s, t, steps=4) == (QQ(7, 5), QQ(17, 12))
  50. s, t = QQ(1, 1), QQ(5, 3)
  51. assert R.dup_refine_real_root(f, s, t, steps=0) == (QQ(1, 1), QQ(5, 3))
  52. assert R.dup_refine_real_root(f, s, t, steps=1) == (QQ(1, 1), QQ(3, 2))
  53. assert R.dup_refine_real_root(f, s, t, steps=2) == (QQ(7, 5), QQ(3, 2))
  54. assert R.dup_refine_real_root(f, s, t, steps=3) == (QQ(7, 5), QQ(13, 9))
  55. assert R.dup_refine_real_root(f, s, t, steps=4) == (QQ(7, 5), QQ(27, 19))
  56. s, t = QQ(-1, 1), QQ(-2, 1)
  57. assert R.dup_refine_real_root(f, s, t, steps=0) == (-QQ(2, 1), -QQ(1, 1))
  58. assert R.dup_refine_real_root(f, s, t, steps=1) == (-QQ(3, 2), -QQ(1, 1))
  59. assert R.dup_refine_real_root(f, s, t, steps=2) == (-QQ(3, 2), -QQ(4, 3))
  60. assert R.dup_refine_real_root(f, s, t, steps=3) == (-QQ(3, 2), -QQ(7, 5))
  61. assert R.dup_refine_real_root(f, s, t, steps=4) == (-QQ(10, 7), -QQ(7, 5))
  62. raises(RefinementFailed, lambda: R.dup_refine_real_root(f, QQ(0), QQ(1)))
  63. s, t, u, v, w = QQ(1), QQ(2), QQ(24, 17), QQ(17, 12), QQ(7, 5)
  64. assert R.dup_refine_real_root(f, s, t, eps=QQ(1, 100)) == (u, v)
  65. assert R.dup_refine_real_root(f, s, t, steps=6) == (u, v)
  66. assert R.dup_refine_real_root(f, s, t, eps=QQ(1, 100), steps=5) == (w, v)
  67. assert R.dup_refine_real_root(f, s, t, eps=QQ(1, 100), steps=6) == (u, v)
  68. assert R.dup_refine_real_root(f, s, t, eps=QQ(1, 100), steps=7) == (u, v)
  69. s, t, u, v = QQ(-2), QQ(-1), QQ(-3, 2), QQ(-4, 3)
  70. assert R.dup_refine_real_root(f, s, t, disjoint=QQ(-5)) == (s, t)
  71. assert R.dup_refine_real_root(f, s, t, disjoint=-v) == (s, t)
  72. assert R.dup_refine_real_root(f, s, t, disjoint=v) == (u, v)
  73. s, t, u, v = QQ(1), QQ(2), QQ(4, 3), QQ(3, 2)
  74. assert R.dup_refine_real_root(f, s, t, disjoint=QQ(5)) == (s, t)
  75. assert R.dup_refine_real_root(f, s, t, disjoint=-u) == (s, t)
  76. assert R.dup_refine_real_root(f, s, t, disjoint=u) == (u, v)
  77. def test_dup_isolate_real_roots_sqf():
  78. R, x = ring("x", ZZ)
  79. assert R.dup_isolate_real_roots_sqf(0) == []
  80. assert R.dup_isolate_real_roots_sqf(5) == []
  81. assert R.dup_isolate_real_roots_sqf(x**2 + x) == [(-1, -1), (0, 0)]
  82. assert R.dup_isolate_real_roots_sqf(x**2 - x) == [( 0, 0), (1, 1)]
  83. assert R.dup_isolate_real_roots_sqf(x**4 + x + 1) == []
  84. I = [(-2, -1), (1, 2)]
  85. assert R.dup_isolate_real_roots_sqf(x**2 - 2) == I
  86. assert R.dup_isolate_real_roots_sqf(-x**2 + 2) == I
  87. assert R.dup_isolate_real_roots_sqf(x - 1) == \
  88. [(1, 1)]
  89. assert R.dup_isolate_real_roots_sqf(x**2 - 3*x + 2) == \
  90. [(1, 1), (2, 2)]
  91. assert R.dup_isolate_real_roots_sqf(x**3 - 6*x**2 + 11*x - 6) == \
  92. [(1, 1), (2, 2), (3, 3)]
  93. assert R.dup_isolate_real_roots_sqf(x**4 - 10*x**3 + 35*x**2 - 50*x + 24) == \
  94. [(1, 1), (2, 2), (3, 3), (4, 4)]
  95. assert R.dup_isolate_real_roots_sqf(x**5 - 15*x**4 + 85*x**3 - 225*x**2 + 274*x - 120) == \
  96. [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]
  97. assert R.dup_isolate_real_roots_sqf(x - 10) == \
  98. [(10, 10)]
  99. assert R.dup_isolate_real_roots_sqf(x**2 - 30*x + 200) == \
  100. [(10, 10), (20, 20)]
  101. assert R.dup_isolate_real_roots_sqf(x**3 - 60*x**2 + 1100*x - 6000) == \
  102. [(10, 10), (20, 20), (30, 30)]
  103. assert R.dup_isolate_real_roots_sqf(x**4 - 100*x**3 + 3500*x**2 - 50000*x + 240000) == \
  104. [(10, 10), (20, 20), (30, 30), (40, 40)]
  105. assert R.dup_isolate_real_roots_sqf(x**5 - 150*x**4 + 8500*x**3 - 225000*x**2 + 2740000*x - 12000000) == \
  106. [(10, 10), (20, 20), (30, 30), (40, 40), (50, 50)]
  107. assert R.dup_isolate_real_roots_sqf(x + 1) == \
  108. [(-1, -1)]
  109. assert R.dup_isolate_real_roots_sqf(x**2 + 3*x + 2) == \
  110. [(-2, -2), (-1, -1)]
  111. assert R.dup_isolate_real_roots_sqf(x**3 + 6*x**2 + 11*x + 6) == \
  112. [(-3, -3), (-2, -2), (-1, -1)]
  113. assert R.dup_isolate_real_roots_sqf(x**4 + 10*x**3 + 35*x**2 + 50*x + 24) == \
  114. [(-4, -4), (-3, -3), (-2, -2), (-1, -1)]
  115. assert R.dup_isolate_real_roots_sqf(x**5 + 15*x**4 + 85*x**3 + 225*x**2 + 274*x + 120) == \
  116. [(-5, -5), (-4, -4), (-3, -3), (-2, -2), (-1, -1)]
  117. assert R.dup_isolate_real_roots_sqf(x + 10) == \
  118. [(-10, -10)]
  119. assert R.dup_isolate_real_roots_sqf(x**2 + 30*x + 200) == \
  120. [(-20, -20), (-10, -10)]
  121. assert R.dup_isolate_real_roots_sqf(x**3 + 60*x**2 + 1100*x + 6000) == \
  122. [(-30, -30), (-20, -20), (-10, -10)]
  123. assert R.dup_isolate_real_roots_sqf(x**4 + 100*x**3 + 3500*x**2 + 50000*x + 240000) == \
  124. [(-40, -40), (-30, -30), (-20, -20), (-10, -10)]
  125. assert R.dup_isolate_real_roots_sqf(x**5 + 150*x**4 + 8500*x**3 + 225000*x**2 + 2740000*x + 12000000) == \
  126. [(-50, -50), (-40, -40), (-30, -30), (-20, -20), (-10, -10)]
  127. assert R.dup_isolate_real_roots_sqf(x**2 - 5) == [(-3, -2), (2, 3)]
  128. assert R.dup_isolate_real_roots_sqf(x**3 - 5) == [(1, 2)]
  129. assert R.dup_isolate_real_roots_sqf(x**4 - 5) == [(-2, -1), (1, 2)]
  130. assert R.dup_isolate_real_roots_sqf(x**5 - 5) == [(1, 2)]
  131. assert R.dup_isolate_real_roots_sqf(x**6 - 5) == [(-2, -1), (1, 2)]
  132. assert R.dup_isolate_real_roots_sqf(x**7 - 5) == [(1, 2)]
  133. assert R.dup_isolate_real_roots_sqf(x**8 - 5) == [(-2, -1), (1, 2)]
  134. assert R.dup_isolate_real_roots_sqf(x**9 - 5) == [(1, 2)]
  135. assert R.dup_isolate_real_roots_sqf(x**2 - 1) == \
  136. [(-1, -1), (1, 1)]
  137. assert R.dup_isolate_real_roots_sqf(x**3 + 2*x**2 - x - 2) == \
  138. [(-2, -2), (-1, -1), (1, 1)]
  139. assert R.dup_isolate_real_roots_sqf(x**4 - 5*x**2 + 4) == \
  140. [(-2, -2), (-1, -1), (1, 1), (2, 2)]
  141. assert R.dup_isolate_real_roots_sqf(x**5 + 3*x**4 - 5*x**3 - 15*x**2 + 4*x + 12) == \
  142. [(-3, -3), (-2, -2), (-1, -1), (1, 1), (2, 2)]
  143. assert R.dup_isolate_real_roots_sqf(x**6 - 14*x**4 + 49*x**2 - 36) == \
  144. [(-3, -3), (-2, -2), (-1, -1), (1, 1), (2, 2), (3, 3)]
  145. assert R.dup_isolate_real_roots_sqf(2*x**7 + x**6 - 28*x**5 - 14*x**4 + 98*x**3 + 49*x**2 - 72*x - 36) == \
  146. [(-3, -3), (-2, -2), (-1, -1), (-1, 0), (1, 1), (2, 2), (3, 3)]
  147. assert R.dup_isolate_real_roots_sqf(4*x**8 - 57*x**6 + 210*x**4 - 193*x**2 + 36) == \
  148. [(-3, -3), (-2, -2), (-1, -1), (-1, 0), (0, 1), (1, 1), (2, 2), (3, 3)]
  149. f = 9*x**2 - 2
  150. assert R.dup_isolate_real_roots_sqf(f) == \
  151. [(-1, 0), (0, 1)]
  152. assert R.dup_isolate_real_roots_sqf(f, eps=QQ(1, 10)) == \
  153. [(QQ(-1, 2), QQ(-3, 7)), (QQ(3, 7), QQ(1, 2))]
  154. assert R.dup_isolate_real_roots_sqf(f, eps=QQ(1, 100)) == \
  155. [(QQ(-9, 19), QQ(-8, 17)), (QQ(8, 17), QQ(9, 19))]
  156. assert R.dup_isolate_real_roots_sqf(f, eps=QQ(1, 1000)) == \
  157. [(QQ(-33, 70), QQ(-8, 17)), (QQ(8, 17), QQ(33, 70))]
  158. assert R.dup_isolate_real_roots_sqf(f, eps=QQ(1, 10000)) == \
  159. [(QQ(-33, 70), QQ(-107, 227)), (QQ(107, 227), QQ(33, 70))]
  160. assert R.dup_isolate_real_roots_sqf(f, eps=QQ(1, 100000)) == \
  161. [(QQ(-305, 647), QQ(-272, 577)), (QQ(272, 577), QQ(305, 647))]
  162. assert R.dup_isolate_real_roots_sqf(f, eps=QQ(1, 1000000)) == \
  163. [(QQ(-1121, 2378), QQ(-272, 577)), (QQ(272, 577), QQ(1121, 2378))]
  164. f = 200100012*x**5 - 700390052*x**4 + 700490079*x**3 - 200240054*x**2 + 40017*x - 2
  165. assert R.dup_isolate_real_roots_sqf(f) == \
  166. [(QQ(0), QQ(1, 10002)), (QQ(1, 10002), QQ(1, 10002)),
  167. (QQ(1, 2), QQ(1, 2)), (QQ(1), QQ(1)), (QQ(2), QQ(2))]
  168. assert R.dup_isolate_real_roots_sqf(f, eps=QQ(1, 100000)) == \
  169. [(QQ(1, 10003), QQ(1, 10003)), (QQ(1, 10002), QQ(1, 10002)),
  170. (QQ(1, 2), QQ(1, 2)), (QQ(1), QQ(1)), (QQ(2), QQ(2))]
  171. a, b, c, d = 10000090000001, 2000100003, 10000300007, 10000005000008
  172. f = 20001600074001600021*x**4 \
  173. + 1700135866278935491773999857*x**3 \
  174. - 2000179008931031182161141026995283662899200197*x**2 \
  175. - 800027600594323913802305066986600025*x \
  176. + 100000950000540000725000008
  177. assert R.dup_isolate_real_roots_sqf(f) == \
  178. [(-a, -a), (-1, 0), (0, 1), (d, d)]
  179. assert R.dup_isolate_real_roots_sqf(f, eps=QQ(1, 100000000000)) == \
  180. [(-QQ(a), -QQ(a)), (-QQ(1, b), -QQ(1, b)), (QQ(1, c), QQ(1, c)), (QQ(d), QQ(d))]
  181. (u, v), B, C, (s, t) = R.dup_isolate_real_roots_sqf(f, fast=True)
  182. assert u < -a < v and B == (-QQ(1), QQ(0)) and C == (QQ(0), QQ(1)) and s < d < t
  183. assert R.dup_isolate_real_roots_sqf(f, fast=True, eps=QQ(1, 100000000000000000000000000000)) == \
  184. [(-QQ(a), -QQ(a)), (-QQ(1, b), -QQ(1, b)), (QQ(1, c), QQ(1, c)), (QQ(d), QQ(d))]
  185. f = -10*x**4 + 8*x**3 + 80*x**2 - 32*x - 160
  186. assert R.dup_isolate_real_roots_sqf(f) == \
  187. [(-2, -2), (-2, -1), (2, 2), (2, 3)]
  188. assert R.dup_isolate_real_roots_sqf(f, eps=QQ(1, 100)) == \
  189. [(-QQ(2), -QQ(2)), (-QQ(23, 14), -QQ(18, 11)), (QQ(2), QQ(2)), (QQ(39, 16), QQ(22, 9))]
  190. f = x - 1
  191. assert R.dup_isolate_real_roots_sqf(f, inf=2) == []
  192. assert R.dup_isolate_real_roots_sqf(f, sup=0) == []
  193. assert R.dup_isolate_real_roots_sqf(f) == [(1, 1)]
  194. assert R.dup_isolate_real_roots_sqf(f, inf=1) == [(1, 1)]
  195. assert R.dup_isolate_real_roots_sqf(f, sup=1) == [(1, 1)]
  196. assert R.dup_isolate_real_roots_sqf(f, inf=1, sup=1) == [(1, 1)]
  197. f = x**2 - 2
  198. assert R.dup_isolate_real_roots_sqf(f, inf=QQ(7, 4)) == []
  199. assert R.dup_isolate_real_roots_sqf(f, inf=QQ(7, 5)) == [(QQ(7, 5), QQ(3, 2))]
  200. assert R.dup_isolate_real_roots_sqf(f, sup=QQ(7, 5)) == [(-2, -1)]
  201. assert R.dup_isolate_real_roots_sqf(f, sup=QQ(7, 4)) == [(-2, -1), (1, QQ(3, 2))]
  202. assert R.dup_isolate_real_roots_sqf(f, sup=-QQ(7, 4)) == []
  203. assert R.dup_isolate_real_roots_sqf(f, sup=-QQ(7, 5)) == [(-QQ(3, 2), -QQ(7, 5))]
  204. assert R.dup_isolate_real_roots_sqf(f, inf=-QQ(7, 5)) == [(1, 2)]
  205. assert R.dup_isolate_real_roots_sqf(f, inf=-QQ(7, 4)) == [(-QQ(3, 2), -1), (1, 2)]
  206. I = [(-2, -1), (1, 2)]
  207. assert R.dup_isolate_real_roots_sqf(f, inf=-2) == I
  208. assert R.dup_isolate_real_roots_sqf(f, sup=+2) == I
  209. assert R.dup_isolate_real_roots_sqf(f, inf=-2, sup=2) == I
  210. R, x = ring("x", QQ)
  211. f = QQ(8, 5)*x**2 - QQ(87374, 3855)*x - QQ(17, 771)
  212. assert R.dup_isolate_real_roots_sqf(f) == [(-1, 0), (14, 15)]
  213. R, x = ring("x", EX)
  214. raises(DomainError, lambda: R.dup_isolate_real_roots_sqf(x + 3))
  215. def test_dup_isolate_real_roots():
  216. R, x = ring("x", ZZ)
  217. assert R.dup_isolate_real_roots(0) == []
  218. assert R.dup_isolate_real_roots(3) == []
  219. assert R.dup_isolate_real_roots(5*x) == [((0, 0), 1)]
  220. assert R.dup_isolate_real_roots(7*x**4) == [((0, 0), 4)]
  221. assert R.dup_isolate_real_roots(x**2 + x) == [((-1, -1), 1), ((0, 0), 1)]
  222. assert R.dup_isolate_real_roots(x**2 - x) == [((0, 0), 1), ((1, 1), 1)]
  223. assert R.dup_isolate_real_roots(x**4 + x + 1) == []
  224. I = [((-2, -1), 1), ((1, 2), 1)]
  225. assert R.dup_isolate_real_roots(x**2 - 2) == I
  226. assert R.dup_isolate_real_roots(-x**2 + 2) == I
  227. f = 16*x**14 - 96*x**13 + 24*x**12 + 936*x**11 - 1599*x**10 - 2880*x**9 + 9196*x**8 \
  228. + 552*x**7 - 21831*x**6 + 13968*x**5 + 21690*x**4 - 26784*x**3 - 2916*x**2 + 15552*x - 5832
  229. g = R.dup_sqf_part(f)
  230. assert R.dup_isolate_real_roots(f) == \
  231. [((-QQ(2), -QQ(3, 2)), 2), ((-QQ(3, 2), -QQ(1, 1)), 3), ((QQ(1), QQ(3, 2)), 3),
  232. ((QQ(3, 2), QQ(3, 2)), 4), ((QQ(5, 3), QQ(2)), 2)]
  233. assert R.dup_isolate_real_roots_sqf(g) == \
  234. [(-QQ(2), -QQ(3, 2)), (-QQ(3, 2), -QQ(1, 1)), (QQ(1), QQ(3, 2)),
  235. (QQ(3, 2), QQ(3, 2)), (QQ(3, 2), QQ(2))]
  236. assert R.dup_isolate_real_roots(g) == \
  237. [((-QQ(2), -QQ(3, 2)), 1), ((-QQ(3, 2), -QQ(1, 1)), 1), ((QQ(1), QQ(3, 2)), 1),
  238. ((QQ(3, 2), QQ(3, 2)), 1), ((QQ(3, 2), QQ(2)), 1)]
  239. f = x - 1
  240. assert R.dup_isolate_real_roots(f, inf=2) == []
  241. assert R.dup_isolate_real_roots(f, sup=0) == []
  242. assert R.dup_isolate_real_roots(f) == [((1, 1), 1)]
  243. assert R.dup_isolate_real_roots(f, inf=1) == [((1, 1), 1)]
  244. assert R.dup_isolate_real_roots(f, sup=1) == [((1, 1), 1)]
  245. assert R.dup_isolate_real_roots(f, inf=1, sup=1) == [((1, 1), 1)]
  246. f = x**4 - 4*x**2 + 4
  247. assert R.dup_isolate_real_roots(f, inf=QQ(7, 4)) == []
  248. assert R.dup_isolate_real_roots(f, inf=QQ(7, 5)) == [((QQ(7, 5), QQ(3, 2)), 2)]
  249. assert R.dup_isolate_real_roots(f, sup=QQ(7, 5)) == [((-2, -1), 2)]
  250. assert R.dup_isolate_real_roots(f, sup=QQ(7, 4)) == [((-2, -1), 2), ((1, QQ(3, 2)), 2)]
  251. assert R.dup_isolate_real_roots(f, sup=-QQ(7, 4)) == []
  252. assert R.dup_isolate_real_roots(f, sup=-QQ(7, 5)) == [((-QQ(3, 2), -QQ(7, 5)), 2)]
  253. assert R.dup_isolate_real_roots(f, inf=-QQ(7, 5)) == [((1, 2), 2)]
  254. assert R.dup_isolate_real_roots(f, inf=-QQ(7, 4)) == [((-QQ(3, 2), -1), 2), ((1, 2), 2)]
  255. I = [((-2, -1), 2), ((1, 2), 2)]
  256. assert R.dup_isolate_real_roots(f, inf=-2) == I
  257. assert R.dup_isolate_real_roots(f, sup=+2) == I
  258. assert R.dup_isolate_real_roots(f, inf=-2, sup=2) == I
  259. f = x**11 - 3*x**10 - x**9 + 11*x**8 - 8*x**7 - 8*x**6 + 12*x**5 - 4*x**4
  260. assert R.dup_isolate_real_roots(f, basis=False) == \
  261. [((-2, -1), 2), ((0, 0), 4), ((1, 1), 3), ((1, 2), 2)]
  262. assert R.dup_isolate_real_roots(f, basis=True) == \
  263. [((-2, -1), 2, [1, 0, -2]), ((0, 0), 4, [1, 0]), ((1, 1), 3, [1, -1]), ((1, 2), 2, [1, 0, -2])]
  264. f = (x**45 - 45*x**44 + 990*x**43 - 1)
  265. g = (x**46 - 15180*x**43 + 9366819*x**40 - 53524680*x**39 + 260932815*x**38 - 1101716330*x**37 + 4076350421*x**36 - 13340783196*x**35 + 38910617655*x**34 - 101766230790*x**33 + 239877544005*x**32 - 511738760544*x**31 + 991493848554*x**30 - 1749695026860*x**29 + 2818953098830*x**28 - 4154246671960*x**27 + 5608233007146*x**26 - 6943526580276*x**25 + 7890371113950*x**24 - 8233430727600*x**23 + 7890371113950*x**22 - 6943526580276*x**21 + 5608233007146*x**20 - 4154246671960*x**19 + 2818953098830*x**18 - 1749695026860*x**17 + 991493848554*x**16 - 511738760544*x**15 + 239877544005*x**14 - 101766230790*x**13 + 38910617655*x**12 - 13340783196*x**11 + 4076350421*x**10 - 1101716330*x**9 + 260932815*x**8 - 53524680*x**7 + 9366819*x**6 - 1370754*x**5 + 163185*x**4 - 15180*x**3 + 1035*x**2 - 47*x + 1)
  266. assert R.dup_isolate_real_roots(f*g) == \
  267. [((0, QQ(1, 2)), 1), ((QQ(2, 3), QQ(3, 4)), 1), ((QQ(3, 4), 1), 1), ((6, 7), 1), ((24, 25), 1)]
  268. R, x = ring("x", EX)
  269. raises(DomainError, lambda: R.dup_isolate_real_roots(x + 3))
  270. def test_dup_isolate_real_roots_list():
  271. R, x = ring("x", ZZ)
  272. assert R.dup_isolate_real_roots_list([x**2 + x, x]) == \
  273. [((-1, -1), {0: 1}), ((0, 0), {0: 1, 1: 1})]
  274. assert R.dup_isolate_real_roots_list([x**2 - x, x]) == \
  275. [((0, 0), {0: 1, 1: 1}), ((1, 1), {0: 1})]
  276. assert R.dup_isolate_real_roots_list([x + 1, x + 2, x - 1, x + 1, x - 1, x - 1]) == \
  277. [((-QQ(2), -QQ(2)), {1: 1}), ((-QQ(1), -QQ(1)), {0: 1, 3: 1}), ((QQ(1), QQ(1)), {2: 1, 4: 1, 5: 1})]
  278. assert R.dup_isolate_real_roots_list([x + 1, x + 2, x - 1, x + 1, x - 1, x + 2]) == \
  279. [((-QQ(2), -QQ(2)), {1: 1, 5: 1}), ((-QQ(1), -QQ(1)), {0: 1, 3: 1}), ((QQ(1), QQ(1)), {2: 1, 4: 1})]
  280. f, g = x**4 - 4*x**2 + 4, x - 1
  281. assert R.dup_isolate_real_roots_list([f, g], inf=QQ(7, 4)) == []
  282. assert R.dup_isolate_real_roots_list([f, g], inf=QQ(7, 5)) == \
  283. [((QQ(7, 5), QQ(3, 2)), {0: 2})]
  284. assert R.dup_isolate_real_roots_list([f, g], sup=QQ(7, 5)) == \
  285. [((-2, -1), {0: 2}), ((1, 1), {1: 1})]
  286. assert R.dup_isolate_real_roots_list([f, g], sup=QQ(7, 4)) == \
  287. [((-2, -1), {0: 2}), ((1, 1), {1: 1}), ((1, QQ(3, 2)), {0: 2})]
  288. assert R.dup_isolate_real_roots_list([f, g], sup=-QQ(7, 4)) == []
  289. assert R.dup_isolate_real_roots_list([f, g], sup=-QQ(7, 5)) == \
  290. [((-QQ(3, 2), -QQ(7, 5)), {0: 2})]
  291. assert R.dup_isolate_real_roots_list([f, g], inf=-QQ(7, 5)) == \
  292. [((1, 1), {1: 1}), ((1, 2), {0: 2})]
  293. assert R.dup_isolate_real_roots_list([f, g], inf=-QQ(7, 4)) == \
  294. [((-QQ(3, 2), -1), {0: 2}), ((1, 1), {1: 1}), ((1, 2), {0: 2})]
  295. f, g = 2*x**2 - 1, x**2 - 2
  296. assert R.dup_isolate_real_roots_list([f, g]) == \
  297. [((-QQ(2), -QQ(1)), {1: 1}), ((-QQ(1), QQ(0)), {0: 1}),
  298. ((QQ(0), QQ(1)), {0: 1}), ((QQ(1), QQ(2)), {1: 1})]
  299. assert R.dup_isolate_real_roots_list([f, g], strict=True) == \
  300. [((-QQ(3, 2), -QQ(4, 3)), {1: 1}), ((-QQ(1), -QQ(2, 3)), {0: 1}),
  301. ((QQ(2, 3), QQ(1)), {0: 1}), ((QQ(4, 3), QQ(3, 2)), {1: 1})]
  302. f, g = x**2 - 2, x**3 - x**2 - 2*x + 2
  303. assert R.dup_isolate_real_roots_list([f, g]) == \
  304. [((-QQ(2), -QQ(1)), {1: 1, 0: 1}), ((QQ(1), QQ(1)), {1: 1}), ((QQ(1), QQ(2)), {1: 1, 0: 1})]
  305. f, g = x**3 - 2*x, x**5 - x**4 - 2*x**3 + 2*x**2
  306. assert R.dup_isolate_real_roots_list([f, g]) == \
  307. [((-QQ(2), -QQ(1)), {1: 1, 0: 1}), ((QQ(0), QQ(0)), {0: 1, 1: 2}),
  308. ((QQ(1), QQ(1)), {1: 1}), ((QQ(1), QQ(2)), {1: 1, 0: 1})]
  309. f, g = x**9 - 3*x**8 - x**7 + 11*x**6 - 8*x**5 - 8*x**4 + 12*x**3 - 4*x**2, x**5 - 2*x**4 + 3*x**3 - 4*x**2 + 2*x
  310. assert R.dup_isolate_real_roots_list([f, g], basis=False) == \
  311. [((-2, -1), {0: 2}), ((0, 0), {0: 2, 1: 1}), ((1, 1), {0: 3, 1: 2}), ((1, 2), {0: 2})]
  312. assert R.dup_isolate_real_roots_list([f, g], basis=True) == \
  313. [((-2, -1), {0: 2}, [1, 0, -2]), ((0, 0), {0: 2, 1: 1}, [1, 0]),
  314. ((1, 1), {0: 3, 1: 2}, [1, -1]), ((1, 2), {0: 2}, [1, 0, -2])]
  315. R, x = ring("x", EX)
  316. raises(DomainError, lambda: R.dup_isolate_real_roots_list([x + 3]))
  317. def test_dup_isolate_real_roots_list_QQ():
  318. R, x = ring("x", ZZ)
  319. f = x**5 - 200
  320. g = x**5 - 201
  321. assert R.dup_isolate_real_roots_list([f, g]) == \
  322. [((QQ(75, 26), QQ(101, 35)), {0: 1}), ((QQ(309, 107), QQ(26, 9)), {1: 1})]
  323. R, x = ring("x", QQ)
  324. f = -QQ(1, 200)*x**5 + 1
  325. g = -QQ(1, 201)*x**5 + 1
  326. assert R.dup_isolate_real_roots_list([f, g]) == \
  327. [((QQ(75, 26), QQ(101, 35)), {0: 1}), ((QQ(309, 107), QQ(26, 9)), {1: 1})]
  328. def test_dup_count_real_roots():
  329. R, x = ring("x", ZZ)
  330. assert R.dup_count_real_roots(0) == 0
  331. assert R.dup_count_real_roots(7) == 0
  332. f = x - 1
  333. assert R.dup_count_real_roots(f) == 1
  334. assert R.dup_count_real_roots(f, inf=1) == 1
  335. assert R.dup_count_real_roots(f, sup=0) == 0
  336. assert R.dup_count_real_roots(f, sup=1) == 1
  337. assert R.dup_count_real_roots(f, inf=0, sup=1) == 1
  338. assert R.dup_count_real_roots(f, inf=0, sup=2) == 1
  339. assert R.dup_count_real_roots(f, inf=1, sup=2) == 1
  340. f = x**2 - 2
  341. assert R.dup_count_real_roots(f) == 2
  342. assert R.dup_count_real_roots(f, sup=0) == 1
  343. assert R.dup_count_real_roots(f, inf=-1, sup=1) == 0
  344. # parameters for test_dup_count_complex_roots_n(): n = 1..8
  345. a, b = (-QQ(1), -QQ(1)), (QQ(1), QQ(1))
  346. c, d = ( QQ(0), QQ(0)), (QQ(1), QQ(1))
  347. def test_dup_count_complex_roots_1():
  348. R, x = ring("x", ZZ)
  349. # z-1
  350. f = x - 1
  351. assert R.dup_count_complex_roots(f, a, b) == 1
  352. assert R.dup_count_complex_roots(f, c, d) == 1
  353. # z+1
  354. f = x + 1
  355. assert R.dup_count_complex_roots(f, a, b) == 1
  356. assert R.dup_count_complex_roots(f, c, d) == 0
  357. def test_dup_count_complex_roots_2():
  358. R, x = ring("x", ZZ)
  359. # (z-1)*(z)
  360. f = x**2 - x
  361. assert R.dup_count_complex_roots(f, a, b) == 2
  362. assert R.dup_count_complex_roots(f, c, d) == 2
  363. # (z-1)*(-z)
  364. f = -x**2 + x
  365. assert R.dup_count_complex_roots(f, a, b) == 2
  366. assert R.dup_count_complex_roots(f, c, d) == 2
  367. # (z+1)*(z)
  368. f = x**2 + x
  369. assert R.dup_count_complex_roots(f, a, b) == 2
  370. assert R.dup_count_complex_roots(f, c, d) == 1
  371. # (z+1)*(-z)
  372. f = -x**2 - x
  373. assert R.dup_count_complex_roots(f, a, b) == 2
  374. assert R.dup_count_complex_roots(f, c, d) == 1
  375. def test_dup_count_complex_roots_3():
  376. R, x = ring("x", ZZ)
  377. # (z-1)*(z+1)
  378. f = x**2 - 1
  379. assert R.dup_count_complex_roots(f, a, b) == 2
  380. assert R.dup_count_complex_roots(f, c, d) == 1
  381. # (z-1)*(z+1)*(z)
  382. f = x**3 - x
  383. assert R.dup_count_complex_roots(f, a, b) == 3
  384. assert R.dup_count_complex_roots(f, c, d) == 2
  385. # (z-1)*(z+1)*(-z)
  386. f = -x**3 + x
  387. assert R.dup_count_complex_roots(f, a, b) == 3
  388. assert R.dup_count_complex_roots(f, c, d) == 2
  389. def test_dup_count_complex_roots_4():
  390. R, x = ring("x", ZZ)
  391. # (z-I)*(z+I)
  392. f = x**2 + 1
  393. assert R.dup_count_complex_roots(f, a, b) == 2
  394. assert R.dup_count_complex_roots(f, c, d) == 1
  395. # (z-I)*(z+I)*(z)
  396. f = x**3 + x
  397. assert R.dup_count_complex_roots(f, a, b) == 3
  398. assert R.dup_count_complex_roots(f, c, d) == 2
  399. # (z-I)*(z+I)*(-z)
  400. f = -x**3 - x
  401. assert R.dup_count_complex_roots(f, a, b) == 3
  402. assert R.dup_count_complex_roots(f, c, d) == 2
  403. # (z-I)*(z+I)*(z-1)
  404. f = x**3 - x**2 + x - 1
  405. assert R.dup_count_complex_roots(f, a, b) == 3
  406. assert R.dup_count_complex_roots(f, c, d) == 2
  407. # (z-I)*(z+I)*(z-1)*(z)
  408. f = x**4 - x**3 + x**2 - x
  409. assert R.dup_count_complex_roots(f, a, b) == 4
  410. assert R.dup_count_complex_roots(f, c, d) == 3
  411. # (z-I)*(z+I)*(z-1)*(-z)
  412. f = -x**4 + x**3 - x**2 + x
  413. assert R.dup_count_complex_roots(f, a, b) == 4
  414. assert R.dup_count_complex_roots(f, c, d) == 3
  415. # (z-I)*(z+I)*(z-1)*(z+1)
  416. f = x**4 - 1
  417. assert R.dup_count_complex_roots(f, a, b) == 4
  418. assert R.dup_count_complex_roots(f, c, d) == 2
  419. # (z-I)*(z+I)*(z-1)*(z+1)*(z)
  420. f = x**5 - x
  421. assert R.dup_count_complex_roots(f, a, b) == 5
  422. assert R.dup_count_complex_roots(f, c, d) == 3
  423. # (z-I)*(z+I)*(z-1)*(z+1)*(-z)
  424. f = -x**5 + x
  425. assert R.dup_count_complex_roots(f, a, b) == 5
  426. assert R.dup_count_complex_roots(f, c, d) == 3
  427. def test_dup_count_complex_roots_5():
  428. R, x = ring("x", ZZ)
  429. # (z-I+1)*(z+I+1)
  430. f = x**2 + 2*x + 2
  431. assert R.dup_count_complex_roots(f, a, b) == 2
  432. assert R.dup_count_complex_roots(f, c, d) == 0
  433. # (z-I+1)*(z+I+1)*(z-1)
  434. f = x**3 + x**2 - 2
  435. assert R.dup_count_complex_roots(f, a, b) == 3
  436. assert R.dup_count_complex_roots(f, c, d) == 1
  437. # (z-I+1)*(z+I+1)*(z-1)*z
  438. f = x**4 + x**3 - 2*x
  439. assert R.dup_count_complex_roots(f, a, b) == 4
  440. assert R.dup_count_complex_roots(f, c, d) == 2
  441. # (z-I+1)*(z+I+1)*(z+1)
  442. f = x**3 + 3*x**2 + 4*x + 2
  443. assert R.dup_count_complex_roots(f, a, b) == 3
  444. assert R.dup_count_complex_roots(f, c, d) == 0
  445. # (z-I+1)*(z+I+1)*(z+1)*z
  446. f = x**4 + 3*x**3 + 4*x**2 + 2*x
  447. assert R.dup_count_complex_roots(f, a, b) == 4
  448. assert R.dup_count_complex_roots(f, c, d) == 1
  449. # (z-I+1)*(z+I+1)*(z-1)*(z+1)
  450. f = x**4 + 2*x**3 + x**2 - 2*x - 2
  451. assert R.dup_count_complex_roots(f, a, b) == 4
  452. assert R.dup_count_complex_roots(f, c, d) == 1
  453. # (z-I+1)*(z+I+1)*(z-1)*(z+1)*z
  454. f = x**5 + 2*x**4 + x**3 - 2*x**2 - 2*x
  455. assert R.dup_count_complex_roots(f, a, b) == 5
  456. assert R.dup_count_complex_roots(f, c, d) == 2
  457. def test_dup_count_complex_roots_6():
  458. R, x = ring("x", ZZ)
  459. # (z-I-1)*(z+I-1)
  460. f = x**2 - 2*x + 2
  461. assert R.dup_count_complex_roots(f, a, b) == 2
  462. assert R.dup_count_complex_roots(f, c, d) == 1
  463. # (z-I-1)*(z+I-1)*(z-1)
  464. f = x**3 - 3*x**2 + 4*x - 2
  465. assert R.dup_count_complex_roots(f, a, b) == 3
  466. assert R.dup_count_complex_roots(f, c, d) == 2
  467. # (z-I-1)*(z+I-1)*(z-1)*z
  468. f = x**4 - 3*x**3 + 4*x**2 - 2*x
  469. assert R.dup_count_complex_roots(f, a, b) == 4
  470. assert R.dup_count_complex_roots(f, c, d) == 3
  471. # (z-I-1)*(z+I-1)*(z+1)
  472. f = x**3 - x**2 + 2
  473. assert R.dup_count_complex_roots(f, a, b) == 3
  474. assert R.dup_count_complex_roots(f, c, d) == 1
  475. # (z-I-1)*(z+I-1)*(z+1)*z
  476. f = x**4 - x**3 + 2*x
  477. assert R.dup_count_complex_roots(f, a, b) == 4
  478. assert R.dup_count_complex_roots(f, c, d) == 2
  479. # (z-I-1)*(z+I-1)*(z-1)*(z+1)
  480. f = x**4 - 2*x**3 + x**2 + 2*x - 2
  481. assert R.dup_count_complex_roots(f, a, b) == 4
  482. assert R.dup_count_complex_roots(f, c, d) == 2
  483. # (z-I-1)*(z+I-1)*(z-1)*(z+1)*z
  484. f = x**5 - 2*x**4 + x**3 + 2*x**2 - 2*x
  485. assert R.dup_count_complex_roots(f, a, b) == 5
  486. assert R.dup_count_complex_roots(f, c, d) == 3
  487. def test_dup_count_complex_roots_7():
  488. R, x = ring("x", ZZ)
  489. # (z-I-1)*(z+I-1)*(z-I+1)*(z+I+1)
  490. f = x**4 + 4
  491. assert R.dup_count_complex_roots(f, a, b) == 4
  492. assert R.dup_count_complex_roots(f, c, d) == 1
  493. # (z-I-1)*(z+I-1)*(z-I+1)*(z+I+1)*(z-2)
  494. f = x**5 - 2*x**4 + 4*x - 8
  495. assert R.dup_count_complex_roots(f, a, b) == 4
  496. assert R.dup_count_complex_roots(f, c, d) == 1
  497. # (z-I-1)*(z+I-1)*(z-I+1)*(z+I+1)*(z**2-2)
  498. f = x**6 - 2*x**4 + 4*x**2 - 8
  499. assert R.dup_count_complex_roots(f, a, b) == 4
  500. assert R.dup_count_complex_roots(f, c, d) == 1
  501. # (z-I-1)*(z+I-1)*(z-I+1)*(z+I+1)*(z-1)
  502. f = x**5 - x**4 + 4*x - 4
  503. assert R.dup_count_complex_roots(f, a, b) == 5
  504. assert R.dup_count_complex_roots(f, c, d) == 2
  505. # (z-I-1)*(z+I-1)*(z-I+1)*(z+I+1)*(z-1)*z
  506. f = x**6 - x**5 + 4*x**2 - 4*x
  507. assert R.dup_count_complex_roots(f, a, b) == 6
  508. assert R.dup_count_complex_roots(f, c, d) == 3
  509. # (z-I-1)*(z+I-1)*(z-I+1)*(z+I+1)*(z+1)
  510. f = x**5 + x**4 + 4*x + 4
  511. assert R.dup_count_complex_roots(f, a, b) == 5
  512. assert R.dup_count_complex_roots(f, c, d) == 1
  513. # (z-I-1)*(z+I-1)*(z-I+1)*(z+I+1)*(z+1)*z
  514. f = x**6 + x**5 + 4*x**2 + 4*x
  515. assert R.dup_count_complex_roots(f, a, b) == 6
  516. assert R.dup_count_complex_roots(f, c, d) == 2
  517. # (z-I-1)*(z+I-1)*(z-I+1)*(z+I+1)*(z-1)*(z+1)
  518. f = x**6 - x**4 + 4*x**2 - 4
  519. assert R.dup_count_complex_roots(f, a, b) == 6
  520. assert R.dup_count_complex_roots(f, c, d) == 2
  521. # (z-I-1)*(z+I-1)*(z-I+1)*(z+I+1)*(z-1)*(z+1)*z
  522. f = x**7 - x**5 + 4*x**3 - 4*x
  523. assert R.dup_count_complex_roots(f, a, b) == 7
  524. assert R.dup_count_complex_roots(f, c, d) == 3
  525. # (z-I-1)*(z+I-1)*(z-I+1)*(z+I+1)*(z-1)*(z+1)*(z-I)*(z+I)
  526. f = x**8 + 3*x**4 - 4
  527. assert R.dup_count_complex_roots(f, a, b) == 8
  528. assert R.dup_count_complex_roots(f, c, d) == 3
  529. def test_dup_count_complex_roots_8():
  530. R, x = ring("x", ZZ)
  531. # (z-I-1)*(z+I-1)*(z-I+1)*(z+I+1)*(z-1)*(z+1)*(z-I)*(z+I)*z
  532. f = x**9 + 3*x**5 - 4*x
  533. assert R.dup_count_complex_roots(f, a, b) == 9
  534. assert R.dup_count_complex_roots(f, c, d) == 4
  535. # (z-I-1)*(z+I-1)*(z-I+1)*(z+I+1)*(z-1)*(z+1)*(z-I)*(z+I)*(z**2-2)*z
  536. f = x**11 - 2*x**9 + 3*x**7 - 6*x**5 - 4*x**3 + 8*x
  537. assert R.dup_count_complex_roots(f, a, b) == 9
  538. assert R.dup_count_complex_roots(f, c, d) == 4
  539. def test_dup_count_complex_roots_implicit():
  540. R, x = ring("x", ZZ)
  541. # z*(z-1)*(z+1)*(z-I)*(z+I)
  542. f = x**5 - x
  543. assert R.dup_count_complex_roots(f) == 5
  544. assert R.dup_count_complex_roots(f, sup=(0, 0)) == 3
  545. assert R.dup_count_complex_roots(f, inf=(0, 0)) == 3
  546. def test_dup_count_complex_roots_exclude():
  547. R, x = ring("x", ZZ)
  548. # z*(z-1)*(z+1)*(z-I)*(z+I)
  549. f = x**5 - x
  550. a, b = (-QQ(1), QQ(0)), (QQ(1), QQ(1))
  551. assert R.dup_count_complex_roots(f, a, b) == 4
  552. assert R.dup_count_complex_roots(f, a, b, exclude=['S']) == 3
  553. assert R.dup_count_complex_roots(f, a, b, exclude=['N']) == 3
  554. assert R.dup_count_complex_roots(f, a, b, exclude=['S', 'N']) == 2
  555. assert R.dup_count_complex_roots(f, a, b, exclude=['E']) == 4
  556. assert R.dup_count_complex_roots(f, a, b, exclude=['W']) == 4
  557. assert R.dup_count_complex_roots(f, a, b, exclude=['E', 'W']) == 4
  558. assert R.dup_count_complex_roots(f, a, b, exclude=['N', 'S', 'E', 'W']) == 2
  559. assert R.dup_count_complex_roots(f, a, b, exclude=['SW']) == 3
  560. assert R.dup_count_complex_roots(f, a, b, exclude=['SE']) == 3
  561. assert R.dup_count_complex_roots(f, a, b, exclude=['SW', 'SE']) == 2
  562. assert R.dup_count_complex_roots(f, a, b, exclude=['SW', 'SE', 'S']) == 1
  563. assert R.dup_count_complex_roots(f, a, b, exclude=['SW', 'SE', 'S', 'N']) == 0
  564. a, b = (QQ(0), QQ(0)), (QQ(1), QQ(1))
  565. assert R.dup_count_complex_roots(f, a, b, exclude=True) == 1
  566. def test_dup_isolate_complex_roots_sqf():
  567. R, x = ring("x", ZZ)
  568. f = x**2 - 2*x + 3
  569. assert R.dup_isolate_complex_roots_sqf(f) == \
  570. [((0, -6), (6, 0)), ((0, 0), (6, 6))]
  571. assert [ r.as_tuple() for r in R.dup_isolate_complex_roots_sqf(f, blackbox=True) ] == \
  572. [((0, -6), (6, 0)), ((0, 0), (6, 6))]
  573. assert R.dup_isolate_complex_roots_sqf(f, eps=QQ(1, 10)) == \
  574. [((QQ(15, 16), -QQ(3, 2)), (QQ(33, 32), -QQ(45, 32))),
  575. ((QQ(15, 16), QQ(45, 32)), (QQ(33, 32), QQ(3, 2)))]
  576. assert R.dup_isolate_complex_roots_sqf(f, eps=QQ(1, 100)) == \
  577. [((QQ(255, 256), -QQ(363, 256)), (QQ(513, 512), -QQ(723, 512))),
  578. ((QQ(255, 256), QQ(723, 512)), (QQ(513, 512), QQ(363, 256)))]
  579. f = 7*x**4 - 19*x**3 + 20*x**2 + 17*x + 20
  580. assert R.dup_isolate_complex_roots_sqf(f) == \
  581. [((-QQ(40, 7), -QQ(40, 7)), (0, 0)), ((-QQ(40, 7), 0), (0, QQ(40, 7))),
  582. ((0, -QQ(40, 7)), (QQ(40, 7), 0)), ((0, 0), (QQ(40, 7), QQ(40, 7)))]
  583. def test_dup_isolate_all_roots_sqf():
  584. R, x = ring("x", ZZ)
  585. f = 4*x**4 - x**3 + 2*x**2 + 5*x
  586. assert R.dup_isolate_all_roots_sqf(f) == \
  587. ([(-1, 0), (0, 0)],
  588. [((0, -QQ(5, 2)), (QQ(5, 2), 0)), ((0, 0), (QQ(5, 2), QQ(5, 2)))])
  589. assert R.dup_isolate_all_roots_sqf(f, eps=QQ(1, 10)) == \
  590. ([(QQ(-7, 8), QQ(-6, 7)), (0, 0)],
  591. [((QQ(35, 64), -QQ(35, 32)), (QQ(5, 8), -QQ(65, 64))), ((QQ(35, 64), QQ(65, 64)), (QQ(5, 8), QQ(35, 32)))])
  592. def test_dup_isolate_all_roots():
  593. R, x = ring("x", ZZ)
  594. f = 4*x**4 - x**3 + 2*x**2 + 5*x
  595. assert R.dup_isolate_all_roots(f) == \
  596. ([((-1, 0), 1), ((0, 0), 1)],
  597. [(((0, -QQ(5, 2)), (QQ(5, 2), 0)), 1),
  598. (((0, 0), (QQ(5, 2), QQ(5, 2))), 1)])
  599. assert R.dup_isolate_all_roots(f, eps=QQ(1, 10)) == \
  600. ([((QQ(-7, 8), QQ(-6, 7)), 1), ((0, 0), 1)],
  601. [(((QQ(35, 64), -QQ(35, 32)), (QQ(5, 8), -QQ(65, 64))), 1),
  602. (((QQ(35, 64), QQ(65, 64)), (QQ(5, 8), QQ(35, 32))), 1)])
  603. f = x**5 + x**4 - 2*x**3 - 2*x**2 + x + 1
  604. raises(NotImplementedError, lambda: R.dup_isolate_all_roots(f))