32
32
ODEs which raises exception.
33
33
34
34
"""
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 ,
37
37
sqrt , symbols , Ei , erfi )
38
38
39
39
from sympy .core import Function , Symbol
46
46
47
47
from sympy .solvers .ode .subscheck import checkodesol
48
48
49
- from sympy .testing .pytest import raises , slow
49
+ from sympy .testing .pytest import raises , slow , ON_TRAVIS
50
50
import traceback
51
51
52
52
@@ -150,7 +150,10 @@ def _ode_solver_test(ode_examples, run_slow_test=False):
150
150
'func' : ode_examples ['examples' ][example ].get ('func' ,ode_examples ['func' ]),
151
151
'example_name' : example ,
152
152
'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 ),
154
157
}
155
158
if (not run_slow_test ) and temp ['slow' ]:
156
159
continue
@@ -191,7 +194,10 @@ def _test_particular_example(our_hint, ode_example, solver_flag=False):
191
194
xfail = our_hint in ode_example ['XFAIL' ]
192
195
func = ode_example ['func' ]
193
196
result = {'msg' : '' , 'xpass_msg' : '' }
197
+ simplify_flag = ode_example ['simplify_flag' ]
194
198
checkodesol_XFAIL = ode_example ['checkodesol_XFAIL' ]
199
+ dsolve_too_slow = ode_example ['dsolve_too_slow' ]
200
+ checkodesol_too_slow = ode_example ['checkodesol_too_slow' ]
195
201
xpass = True
196
202
if solver_flag :
197
203
if our_hint not in classify_ode (eq , func ):
@@ -201,7 +207,13 @@ def _test_particular_example(our_hint, ode_example, solver_flag=False):
201
207
if our_hint in classify_ode (eq , func ):
202
208
result ['match_list' ] = example
203
209
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
205
217
206
218
except Exception as e :
207
219
dsolve_sol = []
@@ -235,16 +247,17 @@ def _test_particular_example(our_hint, ode_example, solver_flag=False):
235
247
if len (expected_sol ) == 1 :
236
248
expected_checkodesol = (True , 0 )
237
249
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
248
261
249
262
if xpass and xfail :
250
263
result ['xpass_msg' ] = example + "is now passing for the hint" + our_hint
@@ -318,6 +331,14 @@ def test_nth_algebraic():
318
331
_ode_solver_test (_get_examples_ode_sol_nth_algebraic ())
319
332
320
333
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
+
321
342
@slow
322
343
def test_slow_examples_nth_order_reducible ():
323
344
_ode_solver_test (_get_examples_ode_sol_nth_order_reducible (), run_slow_test = True )
@@ -357,6 +378,7 @@ def test_separable():
357
378
358
379
359
380
def test_factorable ():
381
+ assert integrate (- asin (f (2 * x )+ pi ), x ) == - Integral (asin (pi + f (2 * x )), x )
360
382
_ode_solver_test (_get_examples_ode_sol_factorable ())
361
383
362
384
@@ -601,6 +623,7 @@ def _get_examples_ode_sol_factorable():
601
623
nth_linear_constant_coeff_undetermined_coefficients"""
602
624
603
625
y = Dummy ('y' )
626
+ a0 ,a1 ,a2 ,a3 ,a4 = symbols ('a0, a1, a2, a3, a4' )
604
627
return {
605
628
'hint' : "factorable" ,
606
629
'func' : f (x ),
@@ -703,6 +726,19 @@ def _get_examples_ode_sol_factorable():
703
726
'eq' : f (x ).diff (x )** 2 - f (x )** 3 ,
704
727
'sol' : [Eq (f (x ), 4 / (C1 ** 2 - 2 * C1 * x + x ** 2 ))]
705
728
},
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
+ },
706
742
}
707
743
}
708
744
@@ -1284,6 +1320,80 @@ def _get_examples_ode_sol_separable():
1284
1320
}
1285
1321
1286
1322
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
+
1287
1397
def _get_all_examples ():
1288
1398
all_solvers = [_get_examples_ode_sol_euler_homogeneous (),
1289
1399
_get_examples_ode_sol_euler_undetermined_coeff (),
@@ -1293,6 +1403,7 @@ def _get_all_examples():
1293
1403
_get_examples_ode_sol_nth_algebraic (),
1294
1404
_get_examples_ode_sol_riccati (),
1295
1405
_get_examples_ode_sol_1st_linear (),
1406
+ _get_examples_ode_sol_1st_exact (),
1296
1407
_get_examples_ode_sol_almost_linear (),
1297
1408
_get_examples_ode_sol_nth_order_reducible (),
1298
1409
_get_examples_ode_sol_nth_linear_undetermined_coefficients (),
@@ -1309,6 +1420,7 @@ def _get_all_examples():
1309
1420
'eq' : solver ['examples' ][example ]['eq' ],
1310
1421
'sol' : solver ['examples' ][example ]['sol' ],
1311
1422
'XFAIL' : solver ['examples' ][example ].get ('XFAIL' ,[]),
1423
+ 'simplify_flag' :solver ['examples' ][example ].get ('simplify_flag' ,True ),
1312
1424
'checkodesol_XFAIL' : solver ['examples' ][example ].get ('checkodesol_XFAIL' , False ),
1313
1425
'example_name' : example ,
1314
1426
}
0 commit comments