b = np.zeros(N + 1, dtype = np.float64)
e2norm = np.zeros(N + 1, dtype = np.float64)
energyError = np.zeros(N + 1, dtype = np.float64)
phi = np.zeros(N + 1, dtype = np.float64)
dphidq_analytic = np.zeros(N + 1, dtype = np.float64)
dphidq_numeric = np.zeros(N + 1, dtype = np.float64)

# initial conditions
q[0] = 1.9
v[0] = -0.0001
energyConst = 0.5*v[0]  + LJ(q[0])

# calcualte phase space
for ii in range(0, N):
    t[ii + 1] = t[ii] + Dt
    q[ii + 1], v[ii + 1] = step.eulerstep(LJ, q[ii], v[ii], Dt, M)
    dphidq = -deriv.derivative(LJ, q[ii], np.abs(q[ii + 1] - q[ii]), False)[0]
    d2phidq2 = -deriv.derivative(LJdiff, q[ii], np.abs(q[ii + 1] - q[ii]), False)[0]
    a[ii] = np.max([1, d2phidq2])
    E = 0.5*v[ii]**2 + LJ(q[ii])
    b[ii] = 0.5*np.sqrt(dphidq**2 + 2*d2phidq2**2*(E - LJ(q[ii])))
    energyError[ii] = E - energyConst
    
# plot
plt.figure(1)
plt.clf()
ax1 = plt.subplot2grid((3, 2), (0, 0), rowspan = 3)
ax1.plot(q, v)
plt.title('Phase Plot')
plt.xlabel('Generalised Coordainte, $q$')
plt.ylabel('Generalised Velocity, $v(q)$')
Oscillator = lambda x: x*x # harmonic oscillator
Dt = 0.0001
N = np.int(2*np.pi/Dt)
q = np.zeros(N + 1, dtype = np.float64)
v = np.zeros(N + 1, dtype = np.float64)
t = np.zeros(N + 1, dtype = np.float64)
M = 1.0


runSubExcerise = 'a'

if runSubExcerise == 'a':
    # a. computes one timestep usingthe Euler method for an arbitrary function
    qn = 2.5
    vn = 0.01
    qn1, vn1 = step.eulerstep(LJ, qn, vn, Dt)
    print(qn1, vn1)
elif runSubExcerise == 'b':
    # b. computes the trajectories of a system dq/dt = v, dv/dt = -dphi(q)/dq
    #    with arbitrary phi(q) using Eulers method
    q[0] = 2.0
    v[0] = 0.001
    for ii in range(N):
        q[ii + 1], v[ii + 1] = step.eulerstep(LJ, q[ii], v[ii], Dt)
        t[ii + 1] = Dt*(ii + 1)
    plt.figure(1)
    plt.clf()
    plt.plot(q, v)
elif runSubExcerise == 'c':
    # c. computes the trajectories of a system dq/dt = v, dv/dt = -phi(q)/dq
    # with arbitrary phi(q) using either Eulere's A method, Euler's B methods,