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.

1071 lines
46 KiB

6 months ago
  1. from sympy.core.function import (Derivative, Function, Subs, diff)
  2. from sympy.core.numbers import (I, Rational, pi)
  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.elementary.complexes import (im, re)
  7. from sympy.functions.elementary.exponential import (exp, log)
  8. from sympy.functions.elementary.hyperbolic import acosh
  9. from sympy.functions.elementary.miscellaneous import sqrt
  10. from sympy.functions.elementary.trigonometric import (atan2, cos, sin, tan)
  11. from sympy.integrals.integrals import Integral
  12. from sympy.polys.polytools import Poly
  13. from sympy.series.order import O
  14. from sympy.simplify.radsimp import collect
  15. from sympy.solvers.ode import (classify_ode,
  16. homogeneous_order, dsolve)
  17. from sympy.solvers.ode.subscheck import checkodesol
  18. from sympy.solvers.ode.ode import (classify_sysode,
  19. constant_renumber, constantsimp, get_numbered_constants, solve_ics)
  20. from sympy.solvers.ode.nonhomogeneous import _undetermined_coefficients_match
  21. from sympy.solvers.ode.single import LinearCoefficients
  22. from sympy.solvers.deutils import ode_order
  23. from sympy.testing.pytest import XFAIL, raises, slow
  24. from sympy.utilities.misc import filldedent
  25. C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10 = symbols('C0:11')
  26. u, x, y, z = symbols('u,x:z', real=True)
  27. f = Function('f')
  28. g = Function('g')
  29. h = Function('h')
  30. # Note: Examples which were specifically testing Single ODE solver are moved to test_single.py
  31. # and all the system of ode examples are moved to test_systems.py
  32. # Note: the tests below may fail (but still be correct) if ODE solver,
  33. # the integral engine, solve(), or even simplify() changes. Also, in
  34. # differently formatted solutions, the arbitrary constants might not be
  35. # equal. Using specific hints in tests can help to avoid this.
  36. # Tests of order higher than 1 should run the solutions through
  37. # constant_renumber because it will normalize it (constant_renumber causes
  38. # dsolve() to return different results on different machines)
  39. def test_get_numbered_constants():
  40. with raises(ValueError):
  41. get_numbered_constants(None)
  42. def test_dsolve_all_hint():
  43. eq = f(x).diff(x)
  44. output = dsolve(eq, hint='all')
  45. # Match the Dummy variables:
  46. sol1 = output['separable_Integral']
  47. _y = sol1.lhs.args[1][0]
  48. sol1 = output['1st_homogeneous_coeff_subs_dep_div_indep_Integral']
  49. _u1 = sol1.rhs.args[1].args[1][0]
  50. expected = {'Bernoulli_Integral': Eq(f(x), C1 + Integral(0, x)),
  51. '1st_homogeneous_coeff_best': Eq(f(x), C1),
  52. 'Bernoulli': Eq(f(x), C1),
  53. 'nth_algebraic': Eq(f(x), C1),
  54. 'nth_linear_euler_eq_homogeneous': Eq(f(x), C1),
  55. 'nth_linear_constant_coeff_homogeneous': Eq(f(x), C1),
  56. 'separable': Eq(f(x), C1),
  57. '1st_homogeneous_coeff_subs_indep_div_dep': Eq(f(x), C1),
  58. 'nth_algebraic_Integral': Eq(f(x), C1),
  59. '1st_linear': Eq(f(x), C1),
  60. '1st_linear_Integral': Eq(f(x), C1 + Integral(0, x)),
  61. '1st_exact': Eq(f(x), C1),
  62. '1st_exact_Integral': Eq(Subs(Integral(0, x) + Integral(1, _y), _y, f(x)), C1),
  63. 'lie_group': Eq(f(x), C1),
  64. '1st_homogeneous_coeff_subs_dep_div_indep': Eq(f(x), C1),
  65. '1st_homogeneous_coeff_subs_dep_div_indep_Integral': Eq(log(x), C1 + Integral(-1/_u1, (_u1, f(x)/x))),
  66. '1st_power_series': Eq(f(x), C1),
  67. 'separable_Integral': Eq(Integral(1, (_y, f(x))), C1 + Integral(0, x)),
  68. '1st_homogeneous_coeff_subs_indep_div_dep_Integral': Eq(f(x), C1),
  69. 'best': Eq(f(x), C1),
  70. 'best_hint': 'nth_algebraic',
  71. 'default': 'nth_algebraic',
  72. 'order': 1}
  73. assert output == expected
  74. assert dsolve(eq, hint='best') == Eq(f(x), C1)
  75. def test_dsolve_ics():
  76. # Maybe this should just use one of the solutions instead of raising...
  77. with raises(NotImplementedError):
  78. dsolve(f(x).diff(x) - sqrt(f(x)), ics={f(1):1})
  79. @slow
  80. def test_dsolve_options():
  81. eq = x*f(x).diff(x) + f(x)
  82. a = dsolve(eq, hint='all')
  83. b = dsolve(eq, hint='all', simplify=False)
  84. c = dsolve(eq, hint='all_Integral')
  85. keys = ['1st_exact', '1st_exact_Integral', '1st_homogeneous_coeff_best',
  86. '1st_homogeneous_coeff_subs_dep_div_indep',
  87. '1st_homogeneous_coeff_subs_dep_div_indep_Integral',
  88. '1st_homogeneous_coeff_subs_indep_div_dep',
  89. '1st_homogeneous_coeff_subs_indep_div_dep_Integral', '1st_linear',
  90. '1st_linear_Integral', 'Bernoulli', 'Bernoulli_Integral',
  91. 'almost_linear', 'almost_linear_Integral', 'best', 'best_hint',
  92. 'default', 'factorable', 'lie_group',
  93. 'nth_linear_euler_eq_homogeneous', 'order',
  94. 'separable', 'separable_Integral']
  95. Integral_keys = ['1st_exact_Integral',
  96. '1st_homogeneous_coeff_subs_dep_div_indep_Integral',
  97. '1st_homogeneous_coeff_subs_indep_div_dep_Integral', '1st_linear_Integral',
  98. 'Bernoulli_Integral', 'almost_linear_Integral', 'best', 'best_hint', 'default',
  99. 'factorable', 'nth_linear_euler_eq_homogeneous',
  100. 'order', 'separable_Integral']
  101. assert sorted(a.keys()) == keys
  102. assert a['order'] == ode_order(eq, f(x))
  103. assert a['best'] == Eq(f(x), C1/x)
  104. assert dsolve(eq, hint='best') == Eq(f(x), C1/x)
  105. assert a['default'] == 'factorable'
  106. assert a['best_hint'] == 'factorable'
  107. assert not a['1st_exact'].has(Integral)
  108. assert not a['separable'].has(Integral)
  109. assert not a['1st_homogeneous_coeff_best'].has(Integral)
  110. assert not a['1st_homogeneous_coeff_subs_dep_div_indep'].has(Integral)
  111. assert not a['1st_homogeneous_coeff_subs_indep_div_dep'].has(Integral)
  112. assert not a['1st_linear'].has(Integral)
  113. assert a['1st_linear_Integral'].has(Integral)
  114. assert a['1st_exact_Integral'].has(Integral)
  115. assert a['1st_homogeneous_coeff_subs_dep_div_indep_Integral'].has(Integral)
  116. assert a['1st_homogeneous_coeff_subs_indep_div_dep_Integral'].has(Integral)
  117. assert a['separable_Integral'].has(Integral)
  118. assert sorted(b.keys()) == keys
  119. assert b['order'] == ode_order(eq, f(x))
  120. assert b['best'] == Eq(f(x), C1/x)
  121. assert dsolve(eq, hint='best', simplify=False) == Eq(f(x), C1/x)
  122. assert b['default'] == 'factorable'
  123. assert b['best_hint'] == 'factorable'
  124. assert a['separable'] != b['separable']
  125. assert a['1st_homogeneous_coeff_subs_dep_div_indep'] != \
  126. b['1st_homogeneous_coeff_subs_dep_div_indep']
  127. assert a['1st_homogeneous_coeff_subs_indep_div_dep'] != \
  128. b['1st_homogeneous_coeff_subs_indep_div_dep']
  129. assert not b['1st_exact'].has(Integral)
  130. assert not b['separable'].has(Integral)
  131. assert not b['1st_homogeneous_coeff_best'].has(Integral)
  132. assert not b['1st_homogeneous_coeff_subs_dep_div_indep'].has(Integral)
  133. assert not b['1st_homogeneous_coeff_subs_indep_div_dep'].has(Integral)
  134. assert not b['1st_linear'].has(Integral)
  135. assert b['1st_linear_Integral'].has(Integral)
  136. assert b['1st_exact_Integral'].has(Integral)
  137. assert b['1st_homogeneous_coeff_subs_dep_div_indep_Integral'].has(Integral)
  138. assert b['1st_homogeneous_coeff_subs_indep_div_dep_Integral'].has(Integral)
  139. assert b['separable_Integral'].has(Integral)
  140. assert sorted(c.keys()) == Integral_keys
  141. raises(ValueError, lambda: dsolve(eq, hint='notarealhint'))
  142. raises(ValueError, lambda: dsolve(eq, hint='Liouville'))
  143. assert dsolve(f(x).diff(x) - 1/f(x)**2, hint='all')['best'] == \
  144. dsolve(f(x).diff(x) - 1/f(x)**2, hint='best')
  145. assert dsolve(f(x) + f(x).diff(x) + sin(x).diff(x) + 1, f(x),
  146. hint="1st_linear_Integral") == \
  147. Eq(f(x), (C1 + Integral((-sin(x).diff(x) - 1)*
  148. exp(Integral(1, x)), x))*exp(-Integral(1, x)))
  149. def test_classify_ode():
  150. assert classify_ode(f(x).diff(x, 2), f(x)) == \
  151. (
  152. 'nth_algebraic',
  153. 'nth_linear_constant_coeff_homogeneous',
  154. 'nth_linear_euler_eq_homogeneous',
  155. 'Liouville',
  156. '2nd_power_series_ordinary',
  157. 'nth_algebraic_Integral',
  158. 'Liouville_Integral',
  159. )
  160. assert classify_ode(f(x), f(x)) == ('nth_algebraic', 'nth_algebraic_Integral')
  161. assert classify_ode(Eq(f(x).diff(x), 0), f(x)) == (
  162. 'nth_algebraic',
  163. 'separable',
  164. '1st_exact',
  165. '1st_linear',
  166. 'Bernoulli',
  167. '1st_homogeneous_coeff_best',
  168. '1st_homogeneous_coeff_subs_indep_div_dep',
  169. '1st_homogeneous_coeff_subs_dep_div_indep',
  170. '1st_power_series', 'lie_group',
  171. 'nth_linear_constant_coeff_homogeneous',
  172. 'nth_linear_euler_eq_homogeneous',
  173. 'nth_algebraic_Integral',
  174. 'separable_Integral',
  175. '1st_exact_Integral',
  176. '1st_linear_Integral',
  177. 'Bernoulli_Integral',
  178. '1st_homogeneous_coeff_subs_indep_div_dep_Integral',
  179. '1st_homogeneous_coeff_subs_dep_div_indep_Integral')
  180. assert classify_ode(f(x).diff(x)**2, f(x)) == ('factorable',
  181. 'nth_algebraic',
  182. 'separable',
  183. '1st_exact',
  184. '1st_linear',
  185. 'Bernoulli',
  186. '1st_homogeneous_coeff_best',
  187. '1st_homogeneous_coeff_subs_indep_div_dep',
  188. '1st_homogeneous_coeff_subs_dep_div_indep',
  189. '1st_power_series',
  190. 'lie_group',
  191. 'nth_linear_euler_eq_homogeneous',
  192. 'nth_algebraic_Integral',
  193. 'separable_Integral',
  194. '1st_exact_Integral',
  195. '1st_linear_Integral',
  196. 'Bernoulli_Integral',
  197. '1st_homogeneous_coeff_subs_indep_div_dep_Integral',
  198. '1st_homogeneous_coeff_subs_dep_div_indep_Integral')
  199. # issue 4749: f(x) should be cleared from highest derivative before classifying
  200. a = classify_ode(Eq(f(x).diff(x) + f(x), x), f(x))
  201. b = classify_ode(f(x).diff(x)*f(x) + f(x)*f(x) - x*f(x), f(x))
  202. c = classify_ode(f(x).diff(x)/f(x) + f(x)/f(x) - x/f(x), f(x))
  203. assert a == ('1st_exact',
  204. '1st_linear',
  205. 'Bernoulli',
  206. 'almost_linear',
  207. '1st_power_series', "lie_group",
  208. 'nth_linear_constant_coeff_undetermined_coefficients',
  209. 'nth_linear_constant_coeff_variation_of_parameters',
  210. '1st_exact_Integral',
  211. '1st_linear_Integral',
  212. 'Bernoulli_Integral',
  213. 'almost_linear_Integral',
  214. 'nth_linear_constant_coeff_variation_of_parameters_Integral')
  215. assert b == ('factorable',
  216. '1st_linear',
  217. 'Bernoulli',
  218. '1st_power_series',
  219. 'lie_group',
  220. 'nth_linear_constant_coeff_undetermined_coefficients',
  221. 'nth_linear_constant_coeff_variation_of_parameters',
  222. '1st_linear_Integral',
  223. 'Bernoulli_Integral',
  224. 'nth_linear_constant_coeff_variation_of_parameters_Integral')
  225. assert c == ('factorable',
  226. '1st_linear',
  227. 'Bernoulli',
  228. '1st_power_series',
  229. 'lie_group',
  230. 'nth_linear_constant_coeff_undetermined_coefficients',
  231. 'nth_linear_constant_coeff_variation_of_parameters',
  232. '1st_linear_Integral',
  233. 'Bernoulli_Integral',
  234. 'nth_linear_constant_coeff_variation_of_parameters_Integral')
  235. assert classify_ode(
  236. 2*x*f(x)*f(x).diff(x) + (1 + x)*f(x)**2 - exp(x), f(x)
  237. ) == ('factorable', '1st_exact', 'Bernoulli', 'almost_linear', 'lie_group',
  238. '1st_exact_Integral', 'Bernoulli_Integral', 'almost_linear_Integral')
  239. assert 'Riccati_special_minus2' in \
  240. classify_ode(2*f(x).diff(x) + f(x)**2 - f(x)/x + 3*x**(-2), f(x))
  241. raises(ValueError, lambda: classify_ode(x + f(x, y).diff(x).diff(
  242. y), f(x, y)))
  243. # issue 5176
  244. k = Symbol('k')
  245. assert classify_ode(f(x).diff(x)/(k*f(x) + k*x*f(x)) + 2*f(x)/(k*f(x) +
  246. k*x*f(x)) + x*f(x).diff(x)/(k*f(x) + k*x*f(x)) + z, f(x)) == \
  247. ('factorable', 'separable', '1st_exact', '1st_linear', 'Bernoulli',
  248. '1st_power_series', 'lie_group', 'separable_Integral', '1st_exact_Integral',
  249. '1st_linear_Integral', 'Bernoulli_Integral')
  250. # preprocessing
  251. ans = ('factorable', 'nth_algebraic', 'separable', '1st_exact', '1st_linear', 'Bernoulli',
  252. '1st_homogeneous_coeff_best',
  253. '1st_homogeneous_coeff_subs_indep_div_dep',
  254. '1st_homogeneous_coeff_subs_dep_div_indep',
  255. '1st_power_series', 'lie_group',
  256. 'nth_linear_constant_coeff_undetermined_coefficients',
  257. 'nth_linear_euler_eq_nonhomogeneous_undetermined_coefficients',
  258. 'nth_linear_constant_coeff_variation_of_parameters',
  259. 'nth_linear_euler_eq_nonhomogeneous_variation_of_parameters',
  260. 'nth_algebraic_Integral',
  261. 'separable_Integral', '1st_exact_Integral',
  262. '1st_linear_Integral',
  263. 'Bernoulli_Integral',
  264. '1st_homogeneous_coeff_subs_indep_div_dep_Integral',
  265. '1st_homogeneous_coeff_subs_dep_div_indep_Integral',
  266. 'nth_linear_constant_coeff_variation_of_parameters_Integral',
  267. 'nth_linear_euler_eq_nonhomogeneous_variation_of_parameters_Integral')
  268. # w/o f(x) given
  269. assert classify_ode(diff(f(x) + x, x) + diff(f(x), x)) == ans
  270. # w/ f(x) and prep=True
  271. assert classify_ode(diff(f(x) + x, x) + diff(f(x), x), f(x),
  272. prep=True) == ans
  273. assert classify_ode(Eq(2*x**3*f(x).diff(x), 0), f(x)) == \
  274. ('factorable', 'nth_algebraic', 'separable', '1st_exact',
  275. '1st_linear', 'Bernoulli', '1st_power_series',
  276. 'lie_group', 'nth_linear_euler_eq_homogeneous',
  277. 'nth_algebraic_Integral', 'separable_Integral', '1st_exact_Integral',
  278. '1st_linear_Integral', 'Bernoulli_Integral')
  279. assert classify_ode(Eq(2*f(x)**3*f(x).diff(x), 0), f(x)) == \
  280. ('factorable', 'nth_algebraic', 'separable', '1st_exact', '1st_linear',
  281. 'Bernoulli', '1st_power_series', 'lie_group', 'nth_algebraic_Integral',
  282. 'separable_Integral', '1st_exact_Integral', '1st_linear_Integral',
  283. 'Bernoulli_Integral')
  284. # test issue 13864
  285. assert classify_ode(Eq(diff(f(x), x) - f(x)**x, 0), f(x)) == \
  286. ('1st_power_series', 'lie_group')
  287. assert isinstance(classify_ode(Eq(f(x), 5), f(x), dict=True), dict)
  288. #This is for new behavior of classify_ode when called internally with default, It should
  289. # return the first hint which matches therefore, 'ordered_hints' key will not be there.
  290. assert sorted(classify_ode(Eq(f(x).diff(x), 0), f(x), dict=True).keys()) == \
  291. ['default', 'nth_linear_constant_coeff_homogeneous', 'order']
  292. a = classify_ode(2*x*f(x)*f(x).diff(x) + (1 + x)*f(x)**2 - exp(x), f(x), dict=True, hint='Bernoulli')
  293. assert sorted(a.keys()) == ['Bernoulli', 'Bernoulli_Integral', 'default', 'order', 'ordered_hints']
  294. # test issue 22155
  295. a = classify_ode(f(x).diff(x) - exp(f(x) - x), f(x))
  296. assert a == ('separable',
  297. '1st_exact', '1st_power_series',
  298. 'lie_group', 'separable_Integral',
  299. '1st_exact_Integral')
  300. def test_classify_ode_ics():
  301. # Dummy
  302. eq = f(x).diff(x, x) - f(x)
  303. # Not f(0) or f'(0)
  304. ics = {x: 1}
  305. raises(ValueError, lambda: classify_ode(eq, f(x), ics=ics))
  306. ############################
  307. # f(0) type (AppliedUndef) #
  308. ############################
  309. # Wrong function
  310. ics = {g(0): 1}
  311. raises(ValueError, lambda: classify_ode(eq, f(x), ics=ics))
  312. # Contains x
  313. ics = {f(x): 1}
  314. raises(ValueError, lambda: classify_ode(eq, f(x), ics=ics))
  315. # Too many args
  316. ics = {f(0, 0): 1}
  317. raises(ValueError, lambda: classify_ode(eq, f(x), ics=ics))
  318. # point contains f
  319. # XXX: Should be NotImplementedError
  320. ics = {f(0): f(1)}
  321. raises(ValueError, lambda: classify_ode(eq, f(x), ics=ics))
  322. # Does not raise
  323. ics = {f(0): 1}
  324. classify_ode(eq, f(x), ics=ics)
  325. #####################
  326. # f'(0) type (Subs) #
  327. #####################
  328. # Wrong function
  329. ics = {g(x).diff(x).subs(x, 0): 1}
  330. raises(ValueError, lambda: classify_ode(eq, f(x), ics=ics))
  331. # Contains x
  332. ics = {f(y).diff(y).subs(y, x): 1}
  333. raises(ValueError, lambda: classify_ode(eq, f(x), ics=ics))
  334. # Wrong variable
  335. ics = {f(y).diff(y).subs(y, 0): 1}
  336. raises(ValueError, lambda: classify_ode(eq, f(x), ics=ics))
  337. # Too many args
  338. ics = {f(x, y).diff(x).subs(x, 0): 1}
  339. raises(ValueError, lambda: classify_ode(eq, f(x), ics=ics))
  340. # Derivative wrt wrong vars
  341. ics = {Derivative(f(x), x, y).subs(x, 0): 1}
  342. raises(ValueError, lambda: classify_ode(eq, f(x), ics=ics))
  343. # point contains f
  344. # XXX: Should be NotImplementedError
  345. ics = {f(x).diff(x).subs(x, 0): f(0)}
  346. raises(ValueError, lambda: classify_ode(eq, f(x), ics=ics))
  347. # Does not raise
  348. ics = {f(x).diff(x).subs(x, 0): 1}
  349. classify_ode(eq, f(x), ics=ics)
  350. ###########################
  351. # f'(y) type (Derivative) #
  352. ###########################
  353. # Wrong function
  354. ics = {g(x).diff(x).subs(x, y): 1}
  355. raises(ValueError, lambda: classify_ode(eq, f(x), ics=ics))
  356. # Contains x
  357. ics = {f(y).diff(y).subs(y, x): 1}
  358. raises(ValueError, lambda: classify_ode(eq, f(x), ics=ics))
  359. # Too many args
  360. ics = {f(x, y).diff(x).subs(x, y): 1}
  361. raises(ValueError, lambda: classify_ode(eq, f(x), ics=ics))
  362. # Derivative wrt wrong vars
  363. ics = {Derivative(f(x), x, z).subs(x, y): 1}
  364. raises(ValueError, lambda: classify_ode(eq, f(x), ics=ics))
  365. # point contains f
  366. # XXX: Should be NotImplementedError
  367. ics = {f(x).diff(x).subs(x, y): f(0)}
  368. raises(ValueError, lambda: classify_ode(eq, f(x), ics=ics))
  369. # Does not raise
  370. ics = {f(x).diff(x).subs(x, y): 1}
  371. classify_ode(eq, f(x), ics=ics)
  372. def test_classify_sysode():
  373. # Here x is assumed to be x(t) and y as y(t) for simplicity.
  374. # Similarly diff(x,t) and diff(y,y) is assumed to be x1 and y1 respectively.
  375. k, l, m, n = symbols('k, l, m, n', Integer=True)
  376. k1, k2, k3, l1, l2, l3, m1, m2, m3 = symbols('k1, k2, k3, l1, l2, l3, m1, m2, m3', Integer=True)
  377. P, Q, R, p, q, r = symbols('P, Q, R, p, q, r', cls=Function)
  378. P1, P2, P3, Q1, Q2, R1, R2 = symbols('P1, P2, P3, Q1, Q2, R1, R2', cls=Function)
  379. x, y, z = symbols('x, y, z', cls=Function)
  380. t = symbols('t')
  381. x1 = diff(x(t),t) ; y1 = diff(y(t),t) ;
  382. eq6 = (Eq(x1, exp(k*x(t))*P(x(t),y(t))), Eq(y1,r(y(t))*P(x(t),y(t))))
  383. sol6 = {'no_of_equation': 2, 'func_coeff': {(0, x(t), 0): 0, (1, x(t), 1): 0, (0, x(t), 1): 1, (1, y(t), 0): 0, \
  384. (1, x(t), 0): 0, (0, y(t), 1): 0, (0, y(t), 0): 0, (1, y(t), 1): 1}, 'type_of_equation': 'type2', 'func': \
  385. [x(t), y(t)], 'is_linear': False, 'eq': [-P(x(t), y(t))*exp(k*x(t)) + Derivative(x(t), t), -P(x(t), \
  386. y(t))*r(y(t)) + Derivative(y(t), t)], 'order': {y(t): 1, x(t): 1}}
  387. assert classify_sysode(eq6) == sol6
  388. eq7 = (Eq(x1, x(t)**2+y(t)/x(t)), Eq(y1, x(t)/y(t)))
  389. sol7 = {'no_of_equation': 2, 'func_coeff': {(0, x(t), 0): 0, (1, x(t), 1): 0, (0, x(t), 1): 1, (1, y(t), 0): 0, \
  390. (1, x(t), 0): -1/y(t), (0, y(t), 1): 0, (0, y(t), 0): -1/x(t), (1, y(t), 1): 1}, 'type_of_equation': 'type3', \
  391. 'func': [x(t), y(t)], 'is_linear': False, 'eq': [-x(t)**2 + Derivative(x(t), t) - y(t)/x(t), -x(t)/y(t) + \
  392. Derivative(y(t), t)], 'order': {y(t): 1, x(t): 1}}
  393. assert classify_sysode(eq7) == sol7
  394. eq8 = (Eq(x1, P1(x(t))*Q1(y(t))*R(x(t),y(t),t)), Eq(y1, P1(x(t))*Q1(y(t))*R(x(t),y(t),t)))
  395. sol8 = {'func': [x(t), y(t)], 'is_linear': False, 'type_of_equation': 'type4', 'eq': \
  396. [-P1(x(t))*Q1(y(t))*R(x(t), y(t), t) + Derivative(x(t), t), -P1(x(t))*Q1(y(t))*R(x(t), y(t), t) + \
  397. Derivative(y(t), t)], 'func_coeff': {(0, y(t), 1): 0, (1, y(t), 1): 1, (1, x(t), 1): 0, (0, y(t), 0): 0, \
  398. (1, x(t), 0): 0, (0, x(t), 0): 0, (1, y(t), 0): 0, (0, x(t), 1): 1}, 'order': {y(t): 1, x(t): 1}, 'no_of_equation': 2}
  399. assert classify_sysode(eq8) == sol8
  400. eq11 = (Eq(x1,x(t)*y(t)**3), Eq(y1,y(t)**5))
  401. sol11 = {'no_of_equation': 2, 'func_coeff': {(0, x(t), 0): -y(t)**3, (1, x(t), 1): 0, (0, x(t), 1): 1, \
  402. (1, y(t), 0): 0, (1, x(t), 0): 0, (0, y(t), 1): 0, (0, y(t), 0): 0, (1, y(t), 1): 1}, 'type_of_equation': \
  403. 'type1', 'func': [x(t), y(t)], 'is_linear': False, 'eq': [-x(t)*y(t)**3 + Derivative(x(t), t), \
  404. -y(t)**5 + Derivative(y(t), t)], 'order': {y(t): 1, x(t): 1}}
  405. assert classify_sysode(eq11) == sol11
  406. eq13 = (Eq(x1,x(t)*y(t)*sin(t)**2), Eq(y1,y(t)**2*sin(t)**2))
  407. sol13 = {'no_of_equation': 2, 'func_coeff': {(0, x(t), 0): -y(t)*sin(t)**2, (1, x(t), 1): 0, (0, x(t), 1): 1, \
  408. (1, y(t), 0): 0, (1, x(t), 0): 0, (0, y(t), 1): 0, (0, y(t), 0): -x(t)*sin(t)**2, (1, y(t), 1): 1}, \
  409. 'type_of_equation': 'type4', 'func': [x(t), y(t)], 'is_linear': False, 'eq': [-x(t)*y(t)*sin(t)**2 + \
  410. Derivative(x(t), t), -y(t)**2*sin(t)**2 + Derivative(y(t), t)], 'order': {y(t): 1, x(t): 1}}
  411. assert classify_sysode(eq13) == sol13
  412. def test_solve_ics():
  413. # Basic tests that things work from dsolve.
  414. assert dsolve(f(x).diff(x) - 1/f(x), f(x), ics={f(1): 2}) == \
  415. Eq(f(x), sqrt(2 * x + 2))
  416. assert dsolve(f(x).diff(x) - f(x), f(x), ics={f(0): 1}) == Eq(f(x), exp(x))
  417. assert dsolve(f(x).diff(x) - f(x), f(x), ics={f(x).diff(x).subs(x, 0): 1}) == Eq(f(x), exp(x))
  418. assert dsolve(f(x).diff(x, x) + f(x), f(x), ics={f(0): 1,
  419. f(x).diff(x).subs(x, 0): 1}) == Eq(f(x), sin(x) + cos(x))
  420. assert dsolve([f(x).diff(x) - f(x) + g(x), g(x).diff(x) - g(x) - f(x)],
  421. [f(x), g(x)], ics={f(0): 1, g(0): 0}) == [Eq(f(x), exp(x)*cos(x)), Eq(g(x), exp(x)*sin(x))]
  422. # Test cases where dsolve returns two solutions.
  423. eq = (x**2*f(x)**2 - x).diff(x)
  424. assert dsolve(eq, f(x), ics={f(1): 0}) == [Eq(f(x),
  425. -sqrt(x - 1)/x), Eq(f(x), sqrt(x - 1)/x)]
  426. assert dsolve(eq, f(x), ics={f(x).diff(x).subs(x, 1): 0}) == [Eq(f(x),
  427. -sqrt(x - S.Half)/x), Eq(f(x), sqrt(x - S.Half)/x)]
  428. eq = cos(f(x)) - (x*sin(f(x)) - f(x)**2)*f(x).diff(x)
  429. assert dsolve(eq, f(x),
  430. ics={f(0):1}, hint='1st_exact', simplify=False) == Eq(x*cos(f(x)) + f(x)**3/3, Rational(1, 3))
  431. assert dsolve(eq, f(x),
  432. ics={f(0):1}, hint='1st_exact', simplify=True) == Eq(x*cos(f(x)) + f(x)**3/3, Rational(1, 3))
  433. assert solve_ics([Eq(f(x), C1*exp(x))], [f(x)], [C1], {f(0): 1}) == {C1: 1}
  434. assert solve_ics([Eq(f(x), C1*sin(x) + C2*cos(x))], [f(x)], [C1, C2],
  435. {f(0): 1, f(pi/2): 1}) == {C1: 1, C2: 1}
  436. assert solve_ics([Eq(f(x), C1*sin(x) + C2*cos(x))], [f(x)], [C1, C2],
  437. {f(0): 1, f(x).diff(x).subs(x, 0): 1}) == {C1: 1, C2: 1}
  438. assert solve_ics([Eq(f(x), C1*sin(x) + C2*cos(x))], [f(x)], [C1, C2], {f(0): 1}) == \
  439. {C2: 1}
  440. # Some more complicated tests Refer to PR #16098
  441. assert set(dsolve(f(x).diff(x)*(f(x).diff(x, 2)-x), ics={f(0):0, f(x).diff(x).subs(x, 1):0})) == \
  442. {Eq(f(x), 0), Eq(f(x), x ** 3 / 6 - x / 2)}
  443. assert set(dsolve(f(x).diff(x)*(f(x).diff(x, 2)-x), ics={f(0):0})) == \
  444. {Eq(f(x), 0), Eq(f(x), C2*x + x**3/6)}
  445. K, r, f0 = symbols('K r f0')
  446. sol = Eq(f(x), K*f0*exp(r*x)/((-K + f0)*(f0*exp(r*x)/(-K + f0) - 1)))
  447. assert (dsolve(Eq(f(x).diff(x), r * f(x) * (1 - f(x) / K)), f(x), ics={f(0): f0})) == sol
  448. #Order dependent issues Refer to PR #16098
  449. assert set(dsolve(f(x).diff(x)*(f(x).diff(x, 2)-x), ics={f(x).diff(x).subs(x,0):0, f(0):0})) == \
  450. {Eq(f(x), 0), Eq(f(x), x ** 3 / 6)}
  451. assert set(dsolve(f(x).diff(x)*(f(x).diff(x, 2)-x), ics={f(0):0, f(x).diff(x).subs(x,0):0})) == \
  452. {Eq(f(x), 0), Eq(f(x), x ** 3 / 6)}
  453. # XXX: Ought to be ValueError
  454. raises(ValueError, lambda: solve_ics([Eq(f(x), C1*sin(x) + C2*cos(x))], [f(x)], [C1, C2], {f(0): 1, f(pi): 1}))
  455. # Degenerate case. f'(0) is identically 0.
  456. raises(ValueError, lambda: solve_ics([Eq(f(x), sqrt(C1 - x**2))], [f(x)], [C1], {f(x).diff(x).subs(x, 0): 0}))
  457. EI, q, L = symbols('EI q L')
  458. # eq = Eq(EI*diff(f(x), x, 4), q)
  459. sols = [Eq(f(x), C1 + C2*x + C3*x**2 + C4*x**3 + q*x**4/(24*EI))]
  460. funcs = [f(x)]
  461. constants = [C1, C2, C3, C4]
  462. # Test both cases, Derivative (the default from f(x).diff(x).subs(x, L)),
  463. # and Subs
  464. ics1 = {f(0): 0,
  465. f(x).diff(x).subs(x, 0): 0,
  466. f(L).diff(L, 2): 0,
  467. f(L).diff(L, 3): 0}
  468. ics2 = {f(0): 0,
  469. f(x).diff(x).subs(x, 0): 0,
  470. Subs(f(x).diff(x, 2), x, L): 0,
  471. Subs(f(x).diff(x, 3), x, L): 0}
  472. solved_constants1 = solve_ics(sols, funcs, constants, ics1)
  473. solved_constants2 = solve_ics(sols, funcs, constants, ics2)
  474. assert solved_constants1 == solved_constants2 == {
  475. C1: 0,
  476. C2: 0,
  477. C3: L**2*q/(4*EI),
  478. C4: -L*q/(6*EI)}
  479. def test_ode_order():
  480. f = Function('f')
  481. g = Function('g')
  482. x = Symbol('x')
  483. assert ode_order(3*x*exp(f(x)), f(x)) == 0
  484. assert ode_order(x*diff(f(x), x) + 3*x*f(x) - sin(x)/x, f(x)) == 1
  485. assert ode_order(x**2*f(x).diff(x, x) + x*diff(f(x), x) - f(x), f(x)) == 2
  486. assert ode_order(diff(x*exp(f(x)), x, x), f(x)) == 2
  487. assert ode_order(diff(x*diff(x*exp(f(x)), x, x), x), f(x)) == 3
  488. assert ode_order(diff(f(x), x, x), g(x)) == 0
  489. assert ode_order(diff(f(x), x, x)*diff(g(x), x), f(x)) == 2
  490. assert ode_order(diff(f(x), x, x)*diff(g(x), x), g(x)) == 1
  491. assert ode_order(diff(x*diff(x*exp(f(x)), x, x), x), g(x)) == 0
  492. # issue 5835: ode_order has to also work for unevaluated derivatives
  493. # (ie, without using doit()).
  494. assert ode_order(Derivative(x*f(x), x), f(x)) == 1
  495. assert ode_order(x*sin(Derivative(x*f(x)**2, x, x)), f(x)) == 2
  496. assert ode_order(Derivative(x*Derivative(x*exp(f(x)), x, x), x), g(x)) == 0
  497. assert ode_order(Derivative(f(x), x, x), g(x)) == 0
  498. assert ode_order(Derivative(x*exp(f(x)), x, x), f(x)) == 2
  499. assert ode_order(Derivative(f(x), x, x)*Derivative(g(x), x), g(x)) == 1
  500. assert ode_order(Derivative(x*Derivative(f(x), x, x), x), f(x)) == 3
  501. assert ode_order(
  502. x*sin(Derivative(x*Derivative(f(x), x)**2, x, x)), f(x)) == 3
  503. def test_homogeneous_order():
  504. assert homogeneous_order(exp(y/x) + tan(y/x), x, y) == 0
  505. assert homogeneous_order(x**2 + sin(x)*cos(y), x, y) is None
  506. assert homogeneous_order(x - y - x*sin(y/x), x, y) == 1
  507. assert homogeneous_order((x*y + sqrt(x**4 + y**4) + x**2*(log(x) - log(y)))/
  508. (pi*x**Rational(2, 3)*sqrt(y)**3), x, y) == Rational(-1, 6)
  509. assert homogeneous_order(y/x*cos(y/x) - x/y*sin(y/x) + cos(y/x), x, y) == 0
  510. assert homogeneous_order(f(x), x, f(x)) == 1
  511. assert homogeneous_order(f(x)**2, x, f(x)) == 2
  512. assert homogeneous_order(x*y*z, x, y) == 2
  513. assert homogeneous_order(x*y*z, x, y, z) == 3
  514. assert homogeneous_order(x**2*f(x)/sqrt(x**2 + f(x)**2), f(x)) is None
  515. assert homogeneous_order(f(x, y)**2, x, f(x, y), y) == 2
  516. assert homogeneous_order(f(x, y)**2, x, f(x), y) is None
  517. assert homogeneous_order(f(x, y)**2, x, f(x, y)) is None
  518. assert homogeneous_order(f(y, x)**2, x, y, f(x, y)) is None
  519. assert homogeneous_order(f(y), f(x), x) is None
  520. assert homogeneous_order(-f(x)/x + 1/sin(f(x)/ x), f(x), x) == 0
  521. assert homogeneous_order(log(1/y) + log(x**2), x, y) is None
  522. assert homogeneous_order(log(1/y) + log(x), x, y) == 0
  523. assert homogeneous_order(log(x/y), x, y) == 0
  524. assert homogeneous_order(2*log(1/y) + 2*log(x), x, y) == 0
  525. a = Symbol('a')
  526. assert homogeneous_order(a*log(1/y) + a*log(x), x, y) == 0
  527. assert homogeneous_order(f(x).diff(x), x, y) is None
  528. assert homogeneous_order(-f(x).diff(x) + x, x, y) is None
  529. assert homogeneous_order(O(x), x, y) is None
  530. assert homogeneous_order(x + O(x**2), x, y) is None
  531. assert homogeneous_order(x**pi, x) == pi
  532. assert homogeneous_order(x**x, x) is None
  533. raises(ValueError, lambda: homogeneous_order(x*y))
  534. @XFAIL
  535. def test_noncircularized_real_imaginary_parts():
  536. # If this passes, lines numbered 3878-3882 (at the time of this commit)
  537. # of sympy/solvers/ode.py for nth_linear_constant_coeff_homogeneous
  538. # should be removed.
  539. y = sqrt(1+x)
  540. i, r = im(y), re(y)
  541. assert not (i.has(atan2) and r.has(atan2))
  542. def test_collect_respecting_exponentials():
  543. # If this test passes, lines 1306-1311 (at the time of this commit)
  544. # of sympy/solvers/ode.py should be removed.
  545. sol = 1 + exp(x/2)
  546. assert sol == collect( sol, exp(x/3))
  547. def test_undetermined_coefficients_match():
  548. assert _undetermined_coefficients_match(g(x), x) == {'test': False}
  549. assert _undetermined_coefficients_match(sin(2*x + sqrt(5)), x) == \
  550. {'test': True, 'trialset':
  551. {cos(2*x + sqrt(5)), sin(2*x + sqrt(5))}}
  552. assert _undetermined_coefficients_match(sin(x)*cos(x), x) == \
  553. {'test': False}
  554. s = {cos(x), x*cos(x), x**2*cos(x), x**2*sin(x), x*sin(x), sin(x)}
  555. assert _undetermined_coefficients_match(sin(x)*(x**2 + x + 1), x) == \
  556. {'test': True, 'trialset': s}
  557. assert _undetermined_coefficients_match(
  558. sin(x)*x**2 + sin(x)*x + sin(x), x) == {'test': True, 'trialset': s}
  559. assert _undetermined_coefficients_match(
  560. exp(2*x)*sin(x)*(x**2 + x + 1), x
  561. ) == {
  562. 'test': True, 'trialset': {exp(2*x)*sin(x), x**2*exp(2*x)*sin(x),
  563. cos(x)*exp(2*x), x**2*cos(x)*exp(2*x), x*cos(x)*exp(2*x),
  564. x*exp(2*x)*sin(x)}}
  565. assert _undetermined_coefficients_match(1/sin(x), x) == {'test': False}
  566. assert _undetermined_coefficients_match(log(x), x) == {'test': False}
  567. assert _undetermined_coefficients_match(2**(x)*(x**2 + x + 1), x) == \
  568. {'test': True, 'trialset': {2**x, x*2**x, x**2*2**x}}
  569. assert _undetermined_coefficients_match(x**y, x) == {'test': False}
  570. assert _undetermined_coefficients_match(exp(x)*exp(2*x + 1), x) == \
  571. {'test': True, 'trialset': {exp(1 + 3*x)}}
  572. assert _undetermined_coefficients_match(sin(x)*(x**2 + x + 1), x) == \
  573. {'test': True, 'trialset': {x*cos(x), x*sin(x), x**2*cos(x),
  574. x**2*sin(x), cos(x), sin(x)}}
  575. assert _undetermined_coefficients_match(sin(x)*(x + sin(x)), x) == \
  576. {'test': False}
  577. assert _undetermined_coefficients_match(sin(x)*(x + sin(2*x)), x) == \
  578. {'test': False}
  579. assert _undetermined_coefficients_match(sin(x)*tan(x), x) == \
  580. {'test': False}
  581. assert _undetermined_coefficients_match(
  582. x**2*sin(x)*exp(x) + x*sin(x) + x, x
  583. ) == {
  584. 'test': True, 'trialset': {x**2*cos(x)*exp(x), x, cos(x), S.One,
  585. exp(x)*sin(x), sin(x), x*exp(x)*sin(x), x*cos(x), x*cos(x)*exp(x),
  586. x*sin(x), cos(x)*exp(x), x**2*exp(x)*sin(x)}}
  587. assert _undetermined_coefficients_match(4*x*sin(x - 2), x) == {
  588. 'trialset': {x*cos(x - 2), x*sin(x - 2), cos(x - 2), sin(x - 2)},
  589. 'test': True,
  590. }
  591. assert _undetermined_coefficients_match(2**x*x, x) == \
  592. {'test': True, 'trialset': {2**x, x*2**x}}
  593. assert _undetermined_coefficients_match(2**x*exp(2*x), x) == \
  594. {'test': True, 'trialset': {2**x*exp(2*x)}}
  595. assert _undetermined_coefficients_match(exp(-x)/x, x) == \
  596. {'test': False}
  597. # Below are from Ordinary Differential Equations,
  598. # Tenenbaum and Pollard, pg. 231
  599. assert _undetermined_coefficients_match(S(4), x) == \
  600. {'test': True, 'trialset': {S.One}}
  601. assert _undetermined_coefficients_match(12*exp(x), x) == \
  602. {'test': True, 'trialset': {exp(x)}}
  603. assert _undetermined_coefficients_match(exp(I*x), x) == \
  604. {'test': True, 'trialset': {exp(I*x)}}
  605. assert _undetermined_coefficients_match(sin(x), x) == \
  606. {'test': True, 'trialset': {cos(x), sin(x)}}
  607. assert _undetermined_coefficients_match(cos(x), x) == \
  608. {'test': True, 'trialset': {cos(x), sin(x)}}
  609. assert _undetermined_coefficients_match(8 + 6*exp(x) + 2*sin(x), x) == \
  610. {'test': True, 'trialset': {S.One, cos(x), sin(x), exp(x)}}
  611. assert _undetermined_coefficients_match(x**2, x) == \
  612. {'test': True, 'trialset': {S.One, x, x**2}}
  613. assert _undetermined_coefficients_match(9*x*exp(x) + exp(-x), x) == \
  614. {'test': True, 'trialset': {x*exp(x), exp(x), exp(-x)}}
  615. assert _undetermined_coefficients_match(2*exp(2*x)*sin(x), x) == \
  616. {'test': True, 'trialset': {exp(2*x)*sin(x), cos(x)*exp(2*x)}}
  617. assert _undetermined_coefficients_match(x - sin(x), x) == \
  618. {'test': True, 'trialset': {S.One, x, cos(x), sin(x)}}
  619. assert _undetermined_coefficients_match(x**2 + 2*x, x) == \
  620. {'test': True, 'trialset': {S.One, x, x**2}}
  621. assert _undetermined_coefficients_match(4*x*sin(x), x) == \
  622. {'test': True, 'trialset': {x*cos(x), x*sin(x), cos(x), sin(x)}}
  623. assert _undetermined_coefficients_match(x*sin(2*x), x) == \
  624. {'test': True, 'trialset':
  625. {x*cos(2*x), x*sin(2*x), cos(2*x), sin(2*x)}}
  626. assert _undetermined_coefficients_match(x**2*exp(-x), x) == \
  627. {'test': True, 'trialset': {x*exp(-x), x**2*exp(-x), exp(-x)}}
  628. assert _undetermined_coefficients_match(2*exp(-x) - x**2*exp(-x), x) == \
  629. {'test': True, 'trialset': {x*exp(-x), x**2*exp(-x), exp(-x)}}
  630. assert _undetermined_coefficients_match(exp(-2*x) + x**2, x) == \
  631. {'test': True, 'trialset': {S.One, x, x**2, exp(-2*x)}}
  632. assert _undetermined_coefficients_match(x*exp(-x), x) == \
  633. {'test': True, 'trialset': {x*exp(-x), exp(-x)}}
  634. assert _undetermined_coefficients_match(x + exp(2*x), x) == \
  635. {'test': True, 'trialset': {S.One, x, exp(2*x)}}
  636. assert _undetermined_coefficients_match(sin(x) + exp(-x), x) == \
  637. {'test': True, 'trialset': {cos(x), sin(x), exp(-x)}}
  638. assert _undetermined_coefficients_match(exp(x), x) == \
  639. {'test': True, 'trialset': {exp(x)}}
  640. # converted from sin(x)**2
  641. assert _undetermined_coefficients_match(S.Half - cos(2*x)/2, x) == \
  642. {'test': True, 'trialset': {S.One, cos(2*x), sin(2*x)}}
  643. # converted from exp(2*x)*sin(x)**2
  644. assert _undetermined_coefficients_match(
  645. exp(2*x)*(S.Half + cos(2*x)/2), x
  646. ) == {
  647. 'test': True, 'trialset': {exp(2*x)*sin(2*x), cos(2*x)*exp(2*x),
  648. exp(2*x)}}
  649. assert _undetermined_coefficients_match(2*x + sin(x) + cos(x), x) == \
  650. {'test': True, 'trialset': {S.One, x, cos(x), sin(x)}}
  651. # converted from sin(2*x)*sin(x)
  652. assert _undetermined_coefficients_match(cos(x)/2 - cos(3*x)/2, x) == \
  653. {'test': True, 'trialset': {cos(x), cos(3*x), sin(x), sin(3*x)}}
  654. assert _undetermined_coefficients_match(cos(x**2), x) == {'test': False}
  655. assert _undetermined_coefficients_match(2**(x**2), x) == {'test': False}
  656. def test_issue_4785_22462():
  657. from sympy.abc import A
  658. eq = x + A*(x + diff(f(x), x) + f(x)) + diff(f(x), x) + f(x) + 2
  659. assert classify_ode(eq, f(x)) == ('factorable', '1st_exact', '1st_linear',
  660. 'Bernoulli', 'almost_linear', '1st_power_series', 'lie_group',
  661. 'nth_linear_constant_coeff_undetermined_coefficients',
  662. 'nth_linear_constant_coeff_variation_of_parameters',
  663. '1st_exact_Integral', '1st_linear_Integral', 'Bernoulli_Integral',
  664. 'almost_linear_Integral',
  665. 'nth_linear_constant_coeff_variation_of_parameters_Integral')
  666. # issue 4864
  667. eq = (x**2 + f(x)**2)*f(x).diff(x) - 2*x*f(x)
  668. assert classify_ode(eq, f(x)) == ('factorable', '1st_exact',
  669. '1st_homogeneous_coeff_best',
  670. '1st_homogeneous_coeff_subs_indep_div_dep',
  671. '1st_homogeneous_coeff_subs_dep_div_indep',
  672. '1st_power_series',
  673. 'lie_group', '1st_exact_Integral',
  674. '1st_homogeneous_coeff_subs_indep_div_dep_Integral',
  675. '1st_homogeneous_coeff_subs_dep_div_indep_Integral')
  676. def test_issue_4825():
  677. raises(ValueError, lambda: dsolve(f(x, y).diff(x) - y*f(x, y), f(x)))
  678. assert classify_ode(f(x, y).diff(x) - y*f(x, y), f(x), dict=True) == \
  679. {'order': 0, 'default': None, 'ordered_hints': ()}
  680. # See also issue 3793, test Z13.
  681. raises(ValueError, lambda: dsolve(f(x).diff(x), f(y)))
  682. assert classify_ode(f(x).diff(x), f(y), dict=True) == \
  683. {'order': 0, 'default': None, 'ordered_hints': ()}
  684. def test_constant_renumber_order_issue_5308():
  685. from sympy.utilities.iterables import variations
  686. assert constant_renumber(C1*x + C2*y) == \
  687. constant_renumber(C1*y + C2*x) == \
  688. C1*x + C2*y
  689. e = C1*(C2 + x)*(C3 + y)
  690. for a, b, c in variations([C1, C2, C3], 3):
  691. assert constant_renumber(a*(b + x)*(c + y)) == e
  692. def test_constant_renumber():
  693. e1, e2, x, y = symbols("e1:3 x y")
  694. exprs = [e2*x, e1*x + e2*y]
  695. assert constant_renumber(exprs[0]) == e2*x
  696. assert constant_renumber(exprs[0], variables=[x]) == C1*x
  697. assert constant_renumber(exprs[0], variables=[x], newconstants=[C2]) == C2*x
  698. assert constant_renumber(exprs, variables=[x, y]) == [C1*x, C1*y + C2*x]
  699. assert constant_renumber(exprs, variables=[x, y], newconstants=symbols("C3:5")) == [C3*x, C3*y + C4*x]
  700. def test_issue_5770():
  701. k = Symbol("k", real=True)
  702. t = Symbol('t')
  703. w = Function('w')
  704. sol = dsolve(w(t).diff(t, 6) - k**6*w(t), w(t))
  705. assert len([s for s in sol.free_symbols if s.name.startswith('C')]) == 6
  706. assert constantsimp((C1*cos(x) + C2*cos(x))*exp(x), {C1, C2}) == \
  707. C1*cos(x)*exp(x)
  708. assert constantsimp(C1*cos(x) + C2*cos(x) + C3*sin(x), {C1, C2, C3}) == \
  709. C1*cos(x) + C3*sin(x)
  710. assert constantsimp(exp(C1 + x), {C1}) == C1*exp(x)
  711. assert constantsimp(x + C1 + y, {C1, y}) == C1 + x
  712. assert constantsimp(x + C1 + Integral(x, (x, 1, 2)), {C1}) == C1 + x
  713. def test_issue_5112_5430():
  714. assert homogeneous_order(-log(x) + acosh(x), x) is None
  715. assert homogeneous_order(y - log(x), x, y) is None
  716. def test_issue_5095():
  717. f = Function('f')
  718. raises(ValueError, lambda: dsolve(f(x).diff(x)**2, f(x), 'fdsjf'))
  719. def test_homogeneous_function():
  720. f = Function('f')
  721. eq1 = tan(x + f(x))
  722. eq2 = sin((3*x)/(4*f(x)))
  723. eq3 = cos(x*f(x)*Rational(3, 4))
  724. eq4 = log((3*x + 4*f(x))/(5*f(x) + 7*x))
  725. eq5 = exp((2*x**2)/(3*f(x)**2))
  726. eq6 = log((3*x + 4*f(x))/(5*f(x) + 7*x) + exp((2*x**2)/(3*f(x)**2)))
  727. eq7 = sin((3*x)/(5*f(x) + x**2))
  728. assert homogeneous_order(eq1, x, f(x)) == None
  729. assert homogeneous_order(eq2, x, f(x)) == 0
  730. assert homogeneous_order(eq3, x, f(x)) == None
  731. assert homogeneous_order(eq4, x, f(x)) == 0
  732. assert homogeneous_order(eq5, x, f(x)) == 0
  733. assert homogeneous_order(eq6, x, f(x)) == 0
  734. assert homogeneous_order(eq7, x, f(x)) == None
  735. def test_linear_coeff_match():
  736. n, d = z*(2*x + 3*f(x) + 5), z*(7*x + 9*f(x) + 11)
  737. rat = n/d
  738. eq1 = sin(rat) + cos(rat.expand())
  739. obj1 = LinearCoefficients(eq1)
  740. eq2 = rat
  741. obj2 = LinearCoefficients(eq2)
  742. eq3 = log(sin(rat))
  743. obj3 = LinearCoefficients(eq3)
  744. ans = (4, Rational(-13, 3))
  745. assert obj1._linear_coeff_match(eq1, f(x)) == ans
  746. assert obj2._linear_coeff_match(eq2, f(x)) == ans
  747. assert obj3._linear_coeff_match(eq3, f(x)) == ans
  748. # no c
  749. eq4 = (3*x)/f(x)
  750. obj4 = LinearCoefficients(eq4)
  751. # not x and f(x)
  752. eq5 = (3*x + 2)/x
  753. obj5 = LinearCoefficients(eq5)
  754. # denom will be zero
  755. eq6 = (3*x + 2*f(x) + 1)/(3*x + 2*f(x) + 5)
  756. obj6 = LinearCoefficients(eq6)
  757. # not rational coefficient
  758. eq7 = (3*x + 2*f(x) + sqrt(2))/(3*x + 2*f(x) + 5)
  759. obj7 = LinearCoefficients(eq7)
  760. assert obj4._linear_coeff_match(eq4, f(x)) is None
  761. assert obj5._linear_coeff_match(eq5, f(x)) is None
  762. assert obj6._linear_coeff_match(eq6, f(x)) is None
  763. assert obj7._linear_coeff_match(eq7, f(x)) is None
  764. def test_constantsimp_take_problem():
  765. c = exp(C1) + 2
  766. assert len(Poly(constantsimp(exp(C1) + c + c*x, [C1])).gens) == 2
  767. def test_series():
  768. C1 = Symbol("C1")
  769. eq = f(x).diff(x) - f(x)
  770. sol = Eq(f(x), C1 + C1*x + C1*x**2/2 + C1*x**3/6 + C1*x**4/24 +
  771. C1*x**5/120 + O(x**6))
  772. assert dsolve(eq, hint='1st_power_series') == sol
  773. assert checkodesol(eq, sol, order=1)[0]
  774. eq = f(x).diff(x) - x*f(x)
  775. sol = Eq(f(x), C1*x**4/8 + C1*x**2/2 + C1 + O(x**6))
  776. assert dsolve(eq, hint='1st_power_series') == sol
  777. assert checkodesol(eq, sol, order=1)[0]
  778. eq = f(x).diff(x) - sin(x*f(x))
  779. sol = Eq(f(x), (x - 2)**2*(1+ sin(4))*cos(4) + (x - 2)*sin(4) + 2 + O(x**3))
  780. assert dsolve(eq, hint='1st_power_series', ics={f(2): 2}, n=3) == sol
  781. # FIXME: The solution here should be O((x-2)**3) so is incorrect
  782. #assert checkodesol(eq, sol, order=1)[0]
  783. @slow
  784. def test_2nd_power_series_ordinary():
  785. C1, C2 = symbols("C1 C2")
  786. eq = f(x).diff(x, 2) - x*f(x)
  787. assert classify_ode(eq) == ('2nd_linear_airy', '2nd_power_series_ordinary')
  788. sol = Eq(f(x), C2*(x**3/6 + 1) + C1*x*(x**3/12 + 1) + O(x**6))
  789. assert dsolve(eq, hint='2nd_power_series_ordinary') == sol
  790. assert checkodesol(eq, sol) == (True, 0)
  791. sol = Eq(f(x), C2*((x + 2)**4/6 + (x + 2)**3/6 - (x + 2)**2 + 1)
  792. + C1*(x + (x + 2)**4/12 - (x + 2)**3/3 + S(2))
  793. + O(x**6))
  794. assert dsolve(eq, hint='2nd_power_series_ordinary', x0=-2) == sol
  795. # FIXME: Solution should be O((x+2)**6)
  796. # assert checkodesol(eq, sol) == (True, 0)
  797. sol = Eq(f(x), C2*x + C1 + O(x**2))
  798. assert dsolve(eq, hint='2nd_power_series_ordinary', n=2) == sol
  799. assert checkodesol(eq, sol) == (True, 0)
  800. eq = (1 + x**2)*(f(x).diff(x, 2)) + 2*x*(f(x).diff(x)) -2*f(x)
  801. assert classify_ode(eq) == ('factorable', '2nd_hypergeometric', '2nd_hypergeometric_Integral',
  802. '2nd_power_series_ordinary')
  803. sol = Eq(f(x), C2*(-x**4/3 + x**2 + 1) + C1*x + O(x**6))
  804. assert dsolve(eq, hint='2nd_power_series_ordinary') == sol
  805. assert checkodesol(eq, sol) == (True, 0)
  806. eq = f(x).diff(x, 2) + x*(f(x).diff(x)) + f(x)
  807. assert classify_ode(eq) == ('factorable', '2nd_power_series_ordinary',)
  808. sol = Eq(f(x), C2*(x**4/8 - x**2/2 + 1) + C1*x*(-x**2/3 + 1) + O(x**6))
  809. assert dsolve(eq) == sol
  810. # FIXME: checkodesol fails for this solution...
  811. # assert checkodesol(eq, sol) == (True, 0)
  812. eq = f(x).diff(x, 2) + f(x).diff(x) - x*f(x)
  813. assert classify_ode(eq) == ('2nd_power_series_ordinary',)
  814. sol = Eq(f(x), C2*(-x**4/24 + x**3/6 + 1)
  815. + C1*x*(x**3/24 + x**2/6 - x/2 + 1) + O(x**6))
  816. assert dsolve(eq) == sol
  817. # FIXME: checkodesol fails for this solution...
  818. # assert checkodesol(eq, sol) == (True, 0)
  819. eq = f(x).diff(x, 2) + x*f(x)
  820. assert classify_ode(eq) == ('2nd_linear_airy', '2nd_power_series_ordinary')
  821. sol = Eq(f(x), C2*(x**6/180 - x**3/6 + 1) + C1*x*(-x**3/12 + 1) + O(x**7))
  822. assert dsolve(eq, hint='2nd_power_series_ordinary', n=7) == sol
  823. assert checkodesol(eq, sol) == (True, 0)
  824. def test_2nd_power_series_regular():
  825. C1, C2, a = symbols("C1 C2 a")
  826. eq = x**2*(f(x).diff(x, 2)) - 3*x*(f(x).diff(x)) + (4*x + 4)*f(x)
  827. sol = Eq(f(x), C1*x**2*(-16*x**3/9 + 4*x**2 - 4*x + 1) + O(x**6))
  828. assert dsolve(eq, hint='2nd_power_series_regular') == sol
  829. assert checkodesol(eq, sol) == (True, 0)
  830. eq = 4*x**2*(f(x).diff(x, 2)) -8*x**2*(f(x).diff(x)) + (4*x**2 +
  831. 1)*f(x)
  832. sol = Eq(f(x), C1*sqrt(x)*(x**4/24 + x**3/6 + x**2/2 + x + 1) + O(x**6))
  833. assert dsolve(eq, hint='2nd_power_series_regular') == sol
  834. assert checkodesol(eq, sol) == (True, 0)
  835. eq = x**2*(f(x).diff(x, 2)) - x**2*(f(x).diff(x)) + (
  836. x**2 - 2)*f(x)
  837. sol = Eq(f(x), C1*(-x**6/720 - 3*x**5/80 - x**4/8 + x**2/2 + x/2 + 1)/x +
  838. C2*x**2*(-x**3/60 + x**2/20 + x/2 + 1) + O(x**6))
  839. assert dsolve(eq) == sol
  840. assert checkodesol(eq, sol) == (True, 0)
  841. eq = x**2*(f(x).diff(x, 2)) + x*(f(x).diff(x)) + (x**2 - Rational(1, 4))*f(x)
  842. sol = Eq(f(x), C1*(x**4/24 - x**2/2 + 1)/sqrt(x) +
  843. C2*sqrt(x)*(x**4/120 - x**2/6 + 1) + O(x**6))
  844. assert dsolve(eq, hint='2nd_power_series_regular') == sol
  845. assert checkodesol(eq, sol) == (True, 0)
  846. eq = x*f(x).diff(x, 2) + f(x).diff(x) - a*x*f(x)
  847. sol = Eq(f(x), C1*(a**2*x**4/64 + a*x**2/4 + 1) + O(x**6))
  848. assert dsolve(eq, f(x), hint="2nd_power_series_regular") == sol
  849. assert checkodesol(eq, sol) == (True, 0)
  850. eq = f(x).diff(x, 2) + ((1 - x)/x)*f(x).diff(x) + (a/x)*f(x)
  851. sol = Eq(f(x), C1*(-a*x**5*(a - 4)*(a - 3)*(a - 2)*(a - 1)/14400 + \
  852. a*x**4*(a - 3)*(a - 2)*(a - 1)/576 - a*x**3*(a - 2)*(a - 1)/36 + \
  853. a*x**2*(a - 1)/4 - a*x + 1) + O(x**6))
  854. assert dsolve(eq, f(x), hint="2nd_power_series_regular") == sol
  855. assert checkodesol(eq, sol) == (True, 0)
  856. def test_issue_15056():
  857. t = Symbol('t')
  858. C3 = Symbol('C3')
  859. assert get_numbered_constants(Symbol('C1') * Function('C2')(t)) == C3
  860. def test_issue_15913():
  861. eq = -C1/x - 2*x*f(x) - f(x) + Derivative(f(x), x)
  862. sol = C2*exp(x**2 + x) + exp(x**2 + x)*Integral(C1*exp(-x**2 - x)/x, x)
  863. assert checkodesol(eq, sol) == (True, 0)
  864. sol = C1 + C2*exp(-x*y)
  865. eq = Derivative(y*f(x), x) + f(x).diff(x, 2)
  866. assert checkodesol(eq, sol, f(x)) == (True, 0)
  867. def test_issue_16146():
  868. raises(ValueError, lambda: dsolve([f(x).diff(x), g(x).diff(x)], [f(x), g(x), h(x)]))
  869. raises(ValueError, lambda: dsolve([f(x).diff(x), g(x).diff(x)], [f(x)]))
  870. def test_dsolve_remove_redundant_solutions():
  871. eq = (f(x)-2)*f(x).diff(x)
  872. sol = Eq(f(x), C1)
  873. assert dsolve(eq) == sol
  874. eq = (f(x)-sin(x))*(f(x).diff(x, 2))
  875. sol = {Eq(f(x), C1 + C2*x), Eq(f(x), sin(x))}
  876. assert set(dsolve(eq)) == sol
  877. eq = (f(x)**2-2*f(x)+1)*f(x).diff(x, 3)
  878. sol = Eq(f(x), C1 + C2*x + C3*x**2)
  879. assert dsolve(eq) == sol
  880. def test_issue_13060():
  881. A, B = symbols("A B", cls=Function)
  882. t = Symbol("t")
  883. eq = [Eq(Derivative(A(t), t), A(t)*B(t)), Eq(Derivative(B(t), t), A(t)*B(t))]
  884. sol = dsolve(eq)
  885. assert checkodesol(eq, sol) == (True, [0, 0])
  886. def test_issue_22523():
  887. N, s = symbols('N s')
  888. rho = Function('rho')
  889. # intentionally use 4.0 to confirm issue with nfloat
  890. # works here
  891. eqn = 4.0*N*sqrt(N - 1)*rho(s) + (4*s**2*(N - 1) + (N - 2*s*(N - 1))**2
  892. )*Derivative(rho(s), (s, 2))
  893. match = classify_ode(eqn, dict=True, hint='all')
  894. assert match['2nd_power_series_ordinary']['terms'] == 5
  895. C1, C2 = symbols('C1,C2')
  896. sol = dsolve(eqn, hint='2nd_power_series_ordinary')
  897. # there is no r(2.0) in this result
  898. assert filldedent(sol) == filldedent(str('''
  899. Eq(rho(s), C2*(1 - 4.0*s**4*sqrt(N - 1.0)/N + 0.666666666666667*s**4/N
  900. - 2.66666666666667*s**3*sqrt(N - 1.0)/N - 2.0*s**2*sqrt(N - 1.0)/N +
  901. 9.33333333333333*s**4*sqrt(N - 1.0)/N**2 - 0.666666666666667*s**4/N**2
  902. + 2.66666666666667*s**3*sqrt(N - 1.0)/N**2 -
  903. 5.33333333333333*s**4*sqrt(N - 1.0)/N**3) + C1*s*(1.0 -
  904. 1.33333333333333*s**3*sqrt(N - 1.0)/N - 0.666666666666667*s**2*sqrt(N
  905. - 1.0)/N + 1.33333333333333*s**3*sqrt(N - 1.0)/N**2) + O(s**6))'''))
  906. def test_issue_22604():
  907. x1, x2 = symbols('x1, x2', cls = Function)
  908. t, k1, k2, m1, m2 = symbols('t k1 k2 m1 m2', real = True)
  909. k1, k2, m1, m2 = 1, 1, 1, 1
  910. eq1 = Eq(m1*diff(x1(t), t, 2) + k1*x1(t) - k2*(x2(t) - x1(t)), 0)
  911. eq2 = Eq(m2*diff(x2(t), t, 2) + k2*(x2(t) - x1(t)), 0)
  912. eqs = [eq1, eq2]
  913. [x1sol, x2sol] = dsolve(eqs, [x1(t), x2(t)], ics = {x1(0):0, x1(t).diff().subs(t,0):0, \
  914. x2(0):1, x2(t).diff().subs(t,0):0})
  915. assert x1sol == Eq(x1(t), sqrt(3 - sqrt(5))*(sqrt(10) + 5*sqrt(2))*cos(sqrt(2)*t*sqrt(3 - sqrt(5))/2)/20 + \
  916. (-5*sqrt(2) + sqrt(10))*sqrt(sqrt(5) + 3)*cos(sqrt(2)*t*sqrt(sqrt(5) + 3)/2)/20)
  917. assert x2sol == Eq(x2(t), (sqrt(5) + 5)*cos(sqrt(2)*t*sqrt(3 - sqrt(5))/2)/10 + (5 - sqrt(5))*cos(sqrt(2)*t*sqrt(sqrt(5) + 3)/2)/10)
  918. def test_issue_22462():
  919. for de in [
  920. Eq(f(x).diff(x), -20*f(x)**2 - 500*f(x)/7200),
  921. Eq(f(x).diff(x), -2*f(x)**2 - 5*f(x)/7)]:
  922. assert 'Bernoulli' in classify_ode(de, f(x))