PlotLine * LOWPASS::getLowpass (PlotLine *in, double fre, double wid) { PlotLine *out = new PlotLine; if (in->getSize() == 0) return out; // ---------------------------------------------------------------------- double slope = 0; // will be modified on call to detrend double intercept = 0; int length = 0; // original caller size int n = 0; // size raised to next power of 2 for fft int i = 0; length = in->getSize(); // Detrend input series PlotLine *series = detrend(in, slope, intercept, true); // Raise length to next power of 2, pad with zero PlotLine *series2 = raise2Power(series, 0); n = series2->getSize(); //qtsFFT fft(n); // construct fft object fft = new qtsFFT(n); // do fft PlotLine * fftFreq = fft->do_FFTqts(series2); //PlotLine * fftFreq = fft.do_FFTqts(series2); // apply low pass filter double f = 0; double dist = 0; double wt = 0; int halfn = n/2; double freqSave = fftFreq->getData(halfn); for (i = 0 ; i < halfn ; i++) { f = (double) i / (double) n ; // Frequency if (f <= fre) // Flat response wt = 1.0 ; else { dist = (f - fre) / wid; wt = exp ( -dist * dist ) ; } fftFreq->setData(i, fftFreq->getData(i) * wt) ; fftFreq->setData(halfn + i, fftFreq->getData(halfn + i) * wt) ; } dist = (0.5 - fre) / wid; // Do Nyquist in fftFreq[0] fftFreq->setData(halfn, freqSave * exp ( -dist * dist )) ; // Do inverse FFT to recover real domain PlotLine *fftReal = fft->do_iFFTqts(fftFreq); //PlotLine *fftReal = fft.do_iFFTqts(fftFreq); // Retrend input series, n.b. original length PlotLine *series3 = detrend(fftReal, slope, intercept, false); for (i = 0; i < length; i++) out->append(series3->getData(i)); delete series; delete series2; delete series3; delete fftReal; delete fftFreq; delete fft; return out; }