Asimetrik pencereli FFT?


17

Ortak dikdörtgen olmayan pencere işlevlerinin hepsi simetrik görünmektedir. Bir FFT önce simetrik olmayan bir pencere işlevi kullanmak istediği bir durum var mı? (FFT açıklığının bir tarafındaki verilerin, diğer taraftaki verilerden biraz daha önemli veya daha az gürültülü vb.

Eğer öyleyse, ne tür asimetrik pencere fonksiyonları üzerinde çalışılmıştır ve (daha kayıplı?) Ofset simetrik pencereye kıyasla frekans tepkisini nasıl etkilerler?


2
Genellikle FFT, bir sinyalin küçük parçaları üzerinde çalıştığı ve lokal olarak sabit bir sinyal gibi görünmeye çalıştığı için kullanılır. Bu yüzden tercih edilecek bir "yan" yoktur, sinyalin her yerde eşit olduğu varsayılır.
endolit

4
canlı veriler üzerinde çalışan ve endişelenecek verim gecikmesi olan bir ses analizi algoritmasında, bazen aynı uzunlukta simetrik pencereden daha az etkili gecikmeye sahip bir asimetrik pencere tasarlanabilir. bu asimetrik pencerenin davranışı (önceden bilinir), bu ses analizinin çıkış parametrelerini bilinen bir şekilde etkiliyorsa, bu parametreler telafi edilebilir ve azaltılmış gecikme avantajını korursunuz.
robert bristow-johnson

Yanıtlar:


9

"Pencere işlevi" için steno penceresini kullanacağım .

Ses ile, ön zil veya ön ekoya benzer bir şey oluşturan herhangi bir işlem, düşük bit oranlı bir mp3 gibi ses çıkarır. Bu, geçici veya bir impulsun lokalize enerjisi zaman içinde geriye doğru yayıldığında, örneğin alışılmış modifiye edilmiş ayrı kosinüs dönüşümü (MDCT) gibi alışılmış dönüşümlerdeki spektral verilerin modifikasyonu ile olur. Böyle bir işlemde ses, üst üste binen analiz pencereleriyle pencerelenir , dönüştürülür, frekans alanında işlenir (veriler daha küçük bir bit hızına sıkıştırılır gibi), bir sentez penceresi ile tekrar pencerelenir ve tekrar toplanır. Analiz ve sentez penceresinin ürünü, üst üste binen pencerelerin birliğe ulaşacağı şekilde olmalıdır.

Geleneksel olarak kullanılan pencere fonksiyonları simetriktir ve genişlikleri frekans seçiciliği (uzun pencere) ile zaman alanı artefaktının önlenmesi (kısa pencere) arasında bir uzlaşma olmuştur. Pencere ne kadar geniş olursa, işlem o kadar fazla geri döner, sinyali yayabilir. Daha yeni bir çözüm asimetrik bir pencere kullanmaktır. Kullanılan iki pencere birbirinin ayna görüntüsü olabilir. Analiz penceresi tepeden sıfıra hızlı düşer, böylece impulslar önceden "algılanmaz" ve sentez penceresi sıfırdan tepeye hızlı yükselir, böylece herhangi bir işlemin etkisi zaman içinde çok geriye yayılmaz. Bunun bir diğer avantajı düşük gecikmedir. Asimetrik pencereler iyi bir frekans seçiciliğine sahip olabilir ve bir tür iyileştirme gibi, ses sıkıştırmada değişken boyutlu simetrik pencerelerin yerini alabilir. GörmekSchnell, M. Schmidt, M. Jander, T. Albert, R. Geiger, V. Ruoppila, P. Ekstrand, M. Lutzky, B. Grill, “MPEG-4 Geliştirilmiş Düşük Gecikmeli AAC - yüksek için yeni bir standart kaliteli iletişim ” , 125. AES Sözleşmesi, San Francisco, CA, ABD, 7503, Ekim 2008 preprint ve ayrıca pencerelerinin Fourier dönüşümünün büyüklüğünü gösterdikleri başka bir konferans kağıdı: Schnell, M., et al. 2007. Gelişmiş MPEG-4 Düşük Gecikmeli AAC - Düşük Bit Hızı Yüksek Kaliteli İletişim. 122. AES Sözleşmesinde .

Asimetrik pencereler kullanılarak alışılmış analiz-işleme-sentezinin gösterimi
Şekil 1. Asimetrik pencerelerin alışılmış analiz-işleme-sentezinde kullanımının gösterimi. Analiz penceresinin (mavi) ve sentez penceresinin (sarımsı turuncu) ürünü (siyah kesikli), bir önceki kareden (gri kesikli) gelen pencereyle bütünlük oluşturur. MDCT kullanırken mükemmel rekonstrüksiyonu garanti etmek için daha fazla kısıtlamaya ihtiyaç vardır.

MDCT yerine Ayrık Fourier dönüşümü (DFT, FFT) kullanılabilir, ancak bu bağlamlarda gereksiz spektral veriler verecektir. DFT ile karşılaştırıldığında, MDCT spektral verilerin sadece yarısını verirken uygun pencereler seçilirse mükemmel yeniden yapılandırmayı mümkün kılar.

İşte kendi asimetrik pencere tasarımım (Şekil 2), DFT kullanarak alışılmış analiz-işleme-sentezi için uygundur, ancak mükemmel rekonstrüksiyon vermediği MDCT için değildir. Pencere, potansiyel olarak faydalı bazı zaman alanı özelliklerini korurken ortalama kare zaman ve frekans bant genişliklerinin ( sınırlı Gauss penceresine benzer şekilde) çarpımını en aza indirmeye çalışır : negatif olmayan, analiz ve sentezin etrafında "zaman sıfırında" pik ile pencereler birbirinin ayna görüntüleri, fonksiyon ve birinci türev sürekliliği, pencere fonksiyonunun karesi normal olmayan olasılık yoğunluk fonksiyonu olarak yorumlandığında sıfır ortalamadır. Pencere, diferansiyel evrim kullanılarak optimize edildi .

Asimetrik ve kosinüs penceresi
Şekil 2. Sol: Zaman tersine ters karşılığı sentez penceresi ile örtüşen analiz-işleme-resentezi için uygun asimetrik bir analiz penceresi. Sağ: Kosinüs penceresi, asimetrik pencereyle aynı gecikmeye sahip

Pencerelerin Fourier Dönüşümü
Şekil 3. Şekil 2'deki kosinüs penceresinin (mavi) ve asimetrik pencerenin (turuncu) Fourier dönüşümlerinin büyüklüğü Asimetrik pencere daha iyi frekans seçiciliği gösterir.

İşte grafikler ve asimetrik pencere için Octave kaynak kodu. Çizim kodu Wikimedia Commons'tan gelir . Ben yüklemenizi öneririz Linux'ta gnuplot, epstool, pstoedit, transfigbirinci ve librsvg2-binkullanılarak görüntüleme display.

pkg load signal

graphics_toolkit gnuplot
set (0, "defaultaxesfontname", "sans-serif")
set (0, "defaultaxesfontsize", 12) 
set (0, "defaultaxeslinewidth", 1)

function plotWindow (w, wname, wfilename = "", wspecifier = "", wfilespecifier = "")

  M = 32; % Fourier transform size as multiple of window length
  Q = 512; % Number of samples in time domain plot
  P = 40; % Maximum bin index drawn
  dr = 130; % Maximum attenuation (dB) drawn in frequency domain plot

  N = length(w);
  B = N*sum(w.^2)/sum(w)^2 % noise bandwidth (bins)

  k = [0 : 1/Q : 1];
  w2 = interp1 ([0 : 1/(N-1) : 1], w, k);

  if (M/N < Q)
    Q = M/N;
  endif

  figure('position', [1 1 1200 600])
  subplot(1,2,1)
  area(k,w2,'FaceColor', [0 0.4 0.6], 'edgecolor', [0 0 0], 'linewidth', 1)
  if (min(w) >= -0.01)
    ylim([0 1.05])
    set(gca,'YTick', [0 : 0.1 : 1])
  else
    ylim([-1 5])
    set(gca,'YTick', [-1 : 1 : 5])
  endif
  ylabel('amplitude')
  set(gca,'XTick', [0 : 1/8 : 1])
  set(gca,'XTickLabel',[' 0'; ' '; ' '; ' '; ' '; ' '; ' '; ' '; 'N-1'])
  grid('on')
  set(gca,'gridlinestyle','-')
  xlabel('samples')
  if (strcmp (wspecifier, ""))
    title(cstrcat(wname,' window'), 'interpreter', 'none')
  else
    title(cstrcat(wname,' window (', wspecifier, ')'), 'interpreter', 'none')
  endif
  set(gca,'Position',[0.094 0.17 0.38 0.71])

  H = abs(fft([w zeros(1,(M-1)*N)]));
  H = fftshift(H);
  H = H/max(H);
  H = 20*log10(H);
  H = max(-dr,H);
  k = ([1:M*N]-1-M*N/2)/M;
  k2 = [-P : 1/M : P];
  H2 = interp1 (k, H, k2);

  subplot(1,2,2)
  set(gca,'FontSize',28)
  h = stem(k2,H2,'-');
  set(h,'BaseValue',-dr)
  xlim([-P P])
  ylim([-dr 6])
  set(gca,'YTick', [0 : -10 : -dr])
  set(findobj('Type','line'),'Marker','none','Color',[0.8710 0.49 0])
  grid('on')
  set(findobj('Type','gridline'),'Color',[.871 .49 0])
  set(gca,'gridlinestyle','-')
  ylabel('decibels')
  xlabel('bins')
  title('Fourier transform')
  set(gca,'Position',[0.595 0.17 0.385 0.71])

  if (strcmp (wfilename, ""))
    wfilename = wname;
  endif
  if (strcmp (wfilespecifier, ""))
    wfilespecifier = wspecifier;
  endif
  if (strcmp (wfilespecifier, ""))
    savetoname = cstrcat('Window function and frequency response - ', wfilename, '.svg');
  else
    savetoname = cstrcat('Window function and frequency response - ', wfilename, ' (', wfilespecifier, ').svg');
  endif
  print(savetoname, '-dsvg', '-S1200,600')
  close

endfunction

N=2^17; % Window length, B is equal for Triangular and Bartlett from 2^17
k=0:N-1;

w = -cos(2*pi*k/(N-1));
w .*= w > 0;
plotWindow(w, "Cosine")

freqData = [0.66697133904805994131, -0.20556692772918355727, 0.49267389481655493588, -0.25062332863369246594, -0.42388422228212319087, 0.42317609537724842905, -0.03930334287740060856, -0.11936153294075849129, 0.30201210285940127687, -0.15541616804857899536, -0.16208119255594669039, 0.12843871362286504723, -0.04470810646117385351, -0.00521885027256757845, 0.07185811583185619522, -0.02835116723496184862, -0.01393644785822748498, 0.00780746224568363342, -0.00748496824751256583, 0.00119325723511989282, 0.00194602547595042175];
freqData(1) /= 2;
scale = freqData(1) + sum(freqData.*not(mod(1:length(freqData), 2)));
freqData /= scale;
w = freqData(1)*ones(1, N);
for bin = 1:(length(freqData)/2)
  w += freqData(bin*2)*cos(2*pi*bin*((1:N)-1)/N);
  w += freqData(bin*2+1)*sin(2*pi*bin*((1:N)-1)/N);
endfor
w(N/4+1:N/2+1) = 0;
w(N/8+2:N/4) = (1 - w(N/8:-1:2).*w(7*N/8+2:N))./w(7*N/8:-1:6*N/8+2);
w = shift(w, -N/2);
plotWindow(w, "Asymmetrical");

Pencerenin yalnızca her ikinci örneğini kullanmak isteyebilirsiniz, çünkü sıfırdan başlar ve biter. Aşağıdaki C ++ kodu bunu sizin için yapar, böylece pencerenin dörtte biri dışında her yerde sıfır dışında sıfır örnek alamazsınız. Analiz penceresi için bu ilk çeyrek ve sentez penceresi için bu son çeyrek. Analiz penceresinin ikinci yarısı, ürünlerinin hesaplanması için sentez penceresinin ilk yarısı ile hizalanmalıdır. Kod ayrıca pencerenin ortalamasını da (olasılık yoğunluk fonksiyonu olarak) test eder ve üst üste binen rekonstrüksiyonun düzlüğünü gösterir.

#include <stdio.h>
#include <math.h>

int main() {
  const int windowSize = 400;
  double *analysisWindow = new double[windowSize];
  double *synthesisWindow = new double[windowSize];
  for (int k = 0; k < windowSize/4; k++) {
    analysisWindow[k] = 0;
  }
  for (int k = windowSize/4; k < windowSize*7/8; k++) {
    double x = 2 * M_PI * ((k+0.5)/windowSize - 1.75);
    analysisWindow[k] = 2.57392230162633461887-1.58661480271141974718*cos(x)+3.80257516644523141380*sin(x)
      -1.93437090055110760822*cos(2*x)-3.27163999159752183488*sin(2*x)+3.26617449847621266201*cos(3*x)
      -0.30335261753524439543*sin(3*x)-0.92126091064427817479*cos(4*x)+2.33100177294084742741*sin(4*x)
      -1.19953922321306438725*cos(5*x)-1.25098147932225423062*sin(5*x)+0.99132076607048635886*cos(6*x)
      -0.34506787787355830410*sin(6*x)-0.04028033685700077582*cos(7*x)+0.55461815542612269425*sin(7*x)
      -0.21882110175036428856*cos(8*x)-0.10756484378756643594*sin(8*x)+0.06025986430527170007*cos(9*x)
      -0.05777077835678736534*sin(9*x)+0.00920984524892982936*cos(10*x)+0.01501989089735343216*sin(10*x);
  }
  for (int k = 0; k < windowSize/8; k++) {
    analysisWindow[windowSize-1-k] = (1 - analysisWindow[windowSize*3/4-1-k]*analysisWindow[windowSize*3/4+k])/analysisWindow[windowSize/2+k];
  }
  printf("Analysis window:\n");
  for (int k = 0; k < windowSize; k++) {
    printf("%d\t%.10f\n", k, analysisWindow[k]);
  }
  double accu, accu2;
  for (int k = 0; k < windowSize; k++) {
    accu += k*analysisWindow[k]*analysisWindow[k];
    accu2 += analysisWindow[k]*analysisWindow[k];
  }
  for (int k = 0; k < windowSize; k++) {
    synthesisWindow[k] = analysisWindow[windowSize-1-k];
  }
  printf("\nSynthesis window:\n");
  for (int k = 0; k < windowSize; k++) {
    printf("%d\t%.10f\n", k, synthesisWindow[k]);
  }
  printf("Mean of square of analysis window as probability density function:\n%f", accu/accu2);
  printf("\nProduct of analysis and synthesis windows:\n");
  for (int k = 0; k < windowSize/2; k++) {
    printf("%d\t%.10f\n", k, analysisWindow[windowSize/2+k]*synthesisWindow[k]);
  }
  printf("\nSum of overlapping products of windows:\n");
  for (int k = 0; k < windowSize/4; k++) {
    printf("%d\t%.10f\n", k, analysisWindow[windowSize/2+k]*synthesisWindow[k]+analysisWindow[windowSize/2+k+windowSize/4]*synthesisWindow[k+windowSize/4]);
  }
  delete[] analysisWindow;
  delete[] synthesisWindow;
}

Ve Kiss FFT ve bir optimizasyon kütüphanesi ile kullanılacak optimizasyon maliyeti fonksiyonunun kaynak kodu :

class WinProblem : public Opti::Problem {
private:
  int numParams;
  double *min;
  double *max;
  kiss_fft_scalar *timeData;
  kiss_fft_cpx *freqData;
  int smallSize;
  int bigSize;
  kiss_fftr_cfg smallFFTR;
  kiss_fftr_cfg smallIFFTR;
  kiss_fftr_cfg bigFFTR;
  kiss_fftr_cfg bigIFFTR;

public:
  // numParams must be odd
  WinProblem(int numParams, int smallSize, int bigSize, double* candidate = NULL) : numParams(numParams), smallSize(smallSize), bigSize(bigSize) {
    min = new double[numParams];
    max = new double[numParams];
    if (candidate != NULL) {
      for (int i = 0; i < numParams; i++) {
        min[i] = candidate[i]-fabs(candidate[i])*(1.0/65536);
        max[i] = candidate[i]+fabs(candidate[i])*(1.0/65536);
      }
    } else {
      for (int i = 0; i < numParams; i++) {
        min[i] = -1;
        max[i] = 1;
      }
    }
    timeData = new kiss_fft_scalar[bigSize];
    freqData = new kiss_fft_cpx[bigSize/2+1];
    smallFFTR = kiss_fftr_alloc(smallSize, 0, NULL, NULL);
    smallIFFTR = kiss_fftr_alloc(smallSize, 1, NULL, NULL);
    bigFFTR = kiss_fftr_alloc(bigSize, 0, NULL, NULL);
    bigIFFTR = kiss_fftr_alloc(bigSize, 1, NULL, NULL);
  }

  double *getMin() {
    return min;
  }

  double *getMax() {
    return max;
  }

// ___                                                            __ 1     
// |  \    |       |       |       |       |       |       |     / |       
// |   \   |       |       |       |       |       |       |    /  |       
// |    \_ |       |       |       |       |       |       |   /   |
// |      \|__     |       |       |       |       |       |  /|   |       
// |       |  -----|_______|___    |       |       |       | / |   |       
// |       |       |       |   ----|       |       |       |/  |   |       
// --------------------------------x-----------------------x---|---- 0
// 0      1/8     2/8     3/8     4/8     5/8     6/8     7/8 15/16 
// |-------------------------------|                       |-------|
//            zeroStarts                                   winStarts
//
// f(x) = 0 if 4/8 < x < 7/8
// f(-x)f(x) + f(-x+1/8)f(x-1/8) = 1 if 0 < x < 1/8

  double costFunction(double *params, double compare, int print) {
    double penalty = 0;
    double accu = params[0]/2;
    for (int i = 1; i < numParams; i += 2) {
      accu += params[i];
    }
    if (print) {
      printf("%.20f", params[0]/2/accu);
      for (int i = 1; i < numParams; i += 2) {
        printf("+%.20fcos(%d pi x)", params[i]/accu, (i+1)/2);
        printf("+%.20fsin(%d pi x)", params[i+1]/accu, (i+1)/2);
      }
      printf("\n");
    }
    if (accu != 0) {
      for (int i = 0; i < numParams; i++) {
        params[i] /= accu;
      }
    }
    const int zeroStarts = 4; // Normally 4
    const int winStarts = 2; // Normally 1
    int i = 0;
    int j = 0;
    freqData[j].r = params[i++];
    freqData[j++].i = 0;
    for (; i < numParams;) {
      freqData[j].r = params[i++];
      freqData[j++].i = params[i++];
    }
    for (; j <= smallSize/2;) {
      freqData[j].r = 0;
      freqData[j++].i = 0;
    }
    kiss_fftri(smallIFFTR, freqData, timeData);
    double scale = 1.0/timeData[0];
    double tilt = 0;
    double tilt2 = 0;
    for (int i = 2; i < numParams; i += 2) {
      if ((i/2)%2) {
        tilt2 += (i/2)*params[i]*scale;
      } else {
        tilt2 -= (i/2)*params[i]*scale;
      }
      tilt += (i/2)*params[i]*scale;
    }
    penalty += fabs(tilt);
    penalty += fabs(tilt2);
    double accu2 = 0;
    for (int i = 0; i < smallSize; i++) {
      timeData[i] *= scale;
    }
    penalty += fabs(timeData[zeroStarts*smallSize/8]);
    penalty += fabs(timeData[winStarts*smallSize/16]*timeData[smallSize-winStarts*smallSize/16]-0.5);
    for (int i = 1; i < winStarts*smallSize/16; i++) {
      // Last 16th
      timeData[bigSize-winStarts*smallSize/16+i] = timeData[smallSize-winStarts*smallSize/16+i];
      accu2 += timeData[bigSize-winStarts*smallSize/16+i]*timeData[bigSize-winStarts*smallSize/16+i];
    }
    // f(-1/8+i)*f(1/8-i) + f(i)*f(-i) = 1
    // => f(-1/8+i) = (1 - f(i)*f(-i))/f(1/8-i)   
    // => f(-1/16) = (1 - f(1/16)*f(-1/16))/f(1/16)
    //             = 1/(2 f(1/16))
    for (int i = 1; i < winStarts*smallSize/16; i++) {
      // 2nd last 16th
      timeData[bigSize-winStarts*smallSize/8+i] = (1 - timeData[i]*timeData[bigSize-i])/timeData[winStarts*smallSize/8-i];
      accu2 += timeData[bigSize-winStarts*smallSize/8+i]*timeData[bigSize-winStarts*smallSize/8+i];
    }
    // Between 2nd last and last 16th
    timeData[bigSize-winStarts*smallSize/16] = 1/(2*timeData[winStarts*smallSize/16]);
    accu2 += timeData[bigSize-winStarts*smallSize/16]*timeData[bigSize-winStarts*smallSize/16];
    for (int i = zeroStarts*smallSize/8; i <= bigSize-winStarts*smallSize/8; i++) {
      timeData[i] = 0;
    }
    for (int i = 0; i < zeroStarts*smallSize/8; i++) {
      accu2 += timeData[i]*timeData[i];
    }
    if (print > 1) {
      printf("\n");
      for (int x = 0; x < bigSize; x++) {
        printf("%d,%f\n", x, timeData[x]);
      }
    }
    scale = 1/sqrt(accu2);
    if (print) {
      printf("sqrt(accu2) = %f\n", sqrt(accu2));
    }
    double tSpread = 0;
    timeData[0] *= scale;
    double tMean = 0;
    for (int i = 1; i <= zeroStarts*smallSize/8; i++) {
      timeData[i] *= scale;
      //      tSpread += ((double)i)*((double)i)*(timeData[i]*timeData[i]);
      double x_0 = timeData[i-1]*timeData[i-1];
      double x_1 = timeData[i]*timeData[i];
      tSpread += ((double)i)*((double)i)*(x_0 + x_1)*0.5 - ((double)i)*(2.0/3*x_0 + 1.0/3*x_1) + 0.25*x_0 + 1.0/12*x_1;
      double slope = timeData[i]-timeData[i-1];
      if (slope > 0) {
        penalty += slope+1;
      }
      tMean += x_1*i;
      if (timeData[i] < 0) {
        penalty -= timeData[i];
      }
    }
    double x_0 = timeData[0]*timeData[0];
    for (int i = 1; i <= winStarts*smallSize/8; i++) {
      timeData[bigSize-i] *= scale;
      double x_1 = timeData[bigSize-i]*timeData[bigSize-i];
      tSpread += ((double)i)*((double)i)*(x_0 + x_1)*0.5 - ((double)i)*(2.0/3*x_0 + 1.0/3*x_1) + 0.25*x_0 + 1.0/12*x_1;
      x_0 = x_1;        
      tMean += x_1*(-i);
    }
    tMean /= smallSize;
    penalty += fabs(tMean);
    if (tMean > 0) {
      penalty += 1;
    }
    tSpread /= ((double)smallSize)*((double)smallSize); 
    if (print) {
      printf("tSpread = %f\n", tSpread);
    }
    kiss_fftr(bigFFTR, timeData, freqData);
    double fSpread = 0;
    x_0 = freqData[0].r*freqData[0].r;
    for (int i = 1; i <= bigSize/2; i++) {
      double x_1 = freqData[i].r*freqData[i].r+freqData[i].i*freqData[i].i;
      fSpread += ((double)i)*((double)i)*(x_0 + x_1)*0.5 - ((double)i)*(2.0/3*x_0 + 1.0/3*x_1) + 0.25*x_0 + 1.0/12*x_1;
      x_0 = x_1;
    }
    if (print > 1) {
      for (int i = 0; i <= bigSize/2; i++) {
        printf("%d,%f,%f\n", i, freqData[i].r, freqData[i].i);
      }
    }
    fSpread /= bigSize; // Includes kiss_fft scaling
    if (print) {
      printf("fSpread = %f\n", fSpread);
      printf("%f,%f,%f\n", tSpread, fSpread, tSpread*fSpread);
    }
    return tSpread*fSpread + penalty;
  }

  double costFunction(double *params, double compare) {
    return costFunction(params, compare, false);
  }

  int getNumDimensions() {
    return numParams;
  }

  ~WinProblem() {
    delete[] min;
    delete[] max;
    delete[] timeData;
    delete[] freqData;
    KISS_FFT_FREE(smallFFTR);
    KISS_FFT_FREE(smallIFFTR);
    KISS_FFT_FREE(bigFFTR);
    KISS_FFT_FREE(bigIFFTR);
  }
};

3

Pencerenin içeriğine bağlıdır. Pencereleme, geleneksel olarak geliştirildiği gibi, tahminin güç spektral yoğunluğunun Blackman-Tukey yöntemi için tasarlanmıştır. Bu, ayrık zamanlı Wiener-Khinchin teoreminden yararlanılan korelogram yöntemlerinin genel biçimidir. Hatırlayın, bu, otokorelasyon sekansını ayrık zaman Fourier dönüşümü yoluyla güç spektral yoğunluğu ile ilişkilendirir.

Bu nedenle, pencereler birkaç kriter göz önünde bulundurularak tasarlanmıştır. İlk olarak, kökeninde birlik kazancı olması gerekiyordu. Bu, rxx [0] örnek güç olarak düşünülebileceğinden, sinyalin otokorelasyon sekansındaki gücü korumaktı. Daha sonra, pencere başlangıç ​​noktasından incelmelidir. Bu birkaç nedenden ötürü. İlk olarak, geçerli bir otokorelasyon sekansı olabilmesi için diğer tüm gecikmelerin başlangıç ​​noktasından küçük veya ona eşit olması gerekir. İkincisi, bu, numunelerin çoğunu kullanarak büyük bir güvenle hesaplanmış olan düşük gecikmelerin daha yüksek ağırlıklandırılmasına ve bunlar için mevcut veri örneklerinin azalan miktarından dolayı artan varyansa sahip olan daha yüksek gecikmelerin küçük veya sıfır ağırlıklandırılmasına izin verdi. hesaplama. Bu sonuçta daha geniş bir ana lob ile sonuçlanır ve daha sonra PSD tahminde azaltılmış çözünürlük,

Son olarak, pencerelerin negatif olmayan bir spektruma sahip olması da çok arzu edilir. Bunun nedeni, Blackman-Tukey yöntemiyle, son tahminin yanlılığını pencere spektrumu ile kıvrık gerçek güç spektral yoğunluğu olarak düşünebilirsiniz. Bu pencere spektrumu negatif bölgelere sahipse, güç spektral yoğunluk tahmininizde negatif bölgelere sahip olmak mümkündür. Bu bağlamda çok az fiziksel anlamı olduğu için bu açıkça arzu edilmemektedir. Ayrıca, Blackman-Tukey yönteminde büyüklükte kare operasyonu olmadığını da not edeceksiniz. Bunun nedeni, gerçek ve eşit bir pencere ile çarpılan gerçek ve eşit bir otokorelasyon sekansı ile, ayrık Fourier dönüşümünün de gerçek ve eşit olacağıdır. Pratikte, genellikle ölçülen çok küçük negatif bileşenler bulacaksınız.

Bu nedenlerle, tüm geçerli otokorelasyon sekansları da olduğu için pencereler de tek uzunluktadır. Şimdi hala yapılabilecek (ve yapılabilecek) periodogram yöntemleri bağlamında pencereleme. Yani, verileri pencereleyin ve ardından pencerelenmiş verilerin karesini alın. Bu Blackman-Tukey yöntemine eşdeğer değildir. Bazı istatistiksel türevlerle, ortalama olarak benzer davrandıklarını , ancak genel olarak değil olduklarını görebilirsiniz . Örneğin, tahminlerin varyansını azaltmak için Welch veya Bartlett'in yöntemindeki her segment için pencereleme kullanmak oldukça yaygındır. Yani özünde, bu yöntemlerle, motivasyon kısmen aynıdır, ancak farklıdır. Bu yöntemlerde güç, örneğin pencere gecikmelerinin dikkatlice tartılması yerine pencere enerjisini bölerek normalleştirilir.

Umarım bu, pencereleri ve kökenlerini ve neden simetrik olduklarını bağlamsallaştırır. Birinin neden asimetrik bir pencere seçebileceğini merak ediyorsanız, Fourier dönüşümünün dualite özelliğinin etkilerini ve güç spektral yoğunluk tahmininizin uygulamanız için ne anlama geldiğini düşünün. Şerefe.


1

Pencerenin orijinal noktası, (DFT tarafından periyodik olduğu varsayılır) sinyalinin başlangıçta uca göre keskin geçişleri olmadığından emin olmaktır. Maliyet, (simetrik) pencerenin merkezine doğru frekansların daha sonraki ağırlıkta ve daha sonraki DFT'de temsil edilmesidir.

Tüm bunlar arka planda iken, DFT aracılığıyla analiz edilen sinyaldeki yerel zamansal özellikleri vurgulamak için asimetrik bir pencere kullanmak istediğini hayal edebiliyorum . Ancak, sinyalinizin uç noktaları pencereden sonra kabaca aynı genlikte değilse, bu DFT sırasında daha geniş bir lob genişliğine mal olabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.