%pylab inline
x = arange(1, 11)
print x
mean(x)
We suppose that a system is described by a state $\vec{x}$ and the differential equation $\dfrac{d\vec{x}}{dt} = \vec{f}(\vec{x}(t), t)$ as follows: $$\vec{x} = \begin{bmatrix}x_1 \\ x_2 \\ \vdots \\ x_n \end{bmatrix}, \hspace{.5in} \dfrac{d\vec{x}}{dt} = \begin{bmatrix}\frac{d x_1}{dt} \\ \frac{d x_2}{dt} \\ \vdots \\ \frac{d x_n}{dt} \end{bmatrix} = \vec{f}(\vec{x}(t), t) = \begin{bmatrix}f_1(\vec{x}(t), t) \\ f_2(\vec{x}(t), t) \\ \vdots \\ f_n(\vec{x}(t), t)\end{bmatrix}$$
The state of the system is given by its position (2 components, $x$ and $y$) and velocity (2 components, $v_x$ and $v_y$).
From Newton's Second Law, and the Law of Universal Gravitation, the differential equation can be derived:
$$\vec{x} = \begin{bmatrix}x \\ y \\ v_x\\ v_y \end{bmatrix}, \hspace{.5in} \dfrac{d\vec{x}}{dt} = \begin{bmatrix} v_x \\ v_y \\ \dfrac{-G M x}{(\sqrt{x^2 + y^2})^3} \\ \dfrac{-G M y}{(\sqrt{x^2 + y^2})^3} \end{bmatrix}$$Euler's method gives a way to calculate the new state of the system after some small time $h$:
$\vec{x}(t + h) = \vec{x}(t) + h \dfrac{d\vec{x}}{dt}$
# Take the derivative of the state, using Newton's Laws.
# For simplicity, assume that the units have been changed so that:
# - the gravitational constant G = 1
# - the mass of the sun, M = 1
def diff_P(P):
G = 1.0
M = 1.0
x, y, vx, vy = P
r3 = (sqrt(x**2 + y**2))**3
ax = -G*M*x/r3
ay = -G*M*y/r3
return array([vx, vy, ax, ay])
def plot_euler(steps, h, x=3., y=0., vx=0, vy=.5):
orbit = empty((steps, 4))
P = array([x, y, vx, vy])
for i in xrange(steps):
orbit[i] = P
P += h*diff_P(P)
plot(0, 0, 'yo', ms=6)
plot(orbit[:, 0], orbit[:, 1], 'r')
title("Euler's Method, h = {}, {} steps taken".format(h, steps))
plot_euler(100, .1)
plot_euler(500, .1)
plot_euler(5000, .1)
figure(figsize=(10, 5))
subplot('121')
plot_euler(5000, .1)
subplot('122')
plot_euler(50000, .01)
Since the changing derivative is the cause of the problem, we try to use a better estimate of the mean derivative between t and t + h.
First calculate the new state using Euler's method:
$\tilde{x} = \vec{x}(t) + h \dfrac{d\vec{x}}{dt}$
Use $\tilde{x}$ to calculate a better estimate of the new state incorporating the changing derivative:
$\vec{x}(t + h) = \vec{x}(t) + \dfrac{h}{2}\left(\dfrac{d\vec{x}}{dt}\bigg|_{\vec{x}(t)} + \dfrac{d\vec{x}}{dt}\bigg|_{\tilde{x}}\right)$
def plot_heun(steps, h, x=3., y=0., vx=0, vy=.5):
orbit = empty((steps, 4))
P = array([x, y, vx, vy])
for i in xrange(steps):
orbit[i] = P
Ptilde = P + h*diff_P(P)
P += h*(diff_P(P) + diff_P(Ptilde))/2.
plot(0, 0, 'yo', ms=6)
plot(orbit[:, 0], orbit[:, 1], 'r')
title("Heun's Method, h = {}, {} steps taken".format(h, steps))
figure(figsize=(10, 5))
subplot('121')
plot_euler(500, .1)
subplot('122')
plot_heun(500, .1)