Guest User

Untitled

a guest
Sep 26th, 2018
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.09 KB | None | 0 0
  1. # FROM: "Comparing Numerical Methods for Ordinary Differential Equations"
  2. # T.E. Hull, W.H. Enright, B.M. Fellen and A.E. Sedgwidh
  3. # SIAM J. Numer. Anal. vol 9, no 4, December 1972, pp: 603-637
  4.  
  5. def deriv_B1(y, x):
  6. return [2.*(y[0]-y[0]*y[1]), -(y[1]-y[0]*y[1])] # "growth of two conflicting populations"
  7.  
  8. def deriv_B4(y, x):
  9. A = 1./np.sqrt(y[0]**2 + y[1]**2)
  10. return [-y[1] - A*y[0]*y[2], y[0] - A*y[1]*y[2], A*y[0]] # "integral surface of a torus"
  11.  
  12. def deriv_C1(y, x):
  13. return [-y[0]] + [y[i]-y[i+1] for i in range(8)] + [y[8]] # a radioactive decay chain
  14.  
  15. def deriv_D1toD5(y, x):
  16. A = -(y[0]**2 + y[1]**2)**-1.5
  17. return [y[2], y[3], A*y[0], A*y[1]] # dimensionless orbit equation
  18.  
  19. deriv_D1, deriv_D5 = deriv_D1toD5, deriv_D1toD5
  20.  
  21. def deriv_E1(y, x):
  22. return [y[1], -(y[1]/(x+1.0) + (1.0 - 0.25/(x+1.0)**2)*y[0])] # derived from Bessel's equation of order 1/2
  23.  
  24. def deriv_E3(y, x):
  25. return [y[1], y[0]**3/6.0 - y[0] + 2.0*np.sin(2.78535*x)] # derived from Duffing's equation
  26.  
  27. import numpy as np
  28. from scipy.integrate import odeint as ODEint
  29. import matplotlib.pyplot as plt
  30. import timeit
  31.  
  32. y0_B1 = [1.0, 3.0]
  33. y0_B4 = [3.0, 0.0, 0.0]
  34. y0_C1 = [1.0] + [0.0 for i in range(9)]
  35. ep1, ep5 = 0.1, 0.9
  36. y0_D1 = [1.0-ep1, 0.0, 0.0, np.sqrt((1.0+ep1)/(1.0-ep1))]
  37. y0_D5 = [1.0-ep5, 0.0, 0.0, np.sqrt((1.0+ep5)/(1.0-ep5))]
  38. y0_E1 = [0.6713968071418030, 0.09540051444747446] # J(1/2, 1), Jprime(1/2, 1)
  39. y0_E3 = [0.0, 0.0]
  40.  
  41. x = np.linspace(0, 20, 51)
  42. xa = np.linspace(0, 20, 2001)
  43.  
  44. derivs = [deriv_B1, deriv_B4, deriv_C1, deriv_D1, deriv_D5, deriv_E3]
  45. names = ["deriv_B1", "deriv_B4", "deriv_C1", "deriv_D1", "deriv_D5", "deriv_E3"]
  46. y0s = [y0_B1, y0_B4, y0_C1, y0_D1, y0_D5, y0_E3]
  47.  
  48. timeit_dict, answer_dict, info_dict = dict(), dict(), dict()
  49.  
  50. ntimes = 10
  51. tols = [10.**-i for i in range(6, 14)]
  52.  
  53. def F(): # low density of time points, no output for speed test
  54. ODEint(deriv, y0, x, rtol=tol, atol=tol)
  55. def Fa(): # hight density of time points, full output for plotting
  56. return ODEint(deriv, y0, xa, rtol=tol, atol=tol, full_output=True)
  57.  
  58. for deriv, y0, name in zip(derivs, y0s, names):
  59. timez = [timeit.timeit(F, number=ntimes)/float(ntimes) for tol in tols]
  60. timeit_dict[name] = timez
  61. alist, dlist = zip(*[Fa() for tol in tols])
  62. answer_dict[name] = np.array([a.T for a in alist])
  63. info_dict[name] = dlist
  64.  
  65. plt.figure(figsize=[10,6])
  66.  
  67. for i, name in enumerate(names):
  68. plt.subplot(2, 3, i+1)
  69. for thing in answer_dict[name][-1]:
  70. plt.plot(xa, thing)
  71. plt.title(name[-2:], fontsize=16)
  72. plt.show()
  73.  
  74. plt.figure(figsize=[10, 8])
  75. for i, name in enumerate(names):
  76. plt.subplot(2,3,i+1)
  77. a = answer_dict[name]
  78. a13, a10, a8 = a[-1], a[-4], a[-6]
  79. d10 = np.abs(a10-a13).max(axis=0)
  80. d8 = np.abs(a8 -a13).max(axis=0)
  81. plt.plot(xa, d10, label="tol(1E-10)-tol(1E-13)")
  82. plt.plot(xa, d8, label="tol(1E-08)-tol(1E-13)")
  83. plt.yscale('log')
  84. plt.ylim(1E-11, 1E-03)
  85. plt.title(name[-2:], fontsize=16)
  86. if i==3:
  87. plt.text(3, 1E-10, "1E-10 - 1E-13", fontsize=14)
  88. plt.text(2, 2E-05, "1E-08 - 1E-13", fontsize=14)
  89. plt.show()
  90.  
  91. fs = 16
  92. plt.figure(figsize=[12,6])
  93.  
  94. plt.subplot(1,3,1)
  95. for name in names:
  96. plt.plot(tols, timeit_dict[name])
  97. plt.title("timing results", fontsize=16)
  98. plt.xscale('log')
  99. plt.yscale('log')
  100. plt.text(1E-09, 5E-02, "D5", fontsize=fs)
  101. plt.text(1E-09, 4.5E-03, "C1", fontsize=fs)
  102.  
  103. plt.subplot(1,3,2)
  104. for name in names:
  105. a = answer_dict[name]
  106. e = a[:-1] - a[-1]
  107. em = [np.abs(thing).max() for thing in e]
  108. plt.plot(tols[:-1], em)
  109. plt.title("max difference from smallest tol", fontsize=16)
  110. plt.xscale('log')
  111. plt.yscale('log')
  112. plt.xlim(min(tols), max(tols))
  113. plt.text(1E-09, 3E-03, "D5", fontsize=fs)
  114. plt.text(1E-09, 8E-11, "C1", fontsize=fs)
  115.  
  116. plt.subplot(1,3,3)
  117. for name in names:
  118. nsteps = [d['nst'][-1] for d in info_dict[name]]
  119. plt.plot(tols, nsteps, label=name[-2:])
  120. plt.title("number of steps", fontsize=16)
  121. plt.xscale('log')
  122. plt.yscale('log')
  123. plt.ylim(3E+01, 3E+03)
  124. plt.legend(loc="upper right", shadow=False, fontsize="large")
  125. plt.text(2E-12, 2.3E+03, "D5", fontsize=fs)
  126. plt.text(2E-12, 1.5E+02, "C1", fontsize=fs)
  127.  
  128. plt.show()
Add Comment
Please, Sign In to add comment