code: def VTRChangeOverGeneration(
      ftol=0.005, gtol=1e-6, generations=30, target=0.0
  ):
      """change in cost is < gtol over a number of generations,
      or cost of last iteration is < ftol from target:
  
      ``cost[-g] - cost[-1] <= gtol`` or ``abs(cost[-1] - target) <= ftol``
      """
      doc = "VTRChangeOverGeneration with %s" % {
          "ftol": ftol,
          "gtol": gtol,
          "generations": generations,
          "target": target,
      }
  
      def _VTRChangeOverGeneration(inst, info=False):
          if info:
              info = lambda x: x
          else:
              info = bool
          hist = inst.energy_history
          lg = len(hist)
          if not lg:
              return info(null)
          # XXX: throws error when hist is shorter than generations ?
          if (
              lg > generations
              and (
                  (hist[-generations] - hist[-1]) <= gtol
                  or (hist[-generations] == hist[-1])
              )
          ) or (abs(hist[-1] - target) <= ftol):
              return info(doc)
          return info(null)
  
      _VTRChangeOverGeneration.__doc__ = doc
      return _VTRChangeOverGeneration
  
imports: import numpy
  import mystic.collapse
  from mystic.math.distance import Lnorm
  from mystic._scipy060optimize import approx_fprime, _epsilon
label_desc: Use image node_id 9 for calling a global function with example usage: VTRChangeOverGeneration(ftol, gtol, generations, target) and returns: _VTRChangeOverGeneration, info, info, info