diff --git a/week9/img/11_2.png b/week9/img/11_2.png
index 0f21d2ee6a6a1bb8128c7e12918ecc76fdb2f731..a68f3377c18abd473b53badd8bd55b54258027a3 100644
Binary files a/week9/img/11_2.png and b/week9/img/11_2.png differ
diff --git a/week9/img/animation.gif b/week9/img/animation.gif
index 1bb36167dcbb22ba2abbd3e995018064008d9866..3cc25a42548bbad3b4e024d73fd38699f1da3c4c 100644
Binary files a/week9/img/animation.gif and b/week9/img/animation.gif differ
diff --git a/week9/week9_11_2.py b/week9/week9_11_2.py
index e4ce973340c129c6a96983f1ca99fa58d3ef25bd..0535f118f39f250fda095f068bea248350a604a4 100644
--- a/week9/week9_11_2.py
+++ b/week9/week9_11_2.py
@@ -19,20 +19,28 @@ def generate_data(size, sigma):
 
 # Levenberg-Marquardt routine to fit y = sin(a+bx) to this data set starting from a = b = 1
 def levenberg_step(x, y, a, b, l):
-    # Calculate the Jacobian
-    J = np.array([np.ones(len(x)), x]).T
-    # Calculate the Hessian
-    H = np.dot(J.T, J)
-    # Calculate the gradient
-    g = np.dot(J.T, y - np.sin(a + b*x))
-    # update = (H + l*I)^-1 * g (where I is the identity matrix np.eye(2)
-    coefficients = np.dot(np.linalg.inv(H + l*np.eye(2)), g)
-    return coefficients
+    # every noisy y - every y from our fit:
+    error = (y - np.sin(a + b*x))**2
+    error_sum = np.sum(error)
+    J = np.zeros(2)
+    J[0] = -2 * np.sum((y - np.sin(a + b*x)) * np.cos(a + b * x))    # from wolfram
+    J[1] = -2 * np.sum((y - np.sin(a + b*x)) * np.cos(a + b * x) * x)
+
+    M = np.zeros((2, 2))
+    M[0, 0] = 0.5 * (1 + l) * 2 * np.sum(np.cos(a + b * x) ** 2)    # from wolfram
+    M[1, 1] = 0.5 * (1 + l) * 2 * np.sum((x * np.cos(a + b * x)) ** 2)
+
+    M[0, 1] = 0.5 * 2 * np.sum(x * (np.cos(a + b * x) ** 2)) 
+    M[1, 0] = M[0, 1] # it's a symmetric matrix
+
+    M_inv = np.linalg.inv(M)
+    step = -M_inv.dot(J)
+    return step
 
 a = 1
 b = 1
-l = 0.1
-steps = 100
+l = 1
+steps = 50
 
 size = 100
 sigma = 0.1
@@ -45,11 +53,12 @@ for i in range(steps):
     coefficients = levenberg_step(x, y, a, b, l)
     A.append(a)
     B.append(b)
-    a += coefficients[0]
+    a += coefficients[0]  # we are taking little relative moves of a and b, not returning absolute positions
     b += coefficients[1]
     # print("a: %.4f, b: %.4f" % (a, b))
 
-'''
+print(a,b)
+# '''
 # Here we plot the data and the fit line
 fig, (ax1, ax2) = plt.subplots(2, 1)
 # slim plot
@@ -64,8 +73,9 @@ ax1.set_title('Levenberg-Marquardt Fit\nsteps = %.2f, sigma = %.2f' % (steps, si
 ax2.scatter(A, B, c=range(steps))
 ax2.set_title('Converging a and b values')
 plt.show()
-'''
+# '''
 
+'''
 # Here we animate the fit converging over the scatter plot
 my_dpi = 96
 fig = plt.figure(figsize=(800/my_dpi, 400/my_dpi), dpi=my_dpi)
@@ -83,9 +93,10 @@ def animate(w):
     y = B[w]
     fit[0].set_data(x_sorted, np.sin(x + y*x_sorted))
 
-anim = animation.FuncAnimation(fig, animate, frames=int(20))
+anim = animation.FuncAnimation(fig, animate, frames=int(50))
 # plt.show()
 
 path = r"c://Users/david/Desktop/NMM/week9/img/animation.gif" 
 # save as a gif
 anim.save(path, writer='imagemagick', fps=8, dpi=my_dpi)
+'''
\ No newline at end of file