function [ x, base, more ] = vector_constrained_next5 ( n, x, sum_min, ...
  sum_max, base, more )

%*****************************************************************************80
%
%% vector_constrained_next5() returns the "next" constrained vector.
%
%  Discussion:
%
%    We consider all positive integer vectors of dimension N whose
%    components satisfy SUM_MIN <= X(1:N) <= SUM_MAX.
%
%    This routine returns, one at a time, and in right-to-left
%    lexicographic order, exactly those vectors which satisfy
%    the constraint.
%
%  Example:
%
%    N = 3
%    SUM_MIN = 5
%    SUM_MAX = 6
%
%    #  X(1)  X(2)  X(3)     SUM
%
%    1    3     1     1        5
%    2    2     2     1        5
%    3    2     1     2        5
%    4    1     3     1        5
%    5    1     2     2        5
%    6    1     1     3        5
%
%    7    4     1     1        6
%    8    3     2     1        6
%    9    3     1     2        6
%   10    2     3     1        6
%   11    2     2     2        6
%   12    2     1     3        6
%   13    1     4     1        6
%   14    1     3     2        6
%   15    1     2     3        6
%   16    1     1     4        6
%
%  Licensing:
%
%    This code is distributed under the MIT license.
%
%  Modified:
%
%    20 May 2015
%
%  Author:
%
%    John Burkardt
%
%  Input:
%
%    integer N, the number of components in the vector.
%
%    integer SUM_MIN, SUM_MAX, the minimum and maximum sums..
%
%    integer X(N).   On first call (with MORE = FALSE),
%    the input value of X is not important.  On subsequent calls, the
%    input value of X should be the output value from the previous call.
%
%    integer BASE, a variable which is used only by
%    this function, but which must be declared by the calling program.
%    The output value from the previous call must be used as the input
%    value for the next call.
%
%    logical MORE.  On output, if MORE is TRUE,
%    then another value was found and returned in X, but if MORE is
%    FALSE, then there are no more values in the sequence, and X is
%    NOT the next value.
%
%  Output:
%
%    integer X(N).  On output with MORE = TRUE, the value of X will be the "next"
%    vector in the reverse lexicographical list of vectors that satisfy
%    the condition.  However, on output with MORE = FALSE, the vector
%    X is meaningless, because there are no more vectors in the list.
%
%    integer BASE, the output value from the previous call must be used as the input
%    value for the next call.
%
%    logical MORE.  On output, if MORE is TRUE,
%    then another value was found and returned in X, but if MORE is
%    FALSE, then there are no more values in the sequence, and X is
%    NOT the next value.
%

%
%  Initialization.
%
  if ( ~ more )

    if ( sum_max < n )
      more = false;
      return
    end

    if ( sum_max < sum_min )
      more = false;
      return;
    end

    more = true;

    base = max ( sum_min, n );

    x(1) = base - n + 1;
    x(2:n) = 1;

    return
%
%  Next element.
%
  else
%
%  Search from the right, seeking an index I < N for which 1 < X(I).
%
    for i = n-1 : -1 : 1
%
%  If you find such an I, decrease X(I) by 1, and add that to X(I+1).
%
      if ( 1 < x(i) )

        x(i)   = x(i)   - 1;
        x(i+1) = x(i+1) + 1;
%
%  Now grab all the "excess" 1's from the entries to the right of X(I+1).
%
        for j = i+2 : n
          if ( 1 < x(j) )
            x(i+1) = x(i+1) + x(j) - 1;
            x(j) = 1;
          end
        end

        return

      end

    end
%
%  The current vector is (1,1,1,...,BASE-N+1).
%  If BASE < SUM_MAX, then increase BASE by 1, and start the new series.
%
    if ( base < sum_max )
      base = base + 1;
      x(1) = base - n + 1;
      x(2:n) = 1;
      return
    end
%
%  We returned the last legal vector on the previous call.
%  The calculation is done.
%
    more = false;

  end

  return
end
