[Kst] [Bug 87447] pass filters are very inefficient for some filter
lengths
Andrew Walker
arwalker at sumusltd.com
Thu Aug 19 00:28:20 CEST 2004
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.
http://bugs.kde.org/show_bug.cgi?id=87447
arwalker sumusltd com changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|NEW |RESOLVED
Resolution| |FIXED
------- Additional Comments From arwalker sumusltd com 2004-08-19 00:28 -------
CVS commit by arwalker:
Round up to nearest power of 2 for a faster mixed-radix FFT.
CCMAIL: 87447-done bugs kde org
M +54 -37 filters.h 1.3
--- kdeextragear-2/kst/plugins/pass_filters/filters.h #1.2:1.3
@ -38,6 +38,8 @ int kst_pass_filter(
gsl_fft_halfcomplex_wavetable* hc;
double* pResult[1];
+ double* pPadded;
double dFreqValue;
int iLengthData;
+ int iLengthDataPadded;
int iReturn = -1;
int iStatus;
@ -48,4 +50,10 @ int kst_pass_filter(
if( iLengthData > 0 ) {
+ //
+ // round up to the nearest power of 2...
+ //
+ iLengthDataPadded = (int)pow( 2.0, ceil( log10( (double)iLengthData ) / log10( 2.0 ) ) );
+ pPadded = (double*)malloc( iLengthDataPadded * sizeof( double ) );
+ if( pPadded != 0L ) {
if( outArrayLens[0] != iLengthData ) {
pResult[0] = (double*)realloc( outArrays[0], iLengthData * sizeof( double ) );
@ -58,14 +66,21 @ int kst_pass_filter(
outArrayLens[0] = iLengthData;
- real = gsl_fft_real_wavetable_alloc( iLengthData );
+ real = gsl_fft_real_wavetable_alloc( iLengthDataPadded );
if( real != NULL ) {
- work = gsl_fft_real_workspace_alloc( iLengthData );
+ work = gsl_fft_real_workspace_alloc( iLengthDataPadded );
if( work != NULL ) {
- memcpy( pResult[0], inArrays[0], iLengthData * sizeof( double ) );
+ memcpy( pPadded, inArrays[0], iLengthData * sizeof( double ) );
+
+ //
+ // linear extrapolation on the padded values...
+ //
+ for( i=iLengthData; i<iLengthDataPadded; i++ ) {
+ pPadded[i] = inArrays[0][iLengthData-1] - (double)( i - iLengthData + 1 ) * ( inArrays[0][iLengthData-1] - inArrays[0][0] ) / (double)( iLengthDataPadded - iLengthData );
+ }
//
// calculate the FFT...
//
- iStatus = gsl_fft_real_transform( pResult[0], 1, iLengthData, real, work );
+ iStatus = gsl_fft_real_transform( pPadded, 1, iLengthDataPadded, real, work );
if( !iStatus ) {
@ -73,16 +88,17 @ int kst_pass_filter(
// apply the filter...
//
- for( i=0; i<iLengthData; i++ ) {
- dFreqValue = 0.5 * (double)i / (double)iLengthData;
- pResult[0][i] *= filter_calculate( dFreqValue, inScalars );
+ for( i=0; i<iLengthDataPadded; i++ ) {
+ dFreqValue = 0.5 * (double)i / (double)iLengthDataPadded;
+ pPadded[i] *= filter_calculate( dFreqValue, inScalars );
}
- hc = gsl_fft_halfcomplex_wavetable_alloc( iLengthData );
+ hc = gsl_fft_halfcomplex_wavetable_alloc( iLengthDataPadded );
if( hc != NULL ) {
//
// calculate the inverse FFT...
//
- iStatus = gsl_fft_halfcomplex_inverse( pResult[0], 1, iLengthData, hc, work );
+ iStatus = gsl_fft_halfcomplex_inverse( pPadded, 1, iLengthDataPadded, hc, work );
if( !iStatus ) {
+ memcpy( outArrays[0], pPadded, iLengthData * sizeof( double ) );
iReturn = 0;
}
@ -95,5 +111,6 @ int kst_pass_filter(
gsl_fft_real_wavetable_free( real );
}
- iReturn = 0;
+ }
+ free( pPadded );
}
}
More information about the Kst
mailing list