Recent

Author Topic: FFTW 3.3.5 preserve input  (Read 4726 times)

antekg

  • Newbie
  • Posts: 6
FFTW 3.3.5 preserve input
« on: May 22, 2017, 11:23:03 am »
I use libfftw3f.dll extracted from fftw-3.3.5-dll64.zip ported to fpc by unit fftw_s.
I struggled with complex to real transformation.
As it was written in documentation http://www.fftw.org/fftw3.pdf (for version 3.3.6-pl1, 15 January 2017):
... the c2r transform destroys its input array (...) This can be prevented, if necessary, by including
FFTW_PRESERVE_INPUT in the flags
...
In my tests the input is not preserved even the flag is set.
Is it a matter of older version of dll than documentation?
Has anybody tried to port the new version (if any) modifying fftw_s?

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: FFTW 3.3.5 preserve input
« Reply #1 on: May 22, 2017, 11:37:00 am »
It is probably an older (very old!) dll, but I will check it against my audio libs.
If the flag is declared in the interface unit it should be accepted by the dll.

[EDIT]
Yes it is an old dll.
The flag is present in fftw_s.pas and it preserves at least my input.

So this is not an FPC or Lazarus issue. Upgrade your FFTW distribution.
« Last Edit: May 22, 2017, 11:42:13 am by Thaddy »
Specialize a type, not a var.

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: FFTW 3.3.5 preserve input
« Reply #2 on: May 22, 2017, 11:46:18 am »
Aside:
FFTW has always had options to preserve original data, but it involved a full copy operation,slowing it down.
The flag implies a full copy operation..... You will loose speed. If it is for display, it is OK, but in that case it is more efficient to use one of the scaling options first.
If it is to perform e.g. FIR filters, it is not so OK, but then why would you want to preserve the data?. But it will still work on a reasonably fast platform. (Even on a RaspBerry Pi 3)
« Last Edit: May 22, 2017, 11:50:25 am by Thaddy »
Specialize a type, not a var.

antekg

  • Newbie
  • Posts: 6
Re: FFTW 3.3.5 preserve input
« Reply #3 on: May 23, 2017, 02:38:48 pm »
Thank you Thaddy,
If you be so kind, please look at my testing program.
Code: Pascal  [Select][+][-]
  1. uses types, Math, fftw_s;
  2. const
  3.   L = 256;
  4. var
  5.   i: Word;
  6.   Signal: TSingleDynArray;
  7.   Fourier, Fourier_preserved: array of complex_single;
  8.   p: fftw_plan_single;
  9.  
  10. procedure Report(const Head: string);
  11. var
  12.   i: Word;
  13.   MaxError: Single;
  14. begin
  15.   MaxError := 0;
  16.   for i := 0 to High(Fourier) do
  17.   begin
  18.     MaxError := Max(MaxError, Abs(Fourier[i].Re - Fourier_preserved[i].Re));
  19.     MaxError := Max(MaxError, Abs(Fourier[i].Im - Fourier_preserved[i].Im));
  20.   end;
  21.   WriteLn('Error ' + Head, #9, MaxError:0:4);
  22. end;
  23.  
  24. begin
  25.   SetLength(Signal, L);
  26.   SetLength(Fourier, L div 2 + 1);
  27.   for i := 0 to High(Signal) do Signal[i] := i;
  28.  
  29.   // Real to complex - just to fill the complex array in
  30.   p := fftw_plan_dft_1d(L, PSingle(@Signal[0]), @Fourier[0], [fftw_estimate]);
  31.   fftw_execute(p);
  32.   fftw_destroy_plan(p);
  33.  
  34.   Fourier_preserved := Copy(Fourier, 0, Length(Fourier));
  35.   Report('before inverse transform' );
  36.  
  37.   // complex to Real - reverse just to test whether Fourier is preserved;
  38.   p := fftw_plan_dft_1d(L, Pcomplex_single(@Fourier[0]), @Signal[0], [fftw_estimate, fftw_preserve_input]);
  39.   fftw_execute(p);
  40.   fftw_destroy_plan(p);
  41.   Report('after inverse transform' );
  42. end.
  43.  
I got such results:

Error before inverse transform    0.0000
Error after inverse transform   32768.0000

The first number is obviously zero because it compares immediate copy. The second number is the evident error and may be random.
I run the test under Windows 10, 64 bits.
I don't know the newer ffftw*.dll for this platform. Version 3.3.6 is not yes compiled (as far as I know).

Obviously, I can manage my problem as it has been shown on my testing program.
I wanted just share the problem, that we can not trust the documentation.
On the other hand, it would be elegant to have a library which does not enforce such patches.
« Last Edit: May 23, 2017, 02:49:43 pm by antekg »

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: FFTW 3.3.5 preserve input
« Reply #4 on: May 23, 2017, 03:11:33 pm »
Inverse FFT needs scaling? Hence that particular error....which is a power of 2.
Specialize a type, not a var.

antekg

  • Newbie
  • Posts: 6
Re: FFTW 3.3.5 preserve input
« Reply #5 on: May 23, 2017, 05:07:07 pm »
Thaddy,

Probably you are writing about testing forth and inverse transform.
My test does something else.
It gives complex array Fourier as an input (line 38 of my code) for calculation of inverse FFT. The array should not be changed. It is not matter of scaling. Some artifacts appear in the array which is expected to be preserved.

 

TinyPortal © 2005-2018