finite_differences.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. """
  2. Illustrate forward, backward and centered finite differences
  3. in four figures.
  4. """
  5. from pysketcher import *
  6. #test_test()
  7. xaxis = 2
  8. drawing_tool.set_coordinate_system(0, 7, 1, 6, axis=False)
  9. f = SketchyFunc1('$u(t)$')
  10. x = 3 # center point where we want the derivative
  11. xb = 2 # x point used for backward difference
  12. xf = 4 # x point used for forward difference
  13. p = (x, f(x)) # center point
  14. pf = (xf, f(xf)) # forward point
  15. pb = (xb, f(xb)) # backward point
  16. r = 0.1 # radius of circles placed at key points
  17. c = Circle(p, r).set_linecolor('blue')
  18. cf = Circle(pf, r).set_linecolor('red')
  19. cb = Circle(pb, r).set_linecolor('green')
  20. # Points in the mesh
  21. p0 = point(x, xaxis) # center point
  22. pf0 = point(xf, xaxis) # forward point
  23. pb0 = point(xb, xaxis) # backward point
  24. tick = 0.05
  25. # 1D mesh with three points
  26. mesh = Composition({
  27. 'tnm1': Text('$t_{n-1}$', pb0 - point(0, 0.3)),
  28. 'tn': Text('$t_{n}$', p0 - point(0, 0.3)),
  29. 'tnp1': Text('$t_{n+1}$', pf0 - point(0, 0.3)),
  30. 'axis': Composition({
  31. 'hline': Line(pf0-point(3,0), pb0+point(3,0)).\
  32. set_linecolor('black').set_linewidth(1),
  33. 'tick_m1': Line(pf0+point(0,tick), pf0-point(0,tick)).\
  34. set_linecolor('black').set_linewidth(1),
  35. 'tick_n': Line(p0+point(0,tick), p0-point(0,tick)).\
  36. set_linecolor('black').set_linewidth(1),
  37. 'tick_p1': Line(pb0+point(0,tick), pb0-point(0,tick)).\
  38. set_linecolor('black').set_linewidth(1)}),
  39. })
  40. # Vertical dotted lines at each mesh point
  41. vlinec = Line(p, p0).set_linestyle('dotted').\
  42. set_linecolor('blue').set_linewidth(1)
  43. vlinef = Line(pf, pf0).set_linestyle('dotted').\
  44. set_linecolor('red').set_linewidth(1)
  45. vlineb = Line(pb, pb0).set_linestyle('dotted').\
  46. set_linecolor('green').set_linewidth(1)
  47. # Compose vertical lines for each type of difference
  48. forward_lines = Composition({'center': vlinec, 'right': vlinef})
  49. backward_lines = Composition({'center': vlinec, 'left': vlineb})
  50. centered_lines = Composition({'left': vlineb, 'right': vlinef})
  51. centered_lines2 = Composition({'left': vlineb, 'right': vlinef,
  52. 'center': vlinec})
  53. # Tangents illustrating the derivative
  54. domain = [1, 5]
  55. domain2 = [2, 5]
  56. forward_tangent = Line(p, pf).new_interval(x=domain2).\
  57. set_linestyle('dashed').set_linecolor('red')
  58. backward_tangent = Line(pb, p).new_interval(x=domain).\
  59. set_linestyle('dashed').set_linecolor('green')
  60. centered_tangent = Line(pb, pf).new_interval(x=domain).\
  61. set_linestyle('dashed').set_linecolor('blue')
  62. h = 1E-3 # h in finite difference approx used to compute the exact tangent
  63. exact_tangent = Line((x+h, f(x+h)), (x-h, f(x-h))).\
  64. new_interval(x=domain).\
  65. set_linestyle('dotted').set_linecolor('black')
  66. forward = Composition(
  67. dict(tangent=forward_tangent,
  68. point1=c, point2=cf, coor=forward_lines,
  69. name=Text('forward',
  70. forward_tangent.geometric_features()['end'] + \
  71. point(0.1,0), alignment='left')))
  72. backward = Composition(
  73. dict(tangent=backward_tangent,
  74. point1=c, point2=cb, coor=backward_lines,
  75. name=Text('backward',
  76. backward_tangent.geometric_features()['end'] + \
  77. point(0.1,0), alignment='left')))
  78. centered = Composition(
  79. dict(tangent=centered_tangent,
  80. point1=cb, point2=cf, point=c, coor=centered_lines2,
  81. name=Text('centered',
  82. centered_tangent.geometric_features()['end'] + \
  83. point(0.1,0), alignment='left')))
  84. exact = Composition(dict(graph=f, tangent=exact_tangent))
  85. forward = Composition(dict(difference=forward, exact=exact)).\
  86. set_name('forward')
  87. backward = Composition(dict(difference=backward, exact=exact)).\
  88. set_name('backward')
  89. centered = Composition(dict(difference=centered, exact=exact)).\
  90. set_name('centered')
  91. all = Composition(
  92. dict(exact=exact, forward=forward, backward=backward,
  93. centered=centered)).set_name('all')
  94. for fig in forward, backward, centered, all:
  95. drawing_tool.erase()
  96. fig.draw()
  97. mesh.draw()
  98. drawing_tool.display()
  99. drawing_tool.savefig('fd_'+fig.get_name())
  100. raw_input()