function [inl,dnl] = inldnl_th(th)
% INLDNL_TH   compute INL and DNL from converter decision thresholds
%      th       ADC decision levels

if nargin == 0
   error('must specify ADC decision thresholds');
end

N   = length(th);
th  = reshape(th, 1, N);
dnl = diff(th) - 1;
inl = th - linspace(th(1), th(end), N);
inl(1) = [];

if nargout==0
   % plot result
   if N > 16
      fmt = 'r-';
   else
      fmt = 'ro:';
   end
   subplot(2,1,1);
   plot(1:N-1, dnl, fmt, [0 N-1], [1 -1; 1 -1], 'b:');
   fixfig;
   xlabel('bin');  ylabel('DNL  [in LSB]');
   maxdnl = ceil(max(dnl));
   axis([1 N-1 floor(min(dnl)) maxdnl+1]);
   text(0.1*N+1, maxdnl+0.2, ...
      sprintf('%.1g / +%.1g LSB,  avg=%.2g,  std.dev=%.2g,  range=%.2g', ...
         min(dnl), max(dnl), mean(dnl), std(dnl), max(dnl)-min(dnl)));
   title(sprintf('DNL and INL of %.2g Bit converter (from converter decision thresholds)', ...
      log2(N)));
   subplot(2,1,2);
   plot(1:N-1, inl, fmt, [0 N-1], [1 -1; 1 -1], 'b:');
   fixfig;
   xlabel('bin');  ylabel('INL  [in LSB]');
   maxinl = ceil(max(inl));
   axis([1 N-1 floor(min(inl)) maxinl+1]);
   text(0.1*N+1, maxinl+0.2, ...
      sprintf('%.1g / +%.1g LSB,  avg=%.2g,  std.dev=%.2g,  range=%.2g', ...
         min(inl), max(inl), mean(inl), std(inl), max(inl)-min(inl)));
end
