test_odeint_jac.py 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import numpy as np
  2. from numpy.testing import assert_equal, assert_allclose
  3. from scipy.integrate import odeint
  4. import scipy.integrate._test_odeint_banded as banded5x5
  5. def rhs(y, t):
  6. dydt = np.zeros_like(y)
  7. banded5x5.banded5x5(t, y, dydt)
  8. return dydt
  9. def jac(y, t):
  10. n = len(y)
  11. jac = np.zeros((n, n), order='F')
  12. banded5x5.banded5x5_jac(t, y, 1, 1, jac)
  13. return jac
  14. def bjac(y, t):
  15. n = len(y)
  16. bjac = np.zeros((4, n), order='F')
  17. banded5x5.banded5x5_bjac(t, y, 1, 1, bjac)
  18. return bjac
  19. JACTYPE_FULL = 1
  20. JACTYPE_BANDED = 4
  21. def check_odeint(jactype):
  22. if jactype == JACTYPE_FULL:
  23. ml = None
  24. mu = None
  25. jacobian = jac
  26. elif jactype == JACTYPE_BANDED:
  27. ml = 2
  28. mu = 1
  29. jacobian = bjac
  30. else:
  31. raise ValueError("invalid jactype: %r" % (jactype,))
  32. y0 = np.arange(1.0, 6.0)
  33. # These tolerances must match the tolerances used in banded5x5.f.
  34. rtol = 1e-11
  35. atol = 1e-13
  36. dt = 0.125
  37. nsteps = 64
  38. t = dt * np.arange(nsteps+1)
  39. sol, info = odeint(rhs, y0, t,
  40. Dfun=jacobian, ml=ml, mu=mu,
  41. atol=atol, rtol=rtol, full_output=True)
  42. yfinal = sol[-1]
  43. odeint_nst = info['nst'][-1]
  44. odeint_nfe = info['nfe'][-1]
  45. odeint_nje = info['nje'][-1]
  46. y1 = y0.copy()
  47. # Pure Fortran solution. y1 is modified in-place.
  48. nst, nfe, nje = banded5x5.banded5x5_solve(y1, nsteps, dt, jactype)
  49. # It is likely that yfinal and y1 are *exactly* the same, but
  50. # we'll be cautious and use assert_allclose.
  51. assert_allclose(yfinal, y1, rtol=1e-12)
  52. assert_equal((odeint_nst, odeint_nfe, odeint_nje), (nst, nfe, nje))
  53. def test_odeint_full_jac():
  54. check_odeint(JACTYPE_FULL)
  55. def test_odeint_banded_jac():
  56. check_odeint(JACTYPE_BANDED)