code: def f_inv(self, z, max_iterations=250, y=None):
          
  
          z = z.copy()
          y = np.ones_like(z)
  
          it = 0
          update = np.inf
          while np.abs(update).sum() > 1e-10 and it < max_iterations:
              fy = self.f(y)
              fgrady = self.fgrad_y(y)
              update = (fy - z) / fgrady
              y -= self.rate * update
              it += 1
          #if it == max_iterations:
          #    print("WARNING!!! Maximum number of iterations reached in f_inv ")
          #    print("Sum of roots: %.4f" % np.sum(fy - z))
          return y
docs: Calculate the numerical inverse of f. This should be
          overwritten for specific warping functions where the
          inverse can be found in closed form.
  
          :param max_iterations: maximum number of N.R. iterations