code: def sgd(grad, x, callback=None, num_iters=200, step_size=0.1, mass=0.9):
      
      velocity = np.zeros(len(x))
      for i in range(num_iters):
          g = grad(x, i)
          if callback: callback(x, i, g)
          velocity = mass * velocity - (1.0 - mass) * g
          x = x + step_size * velocity
      return x
docs: Stochastic gradient descent with momentum.
      grad() must have signature grad(x, i), where i is the iteration number.