code: def fmin_ncg(
      f,
      x0,
      fprime,
      fhess_p=None,
      fhess=None,
      args=(),
      avextol=1e-5,
      epsilon=_epsilon,
      maxiter=None,
      full_output=0,
      disp=1,
      retall=0,
      callback=None,
  ):
      """Minimize the function f using the Newton-CG method.
  
      :Parameters:
  
      f -- the Python function or method to be minimized.
      x0 : ndarray -- the initial guess for the minimizer.
      fprime -- a function to compute the gradient of f: fprime(x, *args)
      fhess_p -- a function to compute the Hessian of f times an
                 arbitrary vector: fhess_p (x, p, *args)
      fhess -- a function to compute the Hessian matrix of f.
      args -- extra arguments for f, fprime, fhess_p, and fhess (the same
              set of extra arguments is supplied to all of these functions).
  
      epsilon : number
          if fhess is approximated use this value for
                   the step size (can be scalar or vector)
      callback -- an optional user-supplied function to call after each
                  iteration.  It is called as callback(xk), where xk is the
                  current parameter vector.
  
      :Returns: (xopt, {fopt, fcalls, gcalls, hcalls, warnflag},{allvecs})
  
      xopt : ndarray
          the minimizer of f
      fopt : number
          the value of the function at xopt: fopt = f(xopt)
      fcalls : number
          the number of function calls
      gcalls : number
          the number of gradient calls
      hcalls : number
          the number of hessian calls.
      warnflag : number
          algorithm warnings:
                  1 : 'Maximum number of iterations exceeded.'
      allvecs : Python list
          a list of all tried iterates
  
      :OtherParameters:
  
      avextol : number
          Convergence is assumed when the average relative error in
                 the minimizer falls below this amount.
      maxiter : number
          Maximum number of iterations to allow.
      full_output : number
          If non-zero return the optional outputs.
      disp : number
          If non-zero print convergence message.
      retall : bool
          return a list of results at each iteration if True
  
      :SeeAlso:
  
        fmin, fmin_powell, fmin_cg,
               fmin_bfgs, fmin_ncg -- multivariate local optimizers
        leastsq -- nonlinear least squares minimizer
  
        fmin_l_bfgs_b, fmin_tnc,
               fmin_cobyla -- constrained multivariate optimizers
  
        anneal, brute -- global optimizers
  
        fminbound, brent, golden, bracket -- local scalar minimizers
  
        fsolve -- n-dimenstional root-finding
  
        brentq, brenth, ridder, bisect, newton -- one-dimensional root-finding
  
        fixed_point -- scalar fixed-point finder
  
      Notes
  
      ---------------------------------------------
  
      Only one of fhess_p or fhess need be given.  If fhess is provided,
      then fhess_p will be ignored.  If neither fhess nor fhess_p is
      provided, then the hessian product will be approximated using finite
      differences on fprime. fhess_p must compute the hessian times an arbitrary
      vector. If it is not given, finite-differences on fprime are used to
      compute it. See Wright, and Nocedal 'Numerical Optimization', 1999,
      pg. 140.
  
      """
      x0 = asarray(x0).flatten()
      fcalls, f = wrap_function(f, args)
      gcalls, fprime = wrap_function(fprime, args)
      hcalls = 0
      if maxiter is None:
          maxiter = len(x0) * 200
  
      xtol = len(x0) * avextol
      update = [2 * xtol]
      xk = x0
      if retall:
          allvecs = [xk]
      k = 0
      old_fval = f(x0)
      while (numpy.add.reduce(abs(update)) > xtol) and (k < maxiter):
          # Compute a search direction pk by applying the CG method to
          #  del2 f(xk) p = - grad f(xk) starting from 0.
          b = -fprime(xk)
          maggrad = numpy.add.reduce(abs(b))
          eta = min([0.5, numpy.sqrt(maggrad)])
          termcond = eta * maggrad
          xsupi = zeros(len(x0), dtype=x0.dtype)
          ri = -b
          psupi = -ri
          i = 0
          dri0 = numpy.dot(ri, ri)
  
          if fhess is not None:  # you want to compute hessian once.
              A = fhess(*(xk,) + args)
              hcalls = hcalls + 1
  
          while numpy.add.reduce(abs(ri)) > termcond:
              if fhess is None:
                  if fhess_p is None:
                      Ap = approx_fhess_p(xk, psupi, fprime, epsilon)
                  else:
                      Ap = fhess_p(xk, psupi, *args)
                      hcalls = hcalls + 1
              else:
                  Ap = numpy.dot(A, psupi)
              # check curvature
              Ap = asarray(Ap).squeeze()  # get rid of matrices...
              curv = numpy.dot(psupi, Ap)
              if curv == 0.0:
                  break
              elif curv < 0:
                  if i > 0:
                      break
                  else:
                      xsupi = xsupi + dri0 / curv * psupi
                      break
              alphai = dri0 / curv
              xsupi = xsupi + alphai * psupi
              ri = ri + alphai * Ap
              dri1 = numpy.dot(ri, ri)
              betai = dri1 / dri0
              psupi = -ri + betai * psupi
              i = i + 1
              dri0 = dri1  # update numpy.dot(ri,ri) for next time.
  
          pk = xsupi  # search direction is solution to system.
          gfk = -b  # gradient at xk
          alphak, fc, gc, old_fval = line_search_BFGS(
              f, xk, pk, gfk, old_fval
          )
  
          update = alphak * pk
          xk = xk + update  # upcast if necessary
          if callback is not None:
              callback(xk)
          if retall:
              allvecs.append(xk)
          k += 1
  
      if disp or full_output:
          fval = old_fval
      if k >= maxiter:
          warnflag = 1
          if disp:
              print(
                  "Warning: Maximum number of iterations has been exceeded"
              )
              print("         Current function value: %s" % fval)
              print("         Iterations: %d" % k)
              print("         Function evaluations: %d" % fcalls[0])
              print("         Gradient evaluations: %d" % gcalls[0])
              print("         Hessian evaluations: %d" % hcalls)
      else:
          warnflag = 0
          if disp:
              print("Optimization terminated successfully.")
              print("         Current function value: %s" % fval)
              print("         Iterations: %d" % k)
              print("         Function evaluations: %d" % fcalls[0])
              print("         Gradient evaluations: %d" % gcalls[0])
              print("         Hessian evaluations: %d" % hcalls)
  
      if full_output:
          retlist = xk, fval, fcalls[0], gcalls[0], hcalls, warnflag
          if retall:
              retlist += (allvecs,)
      else:
          retlist = xk
          if retall:
              retlist = (xk, allvecs)
  
      return retlist
  
imports: import numpy
  from numpy import atleast_1d, eye, mgrid, argmin, zeros, shape, empty, squeeze, isscalar, vectorize, asarray, absolute, sqrt, Inf, asfarray, isinf
  from mystic import linesearch
  from collections.abc import Callable
  import builtins
label_desc: Use image node_id 20 for calling a global function with example usage: fmin_ncg(f, x0, fprime, fhess_p, fhess, args, avextol, epsilon, maxiter, full_output, disp, retall, callback) and returns: retlist