docs: def optimise_gradient_descent(x, a, c, tolerance=0.001):
      """
      Optimise value of x using gradient descent
      """
      x_new = x
      x_old = x-1 # dummy value
      while np.abs(x_new - x_old).sum() > tolerance:
          x_old = x_new
          step_size = golden_section_search(lambda step: f(grad_desc_update(x_old, a, c, step), a, c), -1.0, 1.0)
          x_new = grad_desc_update(x_old, a, c, step_size)
      return x_new