function [ADC,k,f,v,sf] = max8_adc_fn(QUANTIZER_TYPE, M0, M)
%-------------------------------------------------------------------------------
% $Id: max8_adc_fn.m,v 1.8 2023/07/26 21:49:41 ddelore Exp $
%
%  David S. De Lorenzo
%  12 December 2019
%
%  A/D converter specification function:  define the ADC & its parameters
%
%-------------------------------------------------------------------------------
%
%  This function returns the following parameters:
%
%    ADC  The quantization algorithm written as an anonymous function
%           This anonumous function will be called by ADC(s,M,L) where
%               s : the input signal
%               M : number of A/D bits
%               L : maximum quantizer threshold
%
%     k   A/D converter's "optimal ratio"
%           This is the optimal ratio of the converter's maximum
%           quantization threshold 'L' to the input signal's noise
%           standard deviation 'sigma'.
%
%     f   A/D converter's "optimal overflow fraction"
%           This is the fraction of samples which are greater than
%           the maximum quantization threshold for each quantizer
%           type at the optimal value of 'k'.
%
%     v   Desired post-A/D noise variance
%           This is in digitized "post-quantization" units, and
%           represents the desired signal variance of the WGN-like
%           component in the sampled data, as estimated (for example)
%           by the noise floor of an averaged spectrum.
%
%     sf  Post-A/D to pre-A/D noise variance scale factor
%           This relates the signal variance of the digitized WGN-like
%           component in the sampled data to the signal variance of the
%           analog pre-A/D signal.
%
%  References:
%
%  1. H. Chang, "Presampling Filtering, Sampling, and Quantization Effects
%     on the Digital Matched Filter Performance", Proc. Intl. Telemetering
%     Conference, 1982, pgs. 889-915.
%
%     For an analog-to-digital converter (ADC), the optimal ratio 'k' of
%     the converter's maximum quantization threshold 'L' to the input signal's
%     noise standard deviation 'sigma' is contained in Table 4; the ratios also
%     are plotted in, e.g., Figures 7(a-c) and Figures 8(a-c).  Consulting the
%     bottom row of Table 4 for Eb/No <= -10 dB and B = 10/T, the optimum
%     values of L/No are given as:
%
%        quantizer       1-bit    2-bit    3-bit    4-bit    5-bit     inf
%       # of levels        2        4        8       16       32       inf
%      k = L / sigma      ---      1.0      1.7      2.3      2.7      ---
%      min. loss [dB]    2.118    0.624    0.221    0.100    0.0638   0.0478
%
%  2. C.J. Hegarty, "Analytical Model for GNSS Receiver Implementation
%     Losses," NAVIGATION, vol. 58, no. 1, 2011, pgs. 29-44.
%     (also appears in Proc. ION GNSS 2009, pgs. 3165-378.)
%
%     See Table 1 --> note column #1 is by the number of quantization
%     levels (not # of bits) and we read column #4, the optimum maximum
%     input threshold level:
%
%        quantizer       1-bit   2-bit   3-bit   4-bit   5-bit   6-bit   7-bit
%       # of levels        2       4       8       16      32      64     128
%      k = L / sigma      ---    0.996   1.758   2.345   2.820   3.224   3.591
%      min. loss [dB]    1.961   0.549   0.166   0.050   0.015   0.005   0.001
%
%
%  3. F. Bastide, et al., "Automatic Gain Control (AGC) as an Interference
%     Assessment Tool", Proc. ION GPS/GNSS 2003, pgs. 2042-2053.
%
%     See Table 1, which presents the following values:
%
%        quantizer       1-bit    2-bit    3-bit    4-bit    5-bit
%       # of levels        2        4        8       16       32
%      k = L / sigma      ---     0.9860   1.7310   2.2910   2.2910
%      min. loss [dB]    1.96     0.5369   0.1589   0.0138   0.0138
%
%  4. A.J. Van Dierendonck, "GPS Receivers", Global Positioning System:
%     Theory and Applications, Vol. 1, AIAA, 1996, pgs. 329-407.
%
%     See Figs 15 & 16 on pgs. 354-355, which duplicate Chang's figures.
%
%-------------------------------------------------------------------------------

% The quantization algorithm written as an anonymous function
%
%    s : the input signal
%    M : number of A/D bits
%    L : maximum quantizer threshold
%
switch QUANTIZER_TYPE

    case 'centered'
        % A centered & uniform quantization law
        %
        %   "Centered" means that you have a zero-valued bin, which
        %   means that you have to give up one bin in order to have a
        %   balanced output, i.e., for a zero-mean (DC-balanced) input,
        %   the expcted value of the quantized output == 0.0.
        %
        %       e.g., for 3-bit "centered" quantizer:
        %
        %           --> your bin edges look like
        %                 (L/5)*[-inf -5 -3 -1 +1 +3 +5 +inf]
        %
        %           --> and your output values are
        %                 [-3 -2 -1 0 +1 +2 +3]
        %
        %    *** the quantization interval for a centered M-bit A/D ***
        %              --> (2*L) / (2^M - 3)
        %
        %                                   the range is [-L, +L] = 2*L
        %                                    |
        %                                    |    there are (2^M-2) bin edges
        %                                    |     |  thus, [(2^M-2) - 1] bins
        ADC = @(s,M,L) ...                  _|_   _|_
               discretize( s, ...          /   \ /   \              % input
                           [-inf, linspace(-L,+L,2^M-2), +inf], ... % edges
                           linspace(-2^(M-1)+1,2^(M-1)-1,2^M-1)  ); % output
                                 %  \________________________/
                                 %              |
                                 %    for example, with M = 3, your output are
                                 %          {-3, -2, -1, 0, +1, +2, +3}

    case 'non-centered'
        % A non-centered & uniform quantization law
        %
        %   "Non-centered" means that you have a zero-valued bin edge,
        %   which means that you have output values of +1/-1 and you
        %   need to maintain this 2-unit uniform output spacing by
        %   adjusting the quantized output accordingly.
        %
        %       e.g., for 3-bit "non-centered" quantizer:
        %
        %           --> your bin edges look like
        %                 (L/3)*[-inf -3 -2 -1 0 +1 +2 +3 +inf]
        %
        %           --> and your output values are
        %                 [-7 -5 -3 -1 +1 +3 +5 +7]
        %
        %    *** the quantization interval for a non-centered M-bit A/D ***
        %              --> (2*L) / (2^M - 2)
        %
        %                                   the range is [-L, +L] = 2*L
        %                                    |
        %                                    |    there are (2^M-1) bin edges
        %                                    |     |  thus, [(2^M-1) - 1] bins
        ADC = @(s,M,L) ...                  _|_   _|_
               discretize( s, ...          /   \ /   \              % input
                           [-inf, linspace(-L,+L,2^M-1), +inf], ... % edges
                           linspace(-2^M+1,2^M-1,2^M)            ); % output
                                 %  \______________/
                                 %          |
                                 %    for example, with M = 3, your output are
                                 %          {-7, -5, -3, -1, +1, +3, +5, +7}

    case 'quantizer by-pass'
        % Copy input --> output
        ADC = @(s,M,L)s;

    otherwise
        error('Invalid quantization option!!');
end

% Allow early function return when all we want
% is the 'ADC' anonymous function definition.
if (nargout == 1)
    return
end

% Look up the optimal ratio 'k' of the converter's maximum
% quantization threshold 'L' to the input signal's noise
% standard deviation 'sigma'.
%
%   Refer to the function 'adc_quantization_scale_factor.m'
%   for further information on how the optimal ratios in the
%   following switch statement were determined.
%
switch QUANTIZER_TYPE
    case 'centered'
        switch M0
            case 2
                % k = 0.612;    % C. Hegarty
                k = 0.62;       % DSD - 2021
            case 3
                % k = 1.628;    % C. Hegarty
                k = 1.62;       % DSD - 2021
            case 4
                % k = 2.285;    % C. Hegarty (interpolated)
                k = 2.30;       % DSD - 2021
            case 5
                % k = 2.795;    % C. Hegarty (interpolated)
                k = 2.80;       % DSD - 2021
            case 6
                % k = 3.221;    % C. Hegarty (interpolated)
                k = 3.2;        % DSD - 2021
            case 7
                % k = 3.59;     % C. Hegarty (interpolated)
                k = 3.6;        % DSD - 2021
            case {8, 9, 10, 11, 12, 13, 14}
                k = 3.6;
                % Beyond 3-sigma, the rarity of samples from a Gaussian
                % distribution makes the calculation of this optimal
                % ratio overly-sensitive.  Thus, we cap the ratio of
                % the converter's maximum quantization threshold to
                % the input signal's noise standard deviation to a
                % value of 3.6.
            otherwise
                error('Invalid quantization option!!');
        end
    case 'non-centered'
        switch M0
            case 2
                % k = 1.0;      % H. Chang
                % k = 0.996;    % C. Hegarty
                % k = 0.9860;   % Bastide et al.
                k = 1.00;       % DSD - 2021
            case 3
                % k = 1.7;      % H. Chang
                % k = 1.758;    % C. Hegarty
                % k = 1.7310;   % Bastide et al.
                k = 1.77;       % DSD - 2021
            case 4
                % k = 2.3;      % H. Chang
                % k = 2.345;    % C. Hegarty
                % k = 2.2910;   % Bastide et al.
                k = 2.35;       % DSD - 2021
            case 5
                % k = 2.7;      % H. Chang
                % k = 2.820;    % C. Hegarty
                % k = 2.2910;   % Bastide et al.
                k = 2.80;       % DSD - 2021
            case 6
                % k = 3.224;    % C. Hegarty
                k = 3.2;        % DSD - 2021
            case 7
                % k = 3.591;    % C. Hegarty
                k = 3.6;        % DSD - 2021
            case {8, 9, 10, 11, 12, 13, 14}
                k = 3.6;
                % Beyond 3-sigma, the rarity of samples from a Gaussian
                % distribution makes the calculation of this optimal
                % ratio overly-sensitive.  Thus, we cap the ratio of
                % the converter's maximum quantization threshold to
                % the input signal's noise standard deviation to a
                % value of 3.6.
            otherwise
                error('Invalid quantization option!!');
        end
    case 'quantizer by-pass'
        k = [];
    otherwise
        error('Invalid quantizer type!!');
end

% Look up the desired fraction of samples which are greater than
% the maximum quantization threshold at the optimal value of 'k'.
%
%   Refer to the function 'adc_quantization_scale_factor.m'
%   for further information on how the overflow fractions in
%   the following switch statement were determined.
%
switch QUANTIZER_TYPE
    case 'centered'
        switch M
            case 2
                f = 0.538;
            case 3
                f = 0.104;
            case 4
                f = 0.021;
            otherwise
                if ((floor(M) == M) && M >= 5)  % M must be datatype 'double'
                                                % but we need it integer-valued
                    % For M >= 6, the overflow fraction is < 0.005,
                    % so use a vaue of 0.005 (one sample in 200) rather
                    % than base the AGC gain on a filtered estimate of
                    % a very small number (and face potential numerical
                    % precision issues).
                    f = 0.005;
                else
                    error('Invalid quantization option!!');
                end
        end
    case 'non-centered'
        switch M
            case 2
                f = 0.318;
            case 3
                f = 0.080;
            case 4
                f = 0.018;
            otherwise
                if ((floor(M) == M) && M >= 5)  % M must be datatype 'double'
                                                % but we need it integer-valued
                    % For M >= 6, the overflow fraction is < 0.005,
                    % so use a vaue of 0.005 (one sample in 200) rather
                    % than base the AGC gain on a filtered estimate of
                    % a very small number (and face potential numerical
                    % precision issues).
                    f = 0.005;
                else
                    error('Invalid quantization option!!');
                end
        end
    case 'quantizer by-pass'
        f = [];
    otherwise
        error('Invalid quantizer type!!');
end

% Desired post-A/D noise variance
%
%   This is in digitized "post-quantization" units, and
%   represents the desired signal variance of the WGN-like
%   component in the sampled data, as estimated (for example)
%   by the noise floor of an averaged spectrum.
%
%   *** Note, these values are for complex data!! ***
%
%   Refer to the function 'adc_quantization_study.m' for
%   further information on how the noise variance values
%   in the following switch statement were determined.
%
switch QUANTIZER_TYPE
    case 'centered'
        switch M0
            case 2
                v = 1.468;
            case 3
                v = 4.931;
            case 4
                v = 16.17;
            case 5
                v = 53.79;
            case 6
                v = 181.8;
            case 7
                v = 602.9;
            case 8
                v = 2217.;
            otherwise
                % error('Invalid quantization option!!');
                v = [];
        end
    case 'non-centered'
        switch M0
            case 2
                v = 8.670;
            case 3
                v = 23.65;
            case 4
                v = 71.65;
            case 5
                v = 230.2;
            case 6
                v = 751.4;
            case 7
                v = 2451.;
            case 8
                v = 8942.;
            otherwise
                % error('Invalid quantization option!!');
                v = [];
        end
    case 'quantizer by-pass'
        v = [];
    otherwise
        error('Invalid quantizer type!!');
end

% Post-A/D to pre-A/D noise variance scale factor
%
%   This relates the signal variance of the digitized WGN-like
%   component in the sampled data to the signal variance of the
%   analog pre-A/D signal.
%
%   Recall from above, the quantization intervals are:
%         centered   M-bit A/D  -->  (2*L) / (2^M - 3)
%       non-centered M-bit A/D  -->  (2*L) / (2^M - 2)
%
%   So, scaling by the ratio of 'M' vs. 'M0' quantization
%   intervals, and squaring to get variance-like squared
%   units, introducds the following terms into the respective
%   scale factor formulas below:
%         centered   A/D  -->  ( (2^M - 3) / (2^M0 - 3) )^2
%       non-centered A/D  -->  ( (2^M - 2) / (2^M0 - 2) )^2
%
%   *** Note, these values are for complex data!! ***
%
%   Refer to the function 'adc_quantization_study.m' for
%   further information on how the noise variance scale
%   factor equations listed below were determined.
%
switch QUANTIZER_TYPE
    case 'centered'
        sf = v * ( k/sqrt(2) * (2^M - 3) / (2^M0 - 3) )^2;
    case 'non-centered'
        sf = v * ( k/sqrt(2) * (2^M - 2) / (2^M0 - 2) )^2;
    case 'quantizer by-pass'
        sf = [];
    otherwise
        error('Invalid quantizer type!!');
end

return
%===============================================================================