├── requirements.txt
├── Figures
├── A1.png
├── A2.png
├── B1.gif
├── B2.png
├── C1.gif
├── C2.png
├── D1.png
├── E1.png
├── E2.png
├── E3.png
├── E4.png
├── E5.png
├── F1.png
├── F2.png
├── F3.png
├── G1.png
├── G2.png
├── G3.png
├── G4.png
├── G5.png
├── H1.png
├── H2.png
├── H3.png
├── H4.png
├── H5.png
├── H6.png
└── I1.png
├── Monte Carlo Methods Report.pdf
├── README.md
├── montecarlo2d_floating.py
├── montecarlo2d.py
└── montecarlo.py
/requirements.txt:
--------------------------------------------------------------------------------
1 | gif==1.0.2
2 | matplotlib==3.2.1
3 | numpy==1.18.2
4 |
--------------------------------------------------------------------------------
/Figures/A1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s-ankur/montecarlo-pde/HEAD/Figures/A1.png
--------------------------------------------------------------------------------
/Figures/A2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s-ankur/montecarlo-pde/HEAD/Figures/A2.png
--------------------------------------------------------------------------------
/Figures/B1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s-ankur/montecarlo-pde/HEAD/Figures/B1.gif
--------------------------------------------------------------------------------
/Figures/B2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s-ankur/montecarlo-pde/HEAD/Figures/B2.png
--------------------------------------------------------------------------------
/Figures/C1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s-ankur/montecarlo-pde/HEAD/Figures/C1.gif
--------------------------------------------------------------------------------
/Figures/C2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s-ankur/montecarlo-pde/HEAD/Figures/C2.png
--------------------------------------------------------------------------------
/Figures/D1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s-ankur/montecarlo-pde/HEAD/Figures/D1.png
--------------------------------------------------------------------------------
/Figures/E1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s-ankur/montecarlo-pde/HEAD/Figures/E1.png
--------------------------------------------------------------------------------
/Figures/E2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s-ankur/montecarlo-pde/HEAD/Figures/E2.png
--------------------------------------------------------------------------------
/Figures/E3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s-ankur/montecarlo-pde/HEAD/Figures/E3.png
--------------------------------------------------------------------------------
/Figures/E4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s-ankur/montecarlo-pde/HEAD/Figures/E4.png
--------------------------------------------------------------------------------
/Figures/E5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s-ankur/montecarlo-pde/HEAD/Figures/E5.png
--------------------------------------------------------------------------------
/Figures/F1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s-ankur/montecarlo-pde/HEAD/Figures/F1.png
--------------------------------------------------------------------------------
/Figures/F2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s-ankur/montecarlo-pde/HEAD/Figures/F2.png
--------------------------------------------------------------------------------
/Figures/F3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s-ankur/montecarlo-pde/HEAD/Figures/F3.png
--------------------------------------------------------------------------------
/Figures/G1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s-ankur/montecarlo-pde/HEAD/Figures/G1.png
--------------------------------------------------------------------------------
/Figures/G2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s-ankur/montecarlo-pde/HEAD/Figures/G2.png
--------------------------------------------------------------------------------
/Figures/G3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s-ankur/montecarlo-pde/HEAD/Figures/G3.png
--------------------------------------------------------------------------------
/Figures/G4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s-ankur/montecarlo-pde/HEAD/Figures/G4.png
--------------------------------------------------------------------------------
/Figures/G5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s-ankur/montecarlo-pde/HEAD/Figures/G5.png
--------------------------------------------------------------------------------
/Figures/H1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s-ankur/montecarlo-pde/HEAD/Figures/H1.png
--------------------------------------------------------------------------------
/Figures/H2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s-ankur/montecarlo-pde/HEAD/Figures/H2.png
--------------------------------------------------------------------------------
/Figures/H3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s-ankur/montecarlo-pde/HEAD/Figures/H3.png
--------------------------------------------------------------------------------
/Figures/H4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s-ankur/montecarlo-pde/HEAD/Figures/H4.png
--------------------------------------------------------------------------------
/Figures/H5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s-ankur/montecarlo-pde/HEAD/Figures/H5.png
--------------------------------------------------------------------------------
/Figures/H6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s-ankur/montecarlo-pde/HEAD/Figures/H6.png
--------------------------------------------------------------------------------
/Figures/I1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s-ankur/montecarlo-pde/HEAD/Figures/I1.png
--------------------------------------------------------------------------------
/Monte Carlo Methods Report.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s-ankur/montecarlo-pde/HEAD/Monte Carlo Methods Report.pdf
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # montecarlo-pde
2 | The Poisson Equation, and its special case, the
3 | Laplace Equation, are important partial differential equations
4 | within electrostatics, as they describe the electric potential field
5 | caused by a particular charge distribution. Solving the Poisson
6 | equation for a given set of boundary conditions is a fundamental
7 | problem within the field. This report describes an algorithm for a
8 | Monte Carlo Method solution to the Poisson and Laplace
9 | equations. Monte Carlo Method is a parallelizable non-
10 | deterministic numerical approach towards solving this problem.
11 | A Python implementation is also provided for three versions of the
12 | Monte Carlo Method: Fixed Step, Semi-Floating and Full
13 | Floating. Several examples including the one-dimensional and
14 | two-dimensional parallel plate capacitors are performed to
15 | illustrate the function of the implementation.
16 |
17 |
18 | Keywords: Poisson Equation, Laplace Equation, Monte Carlo
19 | Methods, Electrostatics, Parallel Plate Capacitor, Python
20 | Implementation
21 |
22 |
23 | A. One dimentional capacitor (Laplace Equation)
24 |
25 |
26 |
27 |
28 |
29 | B. Variation of solution with number of random walks
30 | (Laplace Equation)
31 |
32 |
33 |
34 |
35 |
36 | C. Variation of solution with number of lattice points
37 | (Laplace Equation)
38 |
39 |
40 |
41 |
42 |
43 | D.One dimensional capacitor with a linear charge
44 | distribution (Poisson Equation)
45 |
46 |
47 |
48 |
49 | E. Two dimentional capacitor (Laplace Equation)
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | F.Two dimentional metal box with a spherical charge in
60 | centre (Poisson Equation)
61 |
62 |
63 |
64 |
65 |
66 |
67 | G. Two dimentional metal box with a two oppositely charged
68 | spheres (Poisson Equation)
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | H.Two dimentional metal box with a spherical charge at
79 | center using semi-floating random walk algorithm
80 | (Poisson Equation)
81 |
82 |
83 |
84 |
85 |
86 |
87 | I. Two dimentional metal box with a spherical charge at
88 | center using full floating random walk algorithm (Poisson
89 | Equation)
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/montecarlo2d_floating.py:
--------------------------------------------------------------------------------
1 | """
2 | All calculations in SI units
3 | """
4 | import random
5 | from mpl_toolkits.mplot3d import axes3d
6 | import matplotlib.pyplot as plt
7 | from matplotlib import cm
8 | import numpy as np
9 | import math
10 |
11 | h = 10e-2 # Distance between plates = 10cm
12 | lattice_points = 30 # Number of Points in lattice
13 | d = h / lattice_points # Lattice size
14 | boundary_voltage_high = 5.0 # 5 Volts at Positive Plate
15 | boundary_voltage_low = 0.0 # 0 Volts at Negative Plate
16 | epsilon_naught = 8.854e-12 # Permittivity of Vaccum
17 | charge_density = 6e-16 # Coulomb per meter cube
18 | N = 400 # Number of Random Walks
19 |
20 |
21 | def f(x):
22 | # Alternative charge distribution: A charged Sphere in the centre of metal box
23 | if (h / 2 - x[0]) ** 2 + (h / 2 - x[1]) ** 2 <= (h / 5) ** 2:
24 | return -charge_density * 5 / epsilon_naught
25 | else:
26 | return 0
27 |
28 |
29 | def g(x):
30 | # Two Dimentional Alternative Boundary Conditions: uncharged metal box
31 | return 0
32 |
33 |
34 | @np.vectorize
35 | def poisson_approximation_semi_floating(*A):
36 | # Returns the Value of Potential Feild at a given point A with N random walks
37 | result = 0
38 | F = 0
39 | for i in range(N):
40 | x = list(A)
41 | while True:
42 | if x[0] <= 0 or x[0] >= h or x[1] <= 0 or x[1] >= h:
43 | break
44 | random_angle = random.random() * 2 * math.pi
45 | random_unit_vector = np.array(
46 | [math.cos(random_angle), math.sin(random_angle)]
47 | )
48 | x += random_unit_vector * d
49 | F += f(x) * d ** 2
50 | result += g(x) / N
51 | result = result - F
52 | return result
53 |
54 |
55 | @np.vectorize
56 | def poisson_approximation_full_floating(*A):
57 | # Returns the Value of Potential Feild at a given point A with N random walks
58 | result = 0
59 | F = 0
60 | for i in range(N):
61 | x = list(A)
62 | while True:
63 | if x[0] <= 0 or x[0] >= h or x[1] <= 0 or x[1] >= h:
64 | break
65 | random_angle = random.random() * 2 * math.pi
66 | random_unit_vector = np.array(
67 | [math.cos(random_angle), math.sin(random_angle)]
68 | )
69 | random_step_size = random.random() * d
70 | x += random_unit_vector * random_step_size
71 | F += f(x) * h ** 2
72 | result += g(x) / N
73 | result = result - F
74 | return result
75 |
76 |
77 | def plot(x, y, z):
78 | # Function for plotting the potential
79 | fig = plt.figure()
80 | ax = fig.add_subplot(111, projection="3d")
81 |
82 | ax.plot_surface(x, y, np.array(z), cmap=cm.jet, linewidth=0.1)
83 | plt.xlabel("X (Meters)")
84 | plt.ylabel("Y (Meters)")
85 | ax.set_zlabel("Potential (Volts)")
86 | plt.show()
87 |
88 |
89 | if __name__ == "__main__":
90 | # Experiment H : Semi Floating Random Walk
91 | print(
92 | f"Calculating Monte Carlo with {lattice_points}x{lattice_points} lattice points and {N} random walks for Semi Floating Random Walk Algorithm"
93 | )
94 | lattice_x, lattice_y = np.mgrid[
95 | 0 : h : lattice_points * 1j, 0 : h : lattice_points * 1j
96 | ]
97 | z = poisson_approximation_semi_floating(
98 | lattice_x.ravel(), lattice_y.ravel()
99 | ).reshape(lattice_x.shape)
100 | plot(lattice_x, lattice_y, z)
101 |
102 | # Experiment H : Full Floating Random Walk
103 | print(
104 | f"Calculating Monte Carlo with {lattice_points}x{lattice_points} lattice points and {N} random walks for Full Floating Random Walk Algorithm"
105 | )
106 | lattice_x, lattice_y = np.mgrid[
107 | 0 : h : lattice_points * 1j, 0 : h : lattice_points * 1j
108 | ]
109 | z = poisson_approximation_full_floating(
110 | lattice_x.ravel(), lattice_y.ravel()
111 | ).reshape(lattice_x.shape)
112 | plot(lattice_x, lattice_y, z)
113 |
--------------------------------------------------------------------------------
/montecarlo2d.py:
--------------------------------------------------------------------------------
1 | """
2 | All calculations in SI units
3 | """
4 | import random
5 | from mpl_toolkits.mplot3d import axes3d
6 | import matplotlib.pyplot as plt
7 | from matplotlib import cm
8 | import numpy as np
9 |
10 | h = 10e-2 # Distance between plates = 10cm
11 | lattice_points = 30 # Number of Points in lattice
12 | d = h / lattice_points # Lattice size
13 | boundary_voltage_high = 5.0 # 5 Volts at Positive Plate
14 | boundary_voltage_low = 0.0 # 0 Volts at Negative Plate
15 | epsilon_naught = 8.854e-12 # Permittivity of Vaccum
16 | charge_density = 6e-16 # Coulomb per meter cube
17 | N = 400 # Number of Random Walks
18 |
19 |
20 | def f(x):
21 | # The Function \nabla^2(phi) = f
22 | # For Laplace f = 0
23 | return 0
24 |
25 |
26 | def g(x):
27 | # Two Dimentional Boundary Conditions: two parallel metal plates at x=0,x=h
28 | # the plate at x=h is at high potential and x=0 is low potential
29 | # Assume that there are metal plates along y=0 and y=h (uncharged)
30 | # this is because I dont know how to simulate open boundry conditions
31 | if x[0] <= 0:
32 | return boundary_voltage_low
33 | if x[0] >= h:
34 | return boundary_voltage_high
35 | if x[1] <= 0 or x[1] >= h:
36 | return boundary_voltage_low
37 |
38 |
39 | def f_2(x):
40 | # Alternative charge distribution: A charged Sphere in the centre of metal box
41 | if (h / 2 - x[0]) ** 2 + (h / 2 - x[1]) ** 2 <= (h / 5) ** 2:
42 | return -charge_density * 5 / epsilon_naught
43 | else:
44 | return 0
45 |
46 |
47 | def g_2(x):
48 | # Two Dimentional Alternative Boundary Conditions: uncharged metal box
49 | return 0
50 |
51 |
52 | def f_3(x):
53 | # Alternative charge distribution: TWO charged Sphere in the centre of metal box
54 | if (h / 3 - x[0]) ** 2 + (h / 2 - x[1]) ** 2 <= (h / 5) ** 2:
55 | return -charge_density * 5 / epsilon_naught
56 | if (2 * h / 3 - x[0]) ** 2 + (h / 2 - x[1]) ** 2 <= (h / 5) ** 2:
57 | return charge_density * 5 / epsilon_naught
58 | else:
59 | return 0
60 |
61 |
62 | @np.vectorize
63 | def poisson_approximation_fixed_step(*A):
64 | # Returns the Value of Potential Feild at a given point A with N random walks
65 | result = 0
66 | F = 0
67 | for i in range(N):
68 | x = list(A)
69 | while True:
70 | if x[0] <= 0 or x[0] >= h or x[1] <= 0 or x[1] >= h:
71 | break
72 | random_number = random.randint(0, 3)
73 | if random_number == 0:
74 | x[0] += d
75 | elif random_number == 1:
76 | x[0] -= d
77 | elif random_number == 2:
78 | x[1] += d
79 | elif random_number == 3:
80 | x[1] -= d
81 | F += f(x) * h ** 2
82 | result += g(x) / N
83 | result = result - F
84 | return result
85 |
86 |
87 | def plot(x, y, z):
88 | # Function for plotting the potential
89 | fig = plt.figure()
90 | ax = fig.add_subplot(111, projection="3d")
91 |
92 | ax.plot_surface(x, y, np.array(z), cmap=cm.jet, linewidth=0.1)
93 | plt.xlabel("X (Meters)")
94 | plt.ylabel("Y (Meters)")
95 | ax.set_zlabel("Potential (Volts)")
96 | plt.show()
97 |
98 |
99 | if __name__ == "__main__":
100 | # Experiment E: 2D Capacitor
101 | print(
102 | f"Calculating Monte Carlo with {lattice_points}x{lattice_points} lattice points and {N} random walks"
103 | )
104 | lattice_x, lattice_y = np.mgrid[
105 | 0 : h : lattice_points * 1j, 0 : h : lattice_points * 1j
106 | ]
107 | z = poisson_approximation_fixed_step(lattice_x.ravel(), lattice_y.ravel()).reshape(
108 | lattice_x.shape
109 | )
110 | plot(lattice_x, lattice_y, z)
111 |
112 | # Experiment F: Metal box with positively charged metal ball inside
113 | f = f2
114 | g = g2
115 | print(
116 | f"Calculating Monte Carlo with {lattice_points}x{lattice_points} lattice points and {N} random walks for {'Laplace' if laplace else 'Poisson'}"
117 | )
118 | lattice_x, lattice_y = np.mgrid[
119 | 0 : h : lattice_points * 1j, 0 : h : lattice_points * 1j
120 | ]
121 | z = poisson_approximation_fixed_step(lattice_x.ravel(), lattice_y.ravel()).reshape(
122 | lattice_x.shape
123 | )
124 | plot(lattice_x, lattice_y, z)
125 |
126 | # Experiment G: Metal Box with two spheres (positive and negative)
127 |
128 | f = f_3
129 | g = g_2
130 | print(
131 | f"Calculating Monte Carlo with {lattice_points}x{lattice_points} lattice points and {N} random walks for {'Laplace' if laplace else 'Poisson'}"
132 | )
133 | lattice_x, lattice_y = np.mgrid[
134 | 0 : h : lattice_points * 1j, 0 : h : lattice_points * 1j
135 | ]
136 | z = poisson_approximation_fixed_step(lattice_x.ravel(), lattice_y.ravel()).reshape(
137 | lattice_x.shape
138 | )
139 | plot(lattice_x, lattice_y, z)
140 |
--------------------------------------------------------------------------------
/montecarlo.py:
--------------------------------------------------------------------------------
1 | """
2 | All calculations in SI units
3 | """
4 | import random
5 | import matplotlib.pyplot as plt
6 | import gif
7 | import numpy as np
8 |
9 | h = 10e-2 # Distance between plates = 10cm
10 | lattice_points = 15 # Number of Points in lattice
11 | d = h / lattice_points # Lattice size
12 | laplace = False # False-> Poisson, True-> Laplace
13 | boundary_voltage_high = 5.0 # 5 Volts at Positive Plate
14 | boundary_voltage_low = 0.0 # 0 Volts at Negative Plate
15 | epsilon_naught = 8.854e-12 # Permittivity of Vaccum
16 | charge_density = 1e-14 # Coulomb per meter cube
17 | N = 400 # Number of Random Walks
18 |
19 |
20 | def f(x):
21 | # The Function \nabla^2(phi) = f
22 | if laplace:
23 | # For Laplace f = 0
24 | return 0
25 | else:
26 | # For Poisson, assume that there is a constant charge density
27 | # between the plates
28 | # So f= - rho/epsilon
29 | return (x / h - 0.5) * -charge_density / epsilon_naught
30 |
31 |
32 | def g(x):
33 | # One Dimentional Boundary Conditions:
34 | if x <= 0:
35 | return boundary_voltage_low
36 | return boundary_voltage_high
37 |
38 |
39 | def poisson_approximation_fixed_step(A):
40 | # Returns the Value of Potential Feild at a given point A with N random walks
41 | result = 0
42 | F = 0
43 | for i in range(N):
44 | x = A
45 | while True:
46 | if x <= 0 or x >= h:
47 | break
48 | if random.randint(0, 1):
49 | x += d
50 | else:
51 | x -= d
52 | F += f(x) * d ** 2
53 | result += g(x) / N
54 | result = result - F
55 | return result
56 |
57 |
58 | # Function for plotting the potential
59 |
60 |
61 | def plot(x, y, y2=None):
62 | plt.figure(figsize=(7, 5), dpi=100)
63 | plt.plot(x, y, "r.-")
64 | if y2 is not None:
65 | plt.plot(x, y2, "b-")
66 | plt.text(h, 0, f"N = {N}", ha="right")
67 | plt.text(h, 0.4, f"L = {lattice_points}", ha="right")
68 | plt.ylim(-2, 7)
69 | plt.xlabel("Distance from negative plate (Meters)")
70 | plt.ylabel("Potential (Volts)")
71 |
72 |
73 | plotgif = gif.frame(plot)
74 |
75 | if __name__ == "__main__":
76 | # Experiment D: One Dimensional Capacitor with constant charge distribution (Poisson Equation)
77 | laplace = False
78 | print(
79 | f"Calculating Monte Carlo with {lattice_points}x{lattice_points} lattice points and {N} random walks for Poisson Equation"
80 | )
81 | lattice = np.linspace(0, h, num=lattice_points, endpoint=True)
82 | plot(lattice, [poisson_approximation_fixed_step(A) for A in lattice])
83 | plt.show()
84 |
85 | # Experiment A: One Dimensional Capacitor (Laplace Equation)
86 | N = 400
87 | lattice_points = 15
88 | print(
89 | f"Calculating Monte Carlo with {lattice_points}x{lattice_points} lattice points and {N} random walks for Laplace Equation"
90 | )
91 | lattice = np.linspace(0, h, num=lattice_points, endpoint=True)
92 | feild_real = (boundary_voltage_high - boundary_voltage_low) / h * lattice
93 | plot(lattice, [poisson_approximation_fixed_step(A) for A in lattice], feild_real)
94 | plt.show()
95 |
96 | # Experiment B: Variation of solution with number of random walks (Laplace Equation)
97 | frames = []
98 | lattice_points = 15
99 | lattice = np.linspace(0, h, num=lattice_points, endpoint=True)
100 | feild_real = (boundary_voltage_high - boundary_voltage_low) / h * lattice
101 | feild_diff = []
102 | for N in range(10, 1000, 20):
103 | print(
104 | f"Calculating Monte Carlo with {lattice_points}x{lattice_points} lattice points and {N} random walks for Laplace Equation"
105 | )
106 | feild_approx = np.array([poisson_approximation_fixed_step(A) for A in lattice])
107 | frame = plotgif(lattice, feild_approx, feild_real)
108 | feild_diff.append(abs(feild_real - feild_approx).sum())
109 | frames.append(frame)
110 | gif.save(
111 | frames, f"Figures/{'Laplace' if laplace else 'Poisson'}_N.gif", duration=100
112 | )
113 | plt.plot(range(10, 1000, 20), feild_diff, "g.-")
114 | plt.xlabel("Number of Random Walks")
115 | plt.ylabel("Abs Error")
116 | plt.show()
117 |
118 | # Experiment C: Variation of solution with number of lattice points (Laplace Equation)
119 | frames = []
120 | feild_diff = []
121 | N = 400
122 | for lattice_points in range(2, 30):
123 | print(
124 | f"Calculating Monte Carlo with {lattice_points}x{lattice_points} lattice points and {N} random walks for Laplace Equation"
125 | )
126 | d = h / lattice_points
127 | lattice = np.linspace(0, h, num=lattice_points, endpoint=True)
128 | feild_real = (boundary_voltage_high - boundary_voltage_low) / h * lattice
129 | feild_approx = np.array([poisson_approximation_fixed_step(A) for A in lattice])
130 | frame = plotgif(lattice, feild_approx, feild_real)
131 | feild_diff.append(abs(feild_real - feild_approx).sum())
132 | frames.append(frame)
133 | gif.save(
134 | frames,
135 | f"Figures/{'Laplace' if laplace else 'Poisson'}_Lattice.gif",
136 | duration=100,
137 | )
138 | plt.plot(range(2, 30), feild_diff)
139 | plt.xlabel("Number of Lattice Points")
140 | plt.ylabel("Abs Error")
141 | plt.show()
142 |
--------------------------------------------------------------------------------