function r = i4_to_halton ( dim_num, step, key, leap, base )

%*****************************************************************************80
%
%% i4_to_halton() computes an element of a leaped Halton subsequence.
%
%  Discussion:
%
%    The DIM_NUM-dimensional Halton sequence is really DIM_NUM separate
%    sequences, each generated by a particular base.
%
%    This routine selects elements of a "leaped" subsequence of the 
%    Halton sequence.  The subsequence elements are indexed by a
%    quantity called STEP, which starts at 0.  The STEP-th subsequence 
%    element is simply element 
%
%      key(1:DIM_NUM) + STEP * LEAP(1:DIM_NUM) 
%
%    of the original Halton sequence.
%
%  Licensing:
%
%    This code is distributed under the MIT license.
%
%  Modified:
%
%    21 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    J H Halton,
%    On the efficiency of certain quasi-random sequences of points
%    in evaluating multi-dimensional integrals,
%    Numerische Mathematik,
%    Volume 2, 1960, pages 84-90.
% 
%    J H Halton and G B Smith,
%    Algorithm 247: Radical-Inverse Quasi-Random Point Sequence,
%    Communications of the ACM,
%    Volume 7, 1964, pages 701-702.
%
%    Ladislav Kocis, William Whiten,
%    Computational Investigations of Low-Discrepancy Sequences,
%    ACM Transactions on Mathematical Software,
%    Volume 23, Number 2, 1997, pages 266-294.
%
%  Input:
%
%    integer DIM_NUM, the spatial dimension.
%    1 <= DIM_NUM is required.
%
%    integer STEP, the index of the subsequence element.
%    0 <= STEP is required.
%
%    integer key(DIM_NUM), the Halton sequence index corresponding 
%    to STEP = 0.
%    0 <= key(1:DIM_NUM) is required.
%
%    integer LEAP(DIM_NUM), the successive jumps in the Halton sequence.
%    1 <= LEAP(1:DIM_NUM) is required.
%
%    integer BASE(DIM_NUM), the Halton bases.
%    1 < BASE(1:DIM_NUM) is required.
%
%  Output:
%
%    real R(DIM_NUM), the STEP-th element of the leaped 
%    Halton subsequence.
%
  dim_num = floor ( dim_num );
  step = floor ( step );
  key(1:dim_num) = floor ( key(1:dim_num) );
  leap(1:dim_num) = floor ( leap(1:dim_num) );
  base(1:dim_num) = floor ( base(1:dim_num) );
%
%  Check the input.
%
  if ( dim_num  < 1 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'I4_TO_HALTON - Fatal error!\n' );
    fprintf ( 1, '  DIM_NUM < 1\n');
    error ( 'I4_TO_HALTON - Fatal error!' );
  end

  if ( step < 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'I4_TO_HALTON - Fatal error!\n' );
    fprintf ( 1, '  STEP < 0\n' );
    error ( 'I4_TO_HALTON - Fatal error!' );
  end

  if ( any ( key < 0 ) )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'I4_TO_HALTON - Fatal error!\n' );
    fprintf ( 1, '  key < 0\n' );
    error ( 'I4_TO_HALTON - Fatal error!' );
  end

  if ( any ( leap < 1 ) )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'I4_TO_HALTON - Fatal error!\n' );
    fprintf ( 1, '  LEAP < 1\n' );
    error ( 'I4_TO_HALTON - Fatal error!' );
  end

  if ( any ( base <= 1 ) )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'I4_TO_HALTON - Fatal error!\n' );
    fprintf ( 1, '  BASE <= 1\n' );
    error ( 'I4_TO_HALTON - Fatal error!' );
  end
%
%  Calculate the data.
%
  key2(1:dim_num) = key(1:dim_num) + step * leap(1:dim_num);

  r(1:dim_num) = 0.0;

  base_inv(1:dim_num) = 1.0 ./ base(1:dim_num);
  
  while ( any ( key2(1:dim_num) ~= 0 ) )
    digit(1:dim_num) = mod ( key2(1:dim_num), base(1:dim_num) );
    r(1:dim_num) = r(1:dim_num) + digit(1:dim_num) .* base_inv(1:dim_num);
    base_inv(1:dim_num) = base_inv(1:dim_num) ./ base(1:dim_num);
    key2(1:dim_num) = floor ( key2(1:dim_num) ./ base(1:dim_num) );
  end

  return
end
