input: Write a python function to implement gradient descent algorithm.
  assert np.allclose(gradient_descent(np.array([1, 2, 3, 4, 5]), np.array([5, 7, 9, 11, 13]), learning_rate=0.01, iterations=1000), (2.0, 3.0), atol=0.01)
  assert np.allclose(gradient_descent(np.array([1, 2, 3]), np.array([2, 2.5, 3.5]), learning_rate=0.01, iterations=1000), (0.75, 1.33), atol=0.01)
  assert np.allclose(gradient_descent(np.array([3, 4, 5, 6]), np.array([7, 9, 11, 13]), learning_rate=0.01, iterations=1000), (2.0, 1.0), atol=0.01)
output: def gradient_descent(X, y, learning_rate=0.01, iterations=1000):
      m = 0
      c = 0
      n = len(X)
      
      for _ in range(iterations):
          y_pred = m * X + c
          D_m = (-2/n) * sum(X * (y - y_pred))
          D_c = (-2/n) * sum(y - y_pred)
          m = m - learning_rate * D_m
          c = c - learning_rate * D_c
      
      return m, c