integral.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. """Comic strip for illustrating numerical integration."""
  2. from pysketcher import *
  3. xdcd = True
  4. def f(x):
  5. return 3*np.exp(-x**4)
  6. xmin = -2
  7. drawing_tool.set_coordinate_system(xmin=xmin, xmax=4,
  8. ymin=0, ymax=4,
  9. axis=True, xkcd=xkcd)
  10. drawing_tool.set_linecolor('blue')
  11. import numpy as np
  12. x = np.linspace(xmin, 3, 201)
  13. y = f(x)
  14. curve = Curve(x, y)
  15. x2 = np.linspace(xmin, 0.2, 201)
  16. y2 = f(x2)
  17. x2 = x2.tolist()
  18. y2 = y2.tolist()
  19. x2.append(x2[-1])
  20. y2.append(0)
  21. x2.append(xmin)
  22. y2.append(0)
  23. #x2 = np.array(x2)
  24. #y2 = np.array(y2)
  25. filled = Curve(x2, y2).set_filled_curves(pattern='/')
  26. text1 = Text_wArrow('The integral $\int_{-\infty}^{0.2} 3e^{-x^4}dx$\nis impossible to calculate\nby hand but so easy with\na program!', (1.5, 3.5), (-0.2, 1), alignment='left')
  27. fig = Composition(dict(curve=curve, integral=filled, comment=text1))
  28. fig.draw()
  29. drawing_tool.display()
  30. drawing_tool.savefig('tmp1')
  31. #input()
  32. # Draw piecewise curve for midpoint rule
  33. def piecewise_curve_for_midpoint_rule(N):
  34. dx = (0.2 - xmin)/float(N)
  35. x3_double = []
  36. y3_double = []
  37. y_prev = 0
  38. for i in range(N):
  39. x = xmin + i*dx
  40. x3_double.append(x)
  41. y3_double.append(y_prev)
  42. x3_double.append(x)
  43. y_next = 0.5*(f(x) + f(xmin+(i+1)*dx))
  44. y3_double.append(y_next)
  45. y_prev = y_next
  46. x = xmin + (i+1)*dx
  47. x3_double.append(x)
  48. y3_double.append(y_prev)
  49. x3_double.append(x)
  50. y3_double.append(0)
  51. # Back to start
  52. x3_double.append(xmin)
  53. y3_double.append(0)
  54. midpoint_curve = Curve(x3_double, y3_double).set_filled_curves(pattern='/').set_linecolor('red')
  55. return midpoint_curve
  56. text2 = Text_wArrow('We just draw some rectangles\nto approximate the area\nunder the curve and sum up\nthe rectangular areas!', (1.2, 3.5), (-0.2, 1), alignment='left')
  57. drawing_tool.erase()
  58. fig = Composition(dict(curve=curve, integral=piecewise_curve_for_midpoint_rule(N=4), comment=text2))
  59. fig.draw()
  60. drawing_tool.display()
  61. drawing_tool.savefig('tmp2')
  62. text3 = Text_wArrow('Just add more rectangles\ngo get the integral\nmore accurate!', (1.5, 3.5), (-0.2, 1), alignment='left')
  63. drawing_tool.erase()
  64. fig = Composition(dict(curve=curve, integral=piecewise_curve_for_midpoint_rule(N=10), comment=text3))
  65. fig.draw()
  66. drawing_tool.display()
  67. drawing_tool.savefig('tmp3')
  68. import os
  69. comic = 'comic' if xkcd else 'non_comic'
  70. os.system('doconce combine_images pdf -3 tmp1 tmp2 tmp3 integral_%s_strip' % comic)
  71. os.system('doconce combine_images png -3 tmp1 tmp2 tmp3 integral_%s_strip' % comic)
  72. input()