Skip to content

Commit 48ec7d5

Browse files
Merge pull request sympy#20267 from Mohitbalwani26/refactor(test_ode)_1st_exact
refactor(test_ode.py): 1st_exact examples
2 parents 8df7482 + ed5eb67 commit 48ec7d5

File tree

2 files changed

+129
-120
lines changed

2 files changed

+129
-120
lines changed

sympy/solvers/ode/tests/test_ode.py

Lines changed: 2 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
from sympy import (acos, acosh, asinh, atan, cos, Derivative, diff,
1+
from sympy import (acos, acosh, atan, cos, Derivative, diff,
22
Dummy, Eq, Ne, exp, Function, I, Integral, LambertW, log, O, pi,
33
Rational, rootof, S, sin, sqrt, Subs, Symbol, tan, asin, sinh,
4-
Piecewise, symbols, Poly, sec, re, im, atan2, collect, hyper, integrate)
4+
Piecewise, symbols, Poly, sec, re, im, atan2, collect, hyper)
55

66
from sympy.solvers.ode import (classify_ode,
77
homogeneous_order, infinitesimals, checkinfsol,
@@ -813,79 +813,6 @@ def test_old_ode_tests():
813813
assert checkodesol(eq11, sol11, order=1, solve_for_func=False)[0]
814814

815815

816-
@slow
817-
def test_1st_exact1():
818-
# Type: Exact differential equation, p(x,f) + q(x,f)*f' == 0,
819-
# where dp/df == dq/dx
820-
eq1 = sin(x)*cos(f(x)) + cos(x)*sin(f(x))*f(x).diff(x)
821-
eq2 = (2*x*f(x) + 1)/f(x) + (f(x) - x)/f(x)**2*f(x).diff(x)
822-
eq3 = 2*x + f(x)*cos(x) + (2*f(x) + sin(x) - sin(f(x)))*f(x).diff(x)
823-
eq4 = cos(f(x)) - (x*sin(f(x)) - f(x)**2)*f(x).diff(x)
824-
eq5 = 2*x*f(x) + (x**2 + f(x)**2)*f(x).diff(x)
825-
sol1 = [Eq(f(x), -acos(C1/cos(x)) + 2*pi), Eq(f(x), acos(C1/cos(x)))]
826-
sol2 = Eq(f(x), exp(C1 - x**2 + LambertW(-x*exp(-C1 + x**2))))
827-
sol2b = Eq(log(f(x)) + x/f(x) + x**2, C1)
828-
sol3 = Eq(f(x)*sin(x) + cos(f(x)) + x**2 + f(x)**2, C1)
829-
sol4 = Eq(x*cos(f(x)) + f(x)**3/3, C1)
830-
sol5 = Eq(x**2*f(x) + f(x)**3/3, C1)
831-
assert dsolve(eq1, f(x), hint='1st_exact') == sol1
832-
assert dsolve(eq2, f(x), hint='1st_exact') == sol2
833-
assert dsolve(eq3, f(x), hint='1st_exact') == sol3
834-
assert dsolve(eq4, hint='1st_exact') == sol4
835-
assert dsolve(eq5, hint='1st_exact', simplify=False) == sol5
836-
assert checkodesol(eq1, sol1, order=1, solve_for_func=False)[0]
837-
# issue 5080 blocks the testing of this solution
838-
# FIXME: assert checkodesol(eq2, sol2, order=1, solve_for_func=False)[0]
839-
assert checkodesol(eq2, sol2b, order=1, solve_for_func=False)[0]
840-
assert checkodesol(eq3, sol3, order=1, solve_for_func=False)[0]
841-
assert checkodesol(eq4, sol4, order=1, solve_for_func=False)[0]
842-
assert checkodesol(eq5, sol5, order=1, solve_for_func=False)[0]
843-
844-
845-
@slow
846-
@XFAIL
847-
def test_1st_exact2_broken():
848-
"""
849-
This is an exact equation that fails under the exact engine. It is caught
850-
by first order homogeneous albeit with a much contorted solution. The
851-
exact engine fails because of a poorly simplified integral of q(0,y)dy,
852-
where q is the function multiplying f'. The solutions should be
853-
Eq(sqrt(x**2+f(x)**2)**3+y**3, C1). The equation below is
854-
equivalent, but it is so complex that checkodesol fails, and takes a long
855-
time to do so.
856-
"""
857-
if ON_TRAVIS:
858-
skip("Too slow for travis.")
859-
eq = (x*sqrt(x**2 + f(x)**2) - (x**2*f(x)/(f(x) -
860-
sqrt(x**2 + f(x)**2)))*f(x).diff(x))
861-
sol = Eq(log(x),
862-
C1 - 9*sqrt(1 + f(x)**2/x**2)*asinh(f(x)/x)/(-27*f(x)/x +
863-
27*sqrt(1 + f(x)**2/x**2)) - 9*sqrt(1 + f(x)**2/x**2)*
864-
log(1 - sqrt(1 + f(x)**2/x**2)*f(x)/x + 2*f(x)**2/x**2)/
865-
(-27*f(x)/x + 27*sqrt(1 + f(x)**2/x**2)) +
866-
9*asinh(f(x)/x)*f(x)/(x*(-27*f(x)/x + 27*sqrt(1 + f(x)**2/x**2))) +
867-
9*f(x)*log(1 - sqrt(1 + f(x)**2/x**2)*f(x)/x + 2*f(x)**2/x**2)/
868-
(x*(-27*f(x)/x + 27*sqrt(1 + f(x)**2/x**2))))
869-
assert dsolve(eq) == sol # Slow
870-
# FIXME: Checked in test_1st_exact2_broken_check below
871-
872-
873-
@slow
874-
def test_1st_exact2_broken_check():
875-
# See test_1st_exact2_broken above
876-
eq = (x*sqrt(x**2 + f(x)**2) - (x**2*f(x)/(f(x) -
877-
sqrt(x**2 + f(x)**2)))*f(x).diff(x))
878-
sol = Eq(log(x),
879-
C1 - 9*sqrt(1 + f(x)**2/x**2)*asinh(f(x)/x)/(-27*f(x)/x +
880-
27*sqrt(1 + f(x)**2/x**2)) - 9*sqrt(1 + f(x)**2/x**2)*
881-
log(1 - sqrt(1 + f(x)**2/x**2)*f(x)/x + 2*f(x)**2/x**2)/
882-
(-27*f(x)/x + 27*sqrt(1 + f(x)**2/x**2)) +
883-
9*asinh(f(x)/x)*f(x)/(x*(-27*f(x)/x + 27*sqrt(1 + f(x)**2/x**2))) +
884-
9*f(x)*log(1 - sqrt(1 + f(x)**2/x**2)*f(x)/x + 2*f(x)**2/x**2)/
885-
(x*(-27*f(x)/x + 27*sqrt(1 + f(x)**2/x**2))))
886-
assert checkodesol(eq, sol, order=1, solve_for_func=False)[0]
887-
888-
889816
def test_homogeneous_order():
890817
assert homogeneous_order(exp(y/x) + tan(y/x), x, y) == 0
891818
assert homogeneous_order(x**2 + sin(x)*cos(y), x, y) is None
@@ -2371,18 +2298,6 @@ def test_issue_10867():
23712298
assert checkodesol(eq, sol, order=2, solve_for_func=False) == (True, 0)
23722299

23732300

2374-
def test_issue_11290():
2375-
eq = cos(f(x)) - (x*sin(f(x)) - f(x)**2)*f(x).diff(x)
2376-
sol_1 = dsolve(eq, f(x), simplify=False, hint='1st_exact_Integral')
2377-
sol_0 = dsolve(eq, f(x), simplify=False, hint='1st_exact')
2378-
assert sol_1.dummy_eq(Eq(Subs(
2379-
Integral(u**2 - x*sin(u) - Integral(-sin(u), x), u) +
2380-
Integral(cos(u), x), u, f(x)), C1))
2381-
assert sol_1.doit() == sol_0
2382-
assert checkodesol(eq, sol_0, order=1, solve_for_func=False)
2383-
assert checkodesol(eq, sol_1, order=1, solve_for_func=False)
2384-
2385-
23862301
def test_issue_4838():
23872302
# Issue #15999
23882303
eq = f(x).diff(x) - C1*f(x)
@@ -2571,21 +2486,3 @@ def test_issue_18408():
25712486
sol = Eq(f(x), C1 + C3*exp(-x) + x*sinh(x)/2 + (C2 + x/2)*exp(x))
25722487
assert sol == dsolve(eq, hint='nth_linear_constant_coeff_undetermined_coefficients')
25732488
assert checkodesol(eq, sol) == (True, 0)
2574-
2575-
2576-
def test_issue_9446():
2577-
f = Function('f')
2578-
assert dsolve(Eq(f(2 * x), sin(Derivative(f(x)))), f(x)) == \
2579-
[Eq(f(x), C1 + pi*x - Integral(asin(f(2*x)), x)), Eq(f(x), C1 + Integral(asin(f(2*x)), x))]
2580-
2581-
assert integrate(-asin(f(2*x)+pi), x) == -Integral(asin(pi + f(2*x)), x)
2582-
2583-
def test_issue_20192():
2584-
# kamke ode 1.1
2585-
a0,a1,a2,a3,a4 = symbols('a0, a1, a2, a3, a4')
2586-
2587-
eq = f(x).diff(x)-(a4*x**4 + a3*x**3 + a2*x**2 + a1*x + a0)**(-1/2)
2588-
sol = Eq(f(x), C1 + Integral(1/sqrt(a0 + a1*x + a2*x**2 + a3*x**3 + a4*x**4), x))
2589-
2590-
assert sol == dsolve(eq,hint='factorable')
2591-
assert checkodesol(eq, sol) == (True, 0)

sympy/solvers/ode/tests/test_single.py

Lines changed: 127 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@
3232
ODEs which raises exception.
3333
3434
"""
35-
from sympy import (acos, asin, atan, cos, Derivative, Dummy, diff,
36-
E, Eq, exp, I, log, pi, Piecewise, Rational, S, sin, sinh, tan,
35+
from sympy import (acos, asin, asinh, atan, cos, Derivative, Dummy, diff,
36+
E, Eq, exp, I, Integral, integrate, LambertW, log, pi, Piecewise, Rational, S, sin, sinh, tan,
3737
sqrt, symbols, Ei, erfi)
3838

3939
from sympy.core import Function, Symbol
@@ -46,7 +46,7 @@
4646

4747
from sympy.solvers.ode.subscheck import checkodesol
4848

49-
from sympy.testing.pytest import raises, slow
49+
from sympy.testing.pytest import raises, slow, ON_TRAVIS
5050
import traceback
5151

5252

@@ -150,7 +150,10 @@ def _ode_solver_test(ode_examples, run_slow_test=False):
150150
'func': ode_examples['examples'][example].get('func',ode_examples['func']),
151151
'example_name': example,
152152
'slow': ode_examples['examples'][example].get('slow', False),
153-
'checkodesol_XFAIL': ode_examples['examples'][example].get('checkodesol_XFAIL', False)
153+
'simplify_flag':ode_examples['examples'][example].get('simplify_flag',True),
154+
'checkodesol_XFAIL': ode_examples['examples'][example].get('checkodesol_XFAIL', False),
155+
'dsolve_too_slow':ode_examples['examples'][example].get('dsolve_too_slow',False),
156+
'checkodesol_too_slow':ode_examples['examples'][example].get('checkodesol_too_slow',False),
154157
}
155158
if (not run_slow_test) and temp['slow']:
156159
continue
@@ -191,7 +194,10 @@ def _test_particular_example(our_hint, ode_example, solver_flag=False):
191194
xfail = our_hint in ode_example['XFAIL']
192195
func = ode_example['func']
193196
result = {'msg': '', 'xpass_msg': ''}
197+
simplify_flag=ode_example['simplify_flag']
194198
checkodesol_XFAIL = ode_example['checkodesol_XFAIL']
199+
dsolve_too_slow = ode_example['dsolve_too_slow']
200+
checkodesol_too_slow = ode_example['checkodesol_too_slow']
195201
xpass = True
196202
if solver_flag:
197203
if our_hint not in classify_ode(eq, func):
@@ -201,7 +207,13 @@ def _test_particular_example(our_hint, ode_example, solver_flag=False):
201207
if our_hint in classify_ode(eq, func):
202208
result['match_list'] = example
203209
try:
204-
dsolve_sol = dsolve(eq, func, hint=our_hint)
210+
if not (dsolve_too_slow and ON_TRAVIS):
211+
dsolve_sol = dsolve(eq, func, simplify=simplify_flag,hint=our_hint)
212+
else:
213+
if len(expected_sol)==1:
214+
dsolve_sol = expected_sol[0]
215+
else:
216+
dsolve_sol = expected_sol
205217

206218
except Exception as e:
207219
dsolve_sol = []
@@ -235,16 +247,17 @@ def _test_particular_example(our_hint, ode_example, solver_flag=False):
235247
if len(expected_sol) == 1:
236248
expected_checkodesol = (True, 0)
237249

238-
if not checkodesol_XFAIL:
239-
if checkodesol(eq, dsolve_sol, solve_for_func=False) != expected_checkodesol:
240-
result['unsolve_list'] = example
241-
xpass = False
242-
message = dsol_incorrect_msg.format(hint=our_hint, eq=eq, sol=expected_sol,dsolve_sol=dsolve_sol)
243-
if solver_flag:
244-
message = checkodesol_msg.format(example=example, eq=eq)
245-
raise AssertionError(message)
246-
else:
247-
result['msg'] = 'AssertionError: ' + message
250+
if not (checkodesol_too_slow and ON_TRAVIS):
251+
if not checkodesol_XFAIL:
252+
if checkodesol(eq, dsolve_sol, solve_for_func=False) != expected_checkodesol:
253+
result['unsolve_list'] = example
254+
xpass = False
255+
message = dsol_incorrect_msg.format(hint=our_hint, eq=eq, sol=expected_sol,dsolve_sol=dsolve_sol)
256+
if solver_flag:
257+
message = checkodesol_msg.format(example=example, eq=eq)
258+
raise AssertionError(message)
259+
else:
260+
result['msg'] = 'AssertionError: ' + message
248261

249262
if xpass and xfail:
250263
result['xpass_msg'] = example + "is now passing for the hint" + our_hint
@@ -318,6 +331,14 @@ def test_nth_algebraic():
318331
_ode_solver_test(_get_examples_ode_sol_nth_algebraic())
319332

320333

334+
@slow
335+
def test_slow_examples_1st_exact():
336+
eq = cos(f(x)) - (x*sin(f(x)) - f(x)**2)*f(x).diff(x)
337+
sol_1 = dsolve(eq, f(x), simplify=False, hint='1st_exact_Integral')
338+
assert checkodesol(eq, sol_1, order=1, solve_for_func=False)
339+
_ode_solver_test(_get_examples_ode_sol_1st_exact(), run_slow_test=True)
340+
341+
321342
@slow
322343
def test_slow_examples_nth_order_reducible():
323344
_ode_solver_test(_get_examples_ode_sol_nth_order_reducible(), run_slow_test=True)
@@ -357,6 +378,7 @@ def test_separable():
357378

358379

359380
def test_factorable():
381+
assert integrate(-asin(f(2*x)+pi), x) == -Integral(asin(pi + f(2*x)), x)
360382
_ode_solver_test(_get_examples_ode_sol_factorable())
361383

362384

@@ -601,6 +623,7 @@ def _get_examples_ode_sol_factorable():
601623
nth_linear_constant_coeff_undetermined_coefficients"""
602624

603625
y = Dummy('y')
626+
a0,a1,a2,a3,a4 = symbols('a0, a1, a2, a3, a4')
604627
return {
605628
'hint': "factorable",
606629
'func': f(x),
@@ -703,6 +726,19 @@ def _get_examples_ode_sol_factorable():
703726
'eq': f(x).diff(x)**2 - f(x)**3,
704727
'sol': [Eq(f(x), 4/(C1**2 - 2*C1*x + x**2))]
705728
},
729+
730+
# kamke ode 1.1
731+
'fact_17': {
732+
'eq': f(x).diff(x)-(a4*x**4 + a3*x**3 + a2*x**2 + a1*x + a0)**(-1/2),
733+
'sol': [Eq(f(x), C1 + Integral(1/sqrt(a0 + a1*x + a2*x**2 + a3*x**3 + a4*x**4), x))]
734+
},
735+
736+
# This is from issue: https://github.com/sympy/sympy/issues/9446
737+
'fact_18':{
738+
'eq': Eq(f(2 * x), sin(Derivative(f(x)))),
739+
'sol': [Eq(f(x), C1 + pi*x - Integral(asin(f(2*x)), x)), Eq(f(x), C1 + Integral(asin(f(2*x)), x))],
740+
'checkodesol_XFAIL':True
741+
},
706742
}
707743
}
708744

@@ -1284,6 +1320,80 @@ def _get_examples_ode_sol_separable():
12841320
}
12851321

12861322

1323+
def _get_examples_ode_sol_1st_exact():
1324+
# Type: Exact differential equation, p(x,f) + q(x,f)*f' == 0,
1325+
# where dp/df == dq/dx
1326+
'''
1327+
Example 7 is an exact equation that fails under the exact engine. It is caught
1328+
by first order homogeneous albeit with a much contorted solution. The
1329+
exact engine fails because of a poorly simplified integral of q(0,y)dy,
1330+
where q is the function multiplying f'. The solutions should be
1331+
Eq(sqrt(x**2+f(x)**2)**3+y**3, C1). The equation below is
1332+
equivalent, but it is so complex that checkodesol fails, and takes a long
1333+
time to do so.
1334+
'''
1335+
return {
1336+
'hint': "1st_exact",
1337+
'func': f(x),
1338+
'examples':{
1339+
'1st_exact_01': {
1340+
'eq': sin(x)*cos(f(x)) + cos(x)*sin(f(x))*f(x).diff(x),
1341+
'sol': [Eq(f(x), -acos(C1/cos(x)) + 2*pi), Eq(f(x), acos(C1/cos(x)))],
1342+
'slow': True,
1343+
},
1344+
1345+
'1st_exact_02': {
1346+
'eq': (2*x*f(x) + 1)/f(x) + (f(x) - x)/f(x)**2*f(x).diff(x),
1347+
'sol': [Eq(f(x), exp(C1 - x**2 + LambertW(-x*exp(-C1 + x**2))))],
1348+
'XFAIL': ['lie_group'], #It shows dsolve raises an exception: List index out of range for lie_group
1349+
'slow': True,
1350+
'checkodesol_XFAIL':True
1351+
},
1352+
1353+
'1st_exact_03': {
1354+
'eq': 2*x + f(x)*cos(x) + (2*f(x) + sin(x) - sin(f(x)))*f(x).diff(x),
1355+
'sol': [Eq(f(x)*sin(x) + cos(f(x)) + x**2 + f(x)**2, C1)],
1356+
'XFAIL': ['lie_group'], #It goes into infinite loop for lie_group.
1357+
'slow': True,
1358+
},
1359+
1360+
'1st_exact_04': {
1361+
'eq': cos(f(x)) - (x*sin(f(x)) - f(x)**2)*f(x).diff(x),
1362+
'sol': [Eq(x*cos(f(x)) + f(x)**3/3, C1)],
1363+
'slow': True,
1364+
},
1365+
1366+
'1st_exact_05': {
1367+
'eq': 2*x*f(x) + (x**2 + f(x)**2)*f(x).diff(x),
1368+
'sol': [Eq(x**2*f(x) + f(x)**3/3, C1)],
1369+
'slow': True,
1370+
'simplify_flag':False
1371+
},
1372+
1373+
# This was from issue: https://github.com/sympy/sympy/issues/11290
1374+
'1st_exact_06': {
1375+
'eq': cos(f(x)) - (x*sin(f(x)) - f(x)**2)*f(x).diff(x),
1376+
'sol': [Eq(x*cos(f(x)) + f(x)**3/3, C1)],
1377+
'simplify_flag':False
1378+
},
1379+
1380+
'1st_exact_07': {
1381+
'eq': x*sqrt(x**2 + f(x)**2) - (x**2*f(x)/(f(x) - sqrt(x**2 + f(x)**2)))*f(x).diff(x),
1382+
'sol': [Eq(log(x),
1383+
C1 - 9*sqrt(1 + f(x)**2/x**2)*asinh(f(x)/x)/(-27*f(x)/x +
1384+
27*sqrt(1 + f(x)**2/x**2)) - 9*sqrt(1 + f(x)**2/x**2)*
1385+
log(1 - sqrt(1 + f(x)**2/x**2)*f(x)/x + 2*f(x)**2/x**2)/
1386+
(-27*f(x)/x + 27*sqrt(1 + f(x)**2/x**2)) +
1387+
9*asinh(f(x)/x)*f(x)/(x*(-27*f(x)/x + 27*sqrt(1 + f(x)**2/x**2))) +
1388+
9*f(x)*log(1 - sqrt(1 + f(x)**2/x**2)*f(x)/x + 2*f(x)**2/x**2)/
1389+
(x*(-27*f(x)/x + 27*sqrt(1 + f(x)**2/x**2))))],
1390+
'slow': True,
1391+
'dsolve_too_slow':True
1392+
},
1393+
}
1394+
}
1395+
1396+
12871397
def _get_all_examples():
12881398
all_solvers = [_get_examples_ode_sol_euler_homogeneous(),
12891399
_get_examples_ode_sol_euler_undetermined_coeff(),
@@ -1293,6 +1403,7 @@ def _get_all_examples():
12931403
_get_examples_ode_sol_nth_algebraic(),
12941404
_get_examples_ode_sol_riccati(),
12951405
_get_examples_ode_sol_1st_linear(),
1406+
_get_examples_ode_sol_1st_exact(),
12961407
_get_examples_ode_sol_almost_linear(),
12971408
_get_examples_ode_sol_nth_order_reducible(),
12981409
_get_examples_ode_sol_nth_linear_undetermined_coefficients(),
@@ -1309,6 +1420,7 @@ def _get_all_examples():
13091420
'eq': solver['examples'][example]['eq'],
13101421
'sol': solver['examples'][example]['sol'],
13111422
'XFAIL': solver['examples'][example].get('XFAIL',[]),
1423+
'simplify_flag':solver['examples'][example].get('simplify_flag',True),
13121424
'checkodesol_XFAIL': solver['examples'][example].get('checkodesol_XFAIL', False),
13131425
'example_name': example,
13141426
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy