diff --git a/GaussFIR.cpp b/GaussFIR.cpp index 1d81aff..cc2c007 100644 --- a/GaussFIR.cpp +++ b/GaussFIR.cpp @@ -20,6 +20,27 @@ static inline double dnorm(double x, double mu, double sigma) } // Calculate length and FIR coefficients for a Gaussian shaped low pass filter. +// +// F2sig is the two-sigma width of the target Doppler POWER spectrum of the +// fading process (the Watterson / ITU-R F.1487 "frequency spread" convention: +// the tap-gain process must have a Gaussian power spectral density whose +// 2-sigma width is the specified Doppler spread). +// +// NOTE for reimplementers: the power spectral density of filtered white noise +// is |H(f)|^2, so this filter's AMPLITUDE response must be the SQUARE ROOT of +// the target Gaussian PSD -- itself Gaussian-shaped, but sqrt(2) wider. That +// is where the SQRT2 in the sigma expression below comes from: +// +// impulse response sigma_t = Fs*sqrt(2) / (2*pi*F2sig) [samples] +// amplitude |H(f)| Gaussian with sigma_f = F2sig/sqrt(2) +// power |H(f)|^2 Gaussian with sigma = F2sig/2 (2-sigma = F2sig) +// +// Dropping the sqrt(2) -- i.e. treating the target power spectrum as the +// amplitude response -- narrows the realized Doppler spread to ~0.71x the +// specified value. This is a real reimplementation trap: the prose in the +// original PathSim technical guide (section 4.1.5) describes "a Gaussian +// shaped low pass filter" without calling out the square root, and at least +// one downstream reimplementation inherited a narrowed spread that way. void GaussFIR::init(double Fs, double F2sig) { double sigma = (Fs * SQRT2) / (PI2 * F2sig); diff --git a/GaussFIR.h b/GaussFIR.h index d724b2f..b2eeb1f 100644 --- a/GaussFIR.h +++ b/GaussFIR.h @@ -1,4 +1,7 @@ -// Gaussian low pass filter +// Gaussian low pass filter used to shape the Doppler (fading) spectrum. +// Its amplitude response is the SQUARE ROOT of the target Gaussian power +// spectrum (the sqrt(2) in the sigma constant) -- see the note above +// GaussFIR::init() in GaussFIR.cpp before reusing this design elsewhere. #ifndef PATHSIM_GAUSS_FIR_HPP #define PATHSIM_GAUSS_FIR_HPP