function [xdata_adjusted,dataStatus,evenSpacingQuantizedValue] = fixpt_evenspace_cleanup(xdata_original,xdt,xscale)
%xdata_adjusted = fixpt_evenspace_cleanup(xdata_original,xdt,xscale)
%
% This function modifies lookup table input data to be be evenly 
% spaced if it is not quite evenly spaced after quantization.  For
% example, 0:0.005:1 appears to be evenly spaced, but if it
% is quantized with scaling 2^-12, it will not be evenly spaced.
% Loss of even spacing can make a very significant impact on
% the efficiency of the implementation.  Code generated by
% Real-Time Workshop to implement an uneven lookup table
% will be more complicated.   Of equal importantance is that
% the input data will be stored in ROM.  Modifying the
% input data to remain evenly spaced after quantization allows
% Real-Time Workshop to generate simpler code and to exclude
% the input data from memory, thereby saving significant amounts 
% of ROM.  
%    The modifications to the lookup table input data
% are likely to change the numerical behavior of the table.
% The numerical changes may or may not be trivial, so the
% model should be tested using simulation, rapid prototyping,
% or other appropriate methods. 
%    This function is intended for use with non-tunable data.
% Tunable data is always treated as if it were unevenly spaced.
% Even if it starts out evenly spaced, it may later be tuned to 
% values that are unevenly spaced.
%    It is important to note that the data is judged to be
% "almost" evenly spaced based on the scaling slope.  Consider
% the data vector [0 2 5], which has spacing value 2 and 3.
% A natural first impression is that the data has significantly 
% uneven spacing.  However, the difference between the maximum
% spacing 3 and the minimum spacing 2 equals 1.  If the scaling slope
% is 1 or greater, then a spacing variation of 1 represents a one
% bit change or less.  A spacing variation of one bit or less is 
% judged to be "almost" evenly spaced, and this function will adjust 
% the data to force it to be evenly spaced.
%  
% xdata_original is the input lookup data, ex. 0:0.005:1
% xdt            is the input data type,   ex. sfix(16)
% xscale         is the input scaling,     ex. 2^-12
%
% see also SFIX, UFIX, FIXDT
%          FIXPT_INTERP1,
%          FIXPT_LOOK1_FUNC_APPROX

% Copyright 1994-2004 The MathWorks, Inc.
% $Revision: 1.1.4.1 $  
% $Date: 2004/04/13 00:34:27 $

if nargin < 3
  xscale = [];
end

evenSpacingQuantizedValue = [];

numDt=getdatatypespecs(xdt,xscale,0,0,1);

if ~any(strcmp(numDt.Category,{'Fixed-point: slope and bias scaling','Fixed-point: binary point scaling'}))

  error('simulink:fixedpoint:invaliddatatype',...
        'Data type and scaling inputs must fully specify an integer or fixed-point data type.');
end    

xdiff = diff(xdata_original);

nx = length(xdata_original);

diffdelta = max(xdiff) - min(xdiff);

xdata_adjusted = xdata_original;

if diffdelta > numDt.Slope

  dataStatus = 'Significantly uneven spacing';
  
else
    
  % The spacing in the ideal real world version of
  % the xdata_original is even or nearly even.  Nearly even
  % means that any difference in spacing is less
  % than half the fixed point precision.
  
  xdata_quantized = num2fixpt( xdata_original, numDt, [], 'Nearest', 'on' );
  
  temp = diff(xdata_quantized);

  diffdelta_quantized = max(temp) - min(temp);

  if diffdelta_quantized == 0
    
    evenSpacingQuantizedValue = temp(1);
  
    dataStatus = 'Perfectly even spacing';
    
  else
    
    dataStatus = 'Slightly uneven spacing, modified to be evenly spaced';

    numDt_NoBias = numDt;
    
    numDt_NoBias.Bias = 0;
    
    % After quantization the scaling was not evenly spaced
    % Corrective action to restore the even spacing will be
    % applied.
    
    % Do NOT include bias when quantizing the delta
    %
    evenSpacingQuantizedValue = num2fixpt( mean(xdiff), numDt_NoBias, [], 'Nearest', 'on' );
    
    xstart_quantized = num2fixpt( xdata_original(1), numDt, [], 'Nearest', 'on' );
    
    xdata_adjusted = xstart_quantized + (0:(nx-1))*evenSpacingQuantizedValue;
    
  end
end