code: def diffev(
      cost,
      x0,
      npop=4,
      args=(),
      bounds=None,
      ftol=5e-3,
      gtol=None,
      maxiter=None,
      maxfun=None,
      cross=0.9,
      scale=0.8,
      full_output=0,
      disp=1,
      retall=0,
      callback=None,
      **kwds,
  ):
      """Minimize a function using differential evolution.
  
      Uses a differential evolution algorithm to find the minimum of a function of
      one or more variables. Mimics a ``scipy.optimize`` style interface.
  
      Args:
          cost (function): the function or method to be minimized: ``y = cost(x)``.
          x0 (ndarray): the initial guess parameter vector ``x`` if desired start
              is a single point, otherwise takes a list of (min,max) bounds that
              define a region from which random initial points are drawn.
          npop (int, default=4): size of the trial solution population.
          args (tuple, default=()): extra arguments for cost.
          bounds (list(tuple), default=None): list of pairs of bounds (min,max),
              one for each parameter.
          ftol (float, default=5e-3): acceptable relative error in ``cost(xopt)``
              for convergence.
          gtol (float, default=None): maximum iterations to run without improvement.
          maxiter (int, default=None): the maximum number of iterations to perform.
          maxfun (int, default=None): the maximum number of function evaluations.
          cross (float, default=0.9): the probability of cross-parameter mutations.
          scale (float, default=0.8): multiplier for mutations on the trial solution.
          full_output (bool, default=False): True if fval and warnflag are desired.
          disp (bool, default=True): if True, print convergence messages.
          retall (bool, default=False): True if allvecs is desired.
          callback (function, default=None): function called after each iteration. The
              interface is ``callback(xk)``, with ``xk`` the current parameter vector.
          handler (bool, default=False): if True, enable handling interrupt signals.
          id (int, default=None): the ``id`` of the solver used in logging.
          strategy (strategy, default=None): override the default mutation strategy.
          itermon (monitor, default=None): override the default GenerationMonitor.
          evalmon (monitor, default=None): override the default EvaluationMonitor.
          constraints (function, default=None): function ``xk' = constraints(xk)``,
              where ``xk`` is the current parameter vector, and ``xk'`` is a parameter
              vector that satisfies the encoded constraints.
          penalty (function, default=None): function ``y = penalty(xk)``, where ``xk``
              is the current parameter vector, and ``y' == 0`` when the encoded
              constraints are satisfied (and ``y' > 0`` otherwise).
          tightrange (bool, default=None): impose bounds and constraints concurrently.
          cliprange (bool, default=None): bounding constraints clip exterior values.
          map (function, default=None): a (parallel) map instance ``y = map(f, x)``.
  
      Returns:
          ``(xopt, {fopt, iter, funcalls, warnflag}, {allvecs})``
  
      Notes:
          - xopt (*ndarray*): the minimizer of the cost function
          - fopt (*float*): value of cost function at minimum: ``fopt = cost(xopt)``
          - iter (*int*): number of iterations
          - funcalls (*int*): number of function calls
          - warnflag (*int*): warning flag:
              - ``1 : Maximum number of function evaluations``
              - ``2 : Maximum number of iterations``
          - allvecs (*list*): a list of solutions at each iteration
      """
      invariant_current = (
          kwds["invariant_current"]
          if "invariant_current" in kwds
          else False
      )
      handler = kwds["handler"] if "handler" in kwds else False
  
      from mystic.strategy import Best1Bin
  
      strategy = kwds["strategy"] if "strategy" in kwds else Best1Bin
      from mystic.monitors import Monitor
  
      stepmon = kwds["itermon"] if "itermon" in kwds else Monitor()
      evalmon = kwds["evalmon"] if "evalmon" in kwds else Monitor()
  
      if (
          gtol
      ):  # if number of generations provided, use ChangeOverGeneration
          from mystic.termination import ChangeOverGeneration
  
          termination = ChangeOverGeneration(ftol, gtol)
      else:
          from mystic.termination import VTRChangeOverGeneration
  
          termination = VTRChangeOverGeneration(ftol)
  
      ND = len(x0)
      if invariant_current:  # use Solver2, not Solver1
          solver = DifferentialEvolutionSolver2(ND, npop)
      else:
          solver = DifferentialEvolutionSolver(ND, npop)
      solver.SetEvaluationLimits(maxiter, maxfun)
      solver.SetEvaluationMonitor(evalmon)
      solver.SetGenerationMonitor(stepmon)
      if "id" in kwds:
          solver.id = int(kwds["id"])
      if "penalty" in kwds:
          solver.SetPenalty(kwds["penalty"])
      if "constraints" in kwds:
          solver.SetConstraints(kwds["constraints"])
      if bounds is not None:
          minb, maxb = unpair(bounds)
          tight = kwds["tightrange"] if "tightrange" in kwds else None
          clip = kwds["cliprange"] if "cliprange" in kwds else None
          solver.SetStrictRanges(minb, maxb, tight=tight, clip=clip)
  
      try:  # x0 passed as 1D array of (min,max) pairs
          minb, maxb = unpair(x0)
          solver.SetRandomInitialPoints(minb, maxb)
      except:  # x0 passed as 1D array of initial parameter values
          solver.SetInitialPoints(x0)
  
      _map = kwds["map"] if "map" in kwds else None
      if _map:
          solver.SetMapper(_map)
  
      if handler:
          solver.enable_signal_handler()
      # TODO: allow sigint_callbacks for all minimal interfaces ?
      solver.Solve(
          cost,
          termination=termination,
          strategy=strategy,  # sigint_callback=other_callback,\
          CrossProbability=cross,
          ScalingFactor=scale,
          ExtraArgs=args,
          callback=callback,
      )
      solution = solver.Solution()
  
      # code below here pushes output to scipy.optimize.fmin interface
      # x = list(solver.bestSolution)
      x = solver.bestSolution
      fval = solver.bestEnergy
      warnflag = 0
      fcalls = solver.evaluations
      iterations = solver.generations
      allvecs = stepmon.x
  
      if fcalls >= solver._maxfun:
          warnflag = 1
          if disp:
              print(
                  "Warning: Maximum number of function evaluations has "
                  "been exceeded."
              )
      elif iterations >= solver._maxiter:
          warnflag = 2
          if disp:
              print(
                  "Warning: Maximum number of iterations has been exceeded"
              )
      else:
          if disp:
              print("Optimization terminated successfully.")
              print("         Current function value: %s" % fval)
              print("         Iterations: %d" % iterations)
              print("         Function evaluations: %d" % fcalls)
  
      if full_output:
          retlist = x, fval, iterations, fcalls, warnflag
          if retall:
              retlist += (allvecs,)
      else:
          retlist = x
          if retall:
              retlist = (x, allvecs)
  
      return retlist
  
imports: from mystic.tools import wrap_function, unpair, isiterable
  from mystic.tools import wrap_bounds, wrap_penalty, reduced
  from mystic.abstract_solver import AbstractSolver
  from mystic.abstract_map_solver import AbstractMapSolver
  from numpy import asfarray, ravel
  from collections.abc import Callable
label_desc: Use image node_id 2 for calling a global function with example usage: diffev(cost, x0, npop, args, bounds, ftol, gtol, maxiter, maxfun, cross, scale, full_output, disp, retall, callback) and returns: retlist