m2m模型翻译
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.

253 lines
9.3 KiB

6 months ago
  1. from sympy.core.function import (Function, Lambda, expand)
  2. from sympy.core.numbers import (I, Rational)
  3. from sympy.core.relational import Eq
  4. from sympy.core.singleton import S
  5. from sympy.core.symbol import (Symbol, symbols)
  6. from sympy.functions.combinatorial.factorials import (rf, binomial, factorial)
  7. from sympy.functions.elementary.complexes import Abs
  8. from sympy.functions.elementary.miscellaneous import sqrt
  9. from sympy.functions.elementary.trigonometric import (cos, sin)
  10. from sympy.polys.polytools import factor
  11. from sympy.solvers.recurr import rsolve, rsolve_hyper, rsolve_poly, rsolve_ratio
  12. from sympy.testing.pytest import raises, slow
  13. from sympy.abc import a, b
  14. y = Function('y')
  15. n, k = symbols('n,k', integer=True)
  16. C0, C1, C2 = symbols('C0,C1,C2')
  17. def test_rsolve_poly():
  18. assert rsolve_poly([-1, -1, 1], 0, n) == 0
  19. assert rsolve_poly([-1, -1, 1], 1, n) == -1
  20. assert rsolve_poly([-1, n + 1], n, n) == 1
  21. assert rsolve_poly([-1, 1], n, n) == C0 + (n**2 - n)/2
  22. assert rsolve_poly([-n - 1, n], 1, n) == C1*n - 1
  23. assert rsolve_poly([-4*n - 2, 1], 4*n + 1, n) == -1
  24. assert rsolve_poly([-1, 1], n**5 + n**3, n) == \
  25. C0 - n**3 / 2 - n**5 / 2 + n**2 / 6 + n**6 / 6 + 2*n**4 / 3
  26. def test_rsolve_ratio():
  27. solution = rsolve_ratio([-2*n**3 + n**2 + 2*n - 1, 2*n**3 + n**2 - 6*n,
  28. -2*n**3 - 11*n**2 - 18*n - 9, 2*n**3 + 13*n**2 + 22*n + 8], 0, n)
  29. assert solution in [
  30. C1*((-2*n + 3)/(n**2 - 1))/3,
  31. (S.Half)*(C1*(-3 + 2*n)/(-1 + n**2)),
  32. (S.Half)*(C1*( 3 - 2*n)/( 1 - n**2)),
  33. (S.Half)*(C2*(-3 + 2*n)/(-1 + n**2)),
  34. (S.Half)*(C2*( 3 - 2*n)/( 1 - n**2)),
  35. ]
  36. def test_rsolve_hyper():
  37. assert rsolve_hyper([-1, -1, 1], 0, n) in [
  38. C0*(S.Half - S.Half*sqrt(5))**n + C1*(S.Half + S.Half*sqrt(5))**n,
  39. C1*(S.Half - S.Half*sqrt(5))**n + C0*(S.Half + S.Half*sqrt(5))**n,
  40. ]
  41. assert rsolve_hyper([n**2 - 2, -2*n - 1, 1], 0, n) in [
  42. C0*rf(sqrt(2), n) + C1*rf(-sqrt(2), n),
  43. C1*rf(sqrt(2), n) + C0*rf(-sqrt(2), n),
  44. ]
  45. assert rsolve_hyper([n**2 - k, -2*n - 1, 1], 0, n) in [
  46. C0*rf(sqrt(k), n) + C1*rf(-sqrt(k), n),
  47. C1*rf(sqrt(k), n) + C0*rf(-sqrt(k), n),
  48. ]
  49. assert rsolve_hyper(
  50. [2*n*(n + 1), -n**2 - 3*n + 2, n - 1], 0, n) == C1*factorial(n) + C0*2**n
  51. assert rsolve_hyper(
  52. [n + 2, -(2*n + 3)*(17*n**2 + 51*n + 39), n + 1], 0, n) == None
  53. assert rsolve_hyper([-n - 1, -1, 1], 0, n) == None
  54. assert rsolve_hyper([-1, 1], n, n).expand() == C0 + n**2/2 - n/2
  55. assert rsolve_hyper([-1, 1], 1 + n, n).expand() == C0 + n**2/2 + n/2
  56. assert rsolve_hyper([-1, 1], 3*(n + n**2), n).expand() == C0 + n**3 - n
  57. assert rsolve_hyper([-a, 1],0,n).expand() == C0*a**n
  58. assert rsolve_hyper([-a, 0, 1], 0, n).expand() == (-1)**n*C1*a**(n/2) + C0*a**(n/2)
  59. assert rsolve_hyper([1, 1, 1], 0, n).expand() == \
  60. C0*(Rational(-1, 2) - sqrt(3)*I/2)**n + C1*(Rational(-1, 2) + sqrt(3)*I/2)**n
  61. assert rsolve_hyper([1, -2*n/a - 2/a, 1], 0, n) is None
  62. def recurrence_term(c, f):
  63. """Compute RHS of recurrence in f(n) with coefficients in c."""
  64. return sum(c[i]*f.subs(n, n + i) for i in range(len(c)))
  65. def test_rsolve_bulk():
  66. """Some bulk-generated tests."""
  67. funcs = [ n, n + 1, n**2, n**3, n**4, n + n**2, 27*n + 52*n**2 - 3*
  68. n**3 + 12*n**4 - 52*n**5 ]
  69. coeffs = [ [-2, 1], [-2, -1, 1], [-1, 1, 1, -1, 1], [-n, 1], [n**2 -
  70. n + 12, 1] ]
  71. for p in funcs:
  72. # compute difference
  73. for c in coeffs:
  74. q = recurrence_term(c, p)
  75. if p.is_polynomial(n):
  76. assert rsolve_poly(c, q, n) == p
  77. # See issue 3956:
  78. #if p.is_hypergeometric(n):
  79. # assert rsolve_hyper(c, q, n) == p
  80. def test_rsolve():
  81. f = y(n + 2) - y(n + 1) - y(n)
  82. h = sqrt(5)*(S.Half + S.Half*sqrt(5))**n \
  83. - sqrt(5)*(S.Half - S.Half*sqrt(5))**n
  84. assert rsolve(f, y(n)) in [
  85. C0*(S.Half - S.Half*sqrt(5))**n + C1*(S.Half + S.Half*sqrt(5))**n,
  86. C1*(S.Half - S.Half*sqrt(5))**n + C0*(S.Half + S.Half*sqrt(5))**n,
  87. ]
  88. assert rsolve(f, y(n), [0, 5]) == h
  89. assert rsolve(f, y(n), {0: 0, 1: 5}) == h
  90. assert rsolve(f, y(n), {y(0): 0, y(1): 5}) == h
  91. assert rsolve(y(n) - y(n - 1) - y(n - 2), y(n), [0, 5]) == h
  92. assert rsolve(Eq(y(n), y(n - 1) + y(n - 2)), y(n), [0, 5]) == h
  93. assert f.subs(y, Lambda(k, rsolve(f, y(n)).subs(n, k))).simplify() == 0
  94. f = (n - 1)*y(n + 2) - (n**2 + 3*n - 2)*y(n + 1) + 2*n*(n + 1)*y(n)
  95. g = C1*factorial(n) + C0*2**n
  96. h = -3*factorial(n) + 3*2**n
  97. assert rsolve(f, y(n)) == g
  98. assert rsolve(f, y(n), []) == g
  99. assert rsolve(f, y(n), {}) == g
  100. assert rsolve(f, y(n), [0, 3]) == h
  101. assert rsolve(f, y(n), {0: 0, 1: 3}) == h
  102. assert rsolve(f, y(n), {y(0): 0, y(1): 3}) == h
  103. assert f.subs(y, Lambda(k, rsolve(f, y(n)).subs(n, k))).simplify() == 0
  104. f = y(n) - y(n - 1) - 2
  105. assert rsolve(f, y(n), {y(0): 0}) == 2*n
  106. assert rsolve(f, y(n), {y(0): 1}) == 2*n + 1
  107. assert rsolve(f, y(n), {y(0): 0, y(1): 1}) is None
  108. assert f.subs(y, Lambda(k, rsolve(f, y(n)).subs(n, k))).simplify() == 0
  109. f = 3*y(n - 1) - y(n) - 1
  110. assert rsolve(f, y(n), {y(0): 0}) == -3**n/2 + S.Half
  111. assert rsolve(f, y(n), {y(0): 1}) == 3**n/2 + S.Half
  112. assert rsolve(f, y(n), {y(0): 2}) == 3*3**n/2 + S.Half
  113. assert f.subs(y, Lambda(k, rsolve(f, y(n)).subs(n, k))).simplify() == 0
  114. f = y(n) - 1/n*y(n - 1)
  115. assert rsolve(f, y(n)) == C0/factorial(n)
  116. assert f.subs(y, Lambda(k, rsolve(f, y(n)).subs(n, k))).simplify() == 0
  117. f = y(n) - 1/n*y(n - 1) - 1
  118. assert rsolve(f, y(n)) is None
  119. f = 2*y(n - 1) + (1 - n)*y(n)/n
  120. assert rsolve(f, y(n), {y(1): 1}) == 2**(n - 1)*n
  121. assert rsolve(f, y(n), {y(1): 2}) == 2**(n - 1)*n*2
  122. assert rsolve(f, y(n), {y(1): 3}) == 2**(n - 1)*n*3
  123. assert f.subs(y, Lambda(k, rsolve(f, y(n)).subs(n, k))).simplify() == 0
  124. f = (n - 1)*(n - 2)*y(n + 2) - (n + 1)*(n + 2)*y(n)
  125. assert rsolve(f, y(n), {y(3): 6, y(4): 24}) == n*(n - 1)*(n - 2)
  126. assert rsolve(
  127. f, y(n), {y(3): 6, y(4): -24}) == -n*(n - 1)*(n - 2)*(-1)**(n)
  128. assert f.subs(y, Lambda(k, rsolve(f, y(n)).subs(n, k))).simplify() == 0
  129. assert rsolve(Eq(y(n + 1), a*y(n)), y(n), {y(1): a}).simplify() == a**n
  130. assert rsolve(y(n) - a*y(n-2),y(n), \
  131. {y(1): sqrt(a)*(a + b), y(2): a*(a - b)}).simplify() == \
  132. a**(n/2)*(-(-1)**n*b + a)
  133. f = (-16*n**2 + 32*n - 12)*y(n - 1) + (4*n**2 - 12*n + 9)*y(n)
  134. yn = rsolve(f, y(n), {y(1): binomial(2*n + 1, 3)})
  135. sol = 2**(2*n)*n*(2*n - 1)**2*(2*n + 1)/12
  136. assert factor(expand(yn, func=True)) == sol
  137. sol = rsolve(y(n) + a*(y(n + 1) + y(n - 1))/2, y(n))
  138. Y = lambda i: sol.subs(n, i)
  139. assert (Y(n) + a*(Y(n + 1) + Y(n - 1))/2).expand().cancel() == 0
  140. assert rsolve((k + 1)*y(k), y(k)) is None
  141. assert (rsolve((k + 1)*y(k) + (k + 3)*y(k + 1) + (k + 5)*y(k + 2), y(k))
  142. is None)
  143. assert rsolve(y(n) + y(n + 1) + 2**n + 3**n, y(n)) == (-1)**n*C0 - 2**n/3 - 3**n/4
  144. def test_rsolve_raises():
  145. x = Function('x')
  146. raises(ValueError, lambda: rsolve(y(n) - y(k + 1), y(n)))
  147. raises(ValueError, lambda: rsolve(y(n) - y(n + 1), x(n)))
  148. raises(ValueError, lambda: rsolve(y(n) - x(n + 1), y(n)))
  149. raises(ValueError, lambda: rsolve(y(n) - sqrt(n)*y(n + 1), y(n)))
  150. raises(ValueError, lambda: rsolve(y(n) - y(n + 1), y(n), {x(0): 0}))
  151. raises(ValueError, lambda: rsolve(y(n) + y(n + 1) + 2**n + cos(n), y(n)))
  152. def test_issue_6844():
  153. f = y(n + 2) - y(n + 1) + y(n)/4
  154. assert rsolve(f, y(n)) == 2**(-n)*(C0 + C1*n)
  155. assert rsolve(f, y(n), {y(0): 0, y(1): 1}) == 2*2**(-n)*n
  156. def test_issue_18751():
  157. r = Symbol('r', positive=True)
  158. theta = Symbol('theta', real=True)
  159. f = y(n) - 2 * r * cos(theta) * y(n - 1) + r**2 * y(n - 2)
  160. assert rsolve(f, y(n)) == \
  161. C0*(r*(cos(theta) - I*Abs(sin(theta))))**n + C1*(r*(cos(theta) + I*Abs(sin(theta))))**n
  162. def test_constant_naming():
  163. #issue 8697
  164. assert rsolve(y(n+3) - y(n+2) - y(n+1) + y(n), y(n)) == (-1)**n*C0+C1+C2*n
  165. assert rsolve(y(n+3)+3*y(n+2)+3*y(n+1)+y(n), y(n)).expand() == C0*(-1)**n + (-1)**n*C1*n + (-1)**n*C2*n**2
  166. assert rsolve(y(n) - 2*y(n - 3) + 5*y(n - 2) - 4*y(n - 1),y(n),[1,3,8]) == 3*2**n - n - 2
  167. #issue 19630
  168. assert rsolve(y(n+3) - 3*y(n+1) + 2*y(n), y(n), {y(1):0, y(2):8, y(3):-2}) == (-2)**n + 2*n
  169. @slow
  170. def test_issue_15751():
  171. f = y(n) + 21*y(n + 1) - 273*y(n + 2) - 1092*y(n + 3) + 1820*y(n + 4) + 1092*y(n + 5) - 273*y(n + 6) - 21*y(n + 7) + y(n + 8)
  172. assert rsolve(f, y(n)) is not None
  173. def test_issue_17990():
  174. f = -10*y(n) + 4*y(n + 1) + 6*y(n + 2) + 46*y(n + 3)
  175. sol = rsolve(f, y(n))
  176. expected = C0*((86*18**(S(1)/3)/69 + (-12 + (-1 + sqrt(3)*I)*(290412 +
  177. 3036*sqrt(9165))**(S(1)/3))*(1 - sqrt(3)*I)*(24201 + 253*sqrt(9165))**
  178. (S(1)/3)/276)/((1 - sqrt(3)*I)*(24201 + 253*sqrt(9165))**(S(1)/3))
  179. )**n + C1*((86*18**(S(1)/3)/69 + (-12 + (-1 - sqrt(3)*I)*(290412 + 3036
  180. *sqrt(9165))**(S(1)/3))*(1 + sqrt(3)*I)*(24201 + 253*sqrt(9165))**
  181. (S(1)/3)/276)/((1 + sqrt(3)*I)*(24201 + 253*sqrt(9165))**(S(1)/3))
  182. )**n + C2*(-43*18**(S(1)/3)/(69*(24201 + 253*sqrt(9165))**(S(1)/3)) -
  183. S(1)/23 + (290412 + 3036*sqrt(9165))**(S(1)/3)/138)**n
  184. assert sol == expected
  185. e = sol.subs({C0: 1, C1: 1, C2: 1, n: 1}).evalf()
  186. assert abs(e + 0.130434782608696) < 1e-13