%% Design Efficient Interpolator
% Design a single-stage interpolator using the designMultirateFIR function and a multistage interpolator using the designMultistageInterpolator function. Determine the efficiency of the two designs using the cost function. The implementation efficiency is characterized by two cost metrics: NumCoefficients and MultiplicationsPerInputSample.
% Compute the cost of implementing both designs, and determine which design is more efficient. To make a comparison, design the filters such that their transition width is the same.
%% Initialization
% Choose an interpolation factor of 48, input sample rate of 30.72 MHz, one-sided bandwidth of 100 kHz, and a stopband attenution of 90 dB.

L = 48;
Fin = 30.72e6;
Astop = 90;
BW = 1e5;

%
%% Using the designMultirateFIR Function
% Designing the interpolation filter using the designMultirateFIR function yields a single-stage design. Set the half-polyphase length to a finite integer, in this case 4.

HalfPolyLength = 4;
b = designMultirateFIR(L,1,HalfPolyLength,Astop);
d = dsp.FIRInterpolator(L,b)

% Compute the cost of implementing the interpolator. The interpolation filter requires 376 coefficients and 7 states. The number of multiplications per input sample and additions per input sample are 376 and 329, respectively.

cost(d)

%
%% Using the designMultistageInterpolator Function
% Design a multistage interpolator with the same filter specifications as the single-stage design. Compute the transition width using the following relationship:

Fc = Fin/(2*L);
TW = 2*(Fc-BW);

% By default, the number of stages given by the NumStages argument is set to 'Auto', yielding an optimal design that tries to minimize the number of multiplications per input sample.

c = designMultistageInterpolator(L,Fin,TW,Astop)

%
% Calling the info function on c shows that the filter is implemented as a cascade of two dsp.FIRInterpolator objects with interpolation factors of 24 and 2, respectively.
%
% Compute the cost of implementing the interpolator.

cost(c)

% The NumCoefficients and the MultiplicationsPerInputSample parameters are lower for the two-stage filter designed by the designMultistageInterpolator function, making it more efficient.
%
% Compare the magnitude response of both designs.

fvtool(b,c)
legend('Single-stage','Multistage')

% The magnitude response shows that the transition width of both the filters is the same, making the filters comparable. The cost function shows that implementing the multistage design is more efficient compared to implementing the single-stage design.
%
%% Using the 'design' Option in the designMultistageInterpolator Function
% The filter can be made even more efficient by setting the 'CostMethod' argument of the designMultistageInterpolator function to 'design'. By default, this argument is set to 'estimate'.
% In the 'design' mode, the function designs each stage and computes the filter order. This yields an optimal design compared to the 'estimate' mode, where the function estimates the filter order for each stage and designs the filter based on the estimate.
% Note that the 'design' option can take much longer compared to the 'estimate' option.

cOptimal = designMultistageInterpolator(L,Fin,TW,Astop,'CostMethod','design')

%

cost(cOptimal)

%
% Copyright 2018 The MathWorks, Inc.