Implementing the Dolph-Chebyshev Window

Introduction §

Chebyshev's name can be alternatively transliterated as Chebychev, Chebysheff, Chebyshov, Tchebychev or Tchebycheff, or Tschebyschev or Tschebyscheff, which often makes it difficult to find anything about him in search engines.

The Dolph-Chebyshev window (a.k.a Chebyshev window) is used in signal processing. It is optimal in that it has a minimum main-lobe width for a given side-lobe attenutation. Another property of the Chebyshev window is that it is equi-ripple, i.e. the side-lobe height is the same at all frequencies.

The Dolph-Chebyshev Window §

The majority of sources that describe the Chebyshev window describe it in frequency domain, e.g. Lyons [1] describes it as:

is the N-point inverse DFT of

where and is the required sidelobe attenuation in dB (e.g. -60 for sidelobe attenuation of 60dB).

Most windows, however, are defined in time domain (not frequency domain like the example above). Several sources even indicate that there is no direct time domain expression for the chebyshev window, however this is not true. Antoniou [2] describes the time domain representation of the Chebyshev window as:

where and is the chebyshev polynomial of the first kind, defined by the following formula:

The thing to note here is that as defined by Lyons [1] is (almost) the same as in Antoniou [2], if , where is the required passband ripple and is the sidelobe attenuation in dB. Antoniou's formula for should be used for the time domain implementation, as this gives results very similar to the matlab implementation of chebwin.

C Implementation of the Chebyshev Window §

/***************************************************************************
 calculate a chebyshev window of size N, store coeffs in out as in Antoniou
-out should be array of size N 
-atten is the required sidelobe attenuation (e.g. if you want -60dB atten, use '60')
***************************************************************************/
void cheby_win(float *out, int N, float atten){
    int nn, i;
    double M, n, sum = 0, max=0;
    double tg = pow(10,atten/20);  /* 1/r term [2], 10^gamma [2] */
    double x0 = cosh((1.0/(N-1))*acosh(tg));
    M = (N-1)/2;
    if(N%2==0) M = M + 0.5; /* handle even length windows */
    for(nn=0; nn<(N/2+1); nn++){
        n = nn-M;
        sum = 0;
        for(i=1; i<=M; i++){
            sum += cheby_poly(N-1,x0*cos(PI*i/N))*cos(2.0*n*PI*i/N);
        }
        out[nn] = tg + 2*sum;
        out[N-nn-1] = out[nn];
        if(out[nn]>max)max=out[nn];
    }
    for(nn=0; nn<N; nn++) out[nn] /= max; /* normalise everything */
    return;
}

/**************************************************************************
This function computes the chebyshev polyomial T_n(x)
***************************************************************************/
double cheby_poly(int n, double x){
    double res;
    if (fabs(x) <= 1) res = cos(n*acos(x));
    else              res = cosh(n*acosh(x));
    return res;
}

References §

[1] Lyons, R., "Understanding Digital Signal Processing", Prentice Hall, 2004.

[2] Antoniou, A., "Digital Filters", McGraw-Hill, 2000.

comments powered by Disqus
YBL KRQ IBF KFNLH R KFSQYRDQ MLXDQH MV TRPPVDQX - TFQZSTDSH