function [ d2, x1, f1, x, nl, nf, fx, qa, qb, qc ] = minny ( n, jsearch, nits, ...
  d2, x1, f1, fk, f, x, t, h, v, q0, q1, nl, nf, dmin, ldt, ...
  fx, qa, qb, qc, qd0, qd1 )

%*****************************************************************************80
%
%% minny() minimizes a scalar function of N variables along a line.
%
%  Discussion:
%
%    MINNY minimizes F along the line from X in the direction V(*,J) unless
%    J is less than 1, when a quadratic search is made in the plane
%    defined by Q0, Q1 and X.
%
%    If FK = true, then F1 is FLIN(X1).  Otherwise X1 and F1 are ignored
%    on entry unless final FX is greater than F1.
%
%    This function was modified by removing the common blocks
%    and the use of labeled statements, 28 July 2016.
%
%  Licensing:
%
%    This code is distributed under the MIT license.
%
%  Modified:
%
%    31 July 2016
%
%  Author:
%
%    Original FORTRAN77 version by Richard Brent.
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    Richard Brent,
%    Algorithms for Minimization with Derivatives,
%    Prentice Hall, 1973,
%    Reprinted by Dover, 2002.
%
%  Input:
%
%    integer N, the number of variables.
%
%    integer JSEARCH, indicates the kind of search.
%    If JSEARCH is a legal column index, linear search in direction of V(*,J).
%    Otherwise, the search is parabolic, based on X, Q0 and Q1.
%
%    integer NITS, the maximum number of times the interval
%    may be halved to retry the calculation.
%
%    real D2, is either zero, or an approximation to
%    the value of (1/2) times the second derivative of F.
%
%    real X1, on entry, an estimate of the
%    distance from X to the minimum along V(*,J), or, if J = 0, a curve.
%    On output, the distance between X and the minimizer that was found.
%
%    real F1, ?
%
%    logical FK; if FK is TRUE, then on input F1 contains
%    the value FLIN(X1).
%
%    real F ( X, N ), the function to be minimized.  
%
%    real X(N), ?
%
%    real T, ?
%
%    real H, ?
%
%    real V(N,N), a matrix whose columns are direction
%    vectors along which the function may be minimized.
%
%    real Q0(N), an auxiliary point used to define
%    a curve through X.
%
%    real Q1(N), an auxiliary point used to define
%    a curve through X.
%
%    integer NL, the number of linear searches.
%
%    integer NF, the number of function evaluations.
%
%    real DMIN, an estimate for the smallest eigenvalue.
%
%    real LDT, the length of the step.
%
%    real FX, the value of F(X,N).
%
%    real QA, QB, QC, ?
%
%    real QD0, QD1, ?.
%
%  Output:
%
%    real D2, is either zero, or an approximation to
%    the value of (1/2) times the second derivative of F.
%
%    real X1, the distance between X and the minimizer that was found.
%
%    real F1, ?
%
%    real X(N), ?
%
%    integer NL, the number of linear searches.
%
%    integer NF, the number of function evaluations.
%
%    real FX, the value of F(X,N).
%
%    real QA, QB, QC, ?
%
  q0 = q0(:);
  q1 = q1(:);
  x = x(:);

  machep = eps;
  small = machep ^ 2;
  m2 = sqrt ( machep );
  m4 = sqrt ( m2 );
  sf1 = f1;
  sx1 = x1;
  k = 0;
  xm = 0.0;
  fm = fx;
  f0 = fx;
  dz = ( d2 < machep );
%
%  Find the step size.
%
  s = norm ( x );

  if ( dz )
    temp = dmin;
  else
    temp = d2;
  end

  t2 = m4 * sqrt ( abs ( fx ) / temp + s * ldt ) + m2 * ldt;
  s = m4 * s + t;
  if ( dz && s < t2 )
    t2 = s;
  end

  t2 = max ( t2, small );
  t2 = min ( t2, 0.01 * h );

  if ( fk && f1 <= fm )
    xm = x1;
    fm = f1;
  end

  if ( ( ~ fk ) || abs ( x1 ) < t2 )

    if ( 0.0 <= x1 )
      temp = 1.0;
    else
      temp = - 1.0;
    end

    x1 = temp * t2;

    [ f1, nf, qa, qb, qc ] = flin ( n, jsearch, x1, f, x, nf, v, ...
      q0, q1, qd0, qd1, qa, qb, qc );

  end

  if ( f1 <= fm )
    xm = x1;
    fm = f1;
  end
%
%  Evaluate FLIN at another point and estimate the second derivative.
%
  while ( true )

    if ( dz )

      if ( f1 <= f0 )
        x2 = 2.0 * x1;
      else
        x2 = - x1;
      end

      [ f2, nf, qa, qb, qc ] = flin ( n, jsearch, x2, f, x, nf, v, ...
        q0, q1, qd0, qd1, qa, qb, qc );

      if ( f2 <= fm )
        xm = x2;
        fm = f2;
      end

      d2 = ( x2 * ( f1 - f0 ) - x1 * ( f2 - f0 ) ) ...
        / ( ( x1 * x2 ) * ( x1 - x2 ) );

    end
%
%  Estimate the first derivative at 0.
%
    d1 = ( f1 - f0 ) / x1 - x1 * d2;
    dz = true;
%
%  Predict the minimum.
%
    if ( d2 <= small )

      if ( 0.0 <= d1 )
        x2 = - h;
      else
        x2 = h;
      end

    else

      x2 = ( - 0.5 * d1 ) / d2;

    end

    if ( h < abs ( x2 ) )

      if ( x2 <= 0.0 )
        x2 = - h;
      else
        x2 = h;
      end

    end
%
%  Evaluate F at the predicted minimum.
%
    ok = true;

    while ( true )

      [ f2, nf, qa, qb, qc ] = flin ( n, jsearch, x2, f, x, nf, v, ...
        q0, q1, qd0, qd1, qa, qb, qc );

      if ( nits <= k || f2 <= f0 )
        break
      end

      k = k + 1;

      if ( f0 < f1 && 0.0 < x1 * x2 )
        ok = false;
        break
      end

      x2 = 0.5 * x2;

    end

    if ( ok )
      break
    end

  end
%
%  Increment the one-dimensional search counter.
%
  nl = nl + 1;

  if ( fm < f2 )
    x2 = xm;
  else
    fm = f2;
  end
%
%  Get a new estimate of the second derivative.
%
  if ( small < abs ( x2 * ( x2 - x1 ) ) )
    d2 = ( x2 * ( f1 - f0 ) - x1 * ( fm - f0 ) ) / ( ( x1 * x2 ) * ( x1 - x2 ) );
  else
    if ( 0 < k )
      d2 = 0.0;
    end
  end

  d2 = max ( d2, small );

  x1 = x2;
  fx = fm;

  if ( sf1 < fx )
    fx = sf1;
    x1 = sx1;
  end
%
%  Update X for linear but not parabolic search.
%
  if ( 1 <= jsearch )

    x(1:n) = x(1:n) + x1 * v(1:n,jsearch);

  end

  return
end
