I have been struggling to figure out some strange results from FFTW. I get a angled banding in the DFT and the inverse gives an image that looks generally OK except that the signal varies periodically, consistent with those bands, by up to 1% above and below the original image signal. I have put some picture and description here: http://www.mirametrics.com/pub/fftw_strange_results.htm I have been yanking out my hair over this. Anyone have any ideas what is wrong? THANKS! Micahel
Weird results from FFTW -- banding and large roundoff
Started by ●February 19, 2007
Reply by ●February 19, 20072007-02-19
Michael48 wrote:> I have been struggling to figure out some strange results from FFTW. I get > a angled banding in the DFT and the inverse gives an image that looks > generally OK except that the signal varies periodically, consistent with > those bands, by up to 1% above and below the original image signal. > > I have put some picture and description here: > http://www.mirametrics.com/pub/fftw_strange_results.htmLooks as if you got your memory management/addressing wrong. My first idea is that you gave FFTW the dimensions in the wrong order. FFTW wants the dimension with consecutive memory as the last dimension. So if your image is 1042x1032 and the 1042 pixels in a line are in consecutive memory locations, you've got to plan a 1032x1042 FFT. Maybe you could show some source? Hendrik vdH
Reply by ●February 19, 20072007-02-19
"Hendrik van der Heijden" <hvdh@gmx.de> wrote in message news:45da252d$0$6392$9b4e6d93@newsspool2.arcor-online.net...> Michael48 wrote: >> I have been struggling to figure out some strange results from FFTW. I >> get >> a angled banding in the DFT and the inverse gives an image that looks >> generally OK except that the signal varies periodically, consistent with >> those bands, by up to 1% above and below the original image signal. >> >> I have put some picture and description here: >> http://www.mirametrics.com/pub/fftw_strange_results.htm > > Looks as if you got your memory management/addressing wrong. > My first idea is that you gave FFTW the dimensions in the wrong > order. FFTW wants the dimension with consecutive memory as > the last dimension. So if your image is 1042x1032 and the > 1042 pixels in a line are in consecutive memory locations, > you've got to plan a 1032x1042 FFT. > > Maybe you could show some source? > > > Hendrik vdH >It might also help to see the original image. Starting from the DFTs is always questionable. Fred
Reply by ●February 24, 20072007-02-24
That fixed the major problem but there is one remaining wrinkle to work out. Thank you!!! There's clearly omething I am missing. The docs say, for every example, that the arguments are passed as nx, ny, nz. So, I guess that nx does not mean "number of columns" and ny does not mean "number of rows" ? I am confused: Should pass the args in the order nx, ny, nz but transpose the data buffer before r2c and after c2r? Or should I reverse the order of parameter passing and leave the data array intact? The 2D image is stored as a single buffer with the column number (nx) varying most rapidly. And I am calling the C libraries from C code. Something is wrong here!! For the in-place case, I get great precision: (forward >> inverse DFT) - orignal < ~10^-18. Here's the remaining wrinkle: If I use an auxiliary buffer rather than in-place, then there's problem in how the data are packed and unpacked, from the point of view of the column count. Maybe this is a transpose/arg ordering issue like I mentioned above. I need to investigate this some more. Thank you again, for getting me over this first hurdle. Michael>Michael48 wrote: >> I have been struggling to figure out some strange results from FFTW. Iget>> a angled banding in the DFT and the inverse gives an image that looks >> generally OK except that the signal varies periodically, consistentwith>> those bands, by up to 1% above and below the original image signal. >> >> I have put some picture and description here: >> http://www.mirametrics.com/pub/fftw_strange_results.htm > >Looks as if you got your memory management/addressing wrong. >My first idea is that you gave FFTW the dimensions in the wrong >order. FFTW wants the dimension with consecutive memory as >the last dimension. So if your image is 1042x1032 and the >1042 pixels in a line are in consecutive memory locations, >you've got to plan a 1032x1042 FFT. > >Maybe you could show some source? > > >Hendrik vdH > >
Reply by ●February 24, 20072007-02-24
Michael48 wrote:> There's clearly omething I am missing. The docs say, for every example, > that the arguments are passed as nx, ny, nz. So, I guess that nx does not > mean "number of columns" and ny does not mean "number of rows" ? I am > confused: Should pass the args in the order nx, ny, nz but transpose the > data buffer before r2c and after c2r? Or should I reverse the order of > parameter passing and leave the data array intact?Transposing a 1MP image takes some time. Passing the args in a different order doesn't cost anything.> For the in-place case, I get great precision:> Here's the remaining wrinkle: If I use an auxiliary buffer rather than > in-place, then there's problem in how the data are packed and unpacked, > from the point of view of the column count.If you do a R2C FFT out-of-place, the memory strides (# of bytes between two line starts) of input and output image are different, see http://fftw.org/fftw3_doc/Multi_002dDimensional-DFTs-of-Real-Data.html Another thing is that in out-of-place transforms, the input array data will generally not be preserved unless you don't specify the FFTW_PRESERVE_INPUT planner flag. Maybe you just compared to you overwritten input array. Hendrik vdH
Reply by ●February 24, 20072007-02-24
Michael48 wrote: > There's clearly omething I am missing. The docs say, for every example, > that the arguments are passed as nx, ny, nz. So, I guess that nx does not > mean "number of columns" and ny does not mean "number of rows" ? I am > confused: Should pass the args in the order nx, ny, nz but transpose the > data buffer before r2c and after c2r? Or should I reverse the order of > parameter passing and leave the data array intact? Transposing a 1MP image takes some time. Passing the args in a different order doesn't cost anything. > For the in-place case, I get great precision: > Here's the remaining wrinkle: If I use an auxiliary buffer rather than > in-place, then there's problem in how the data are packed and unpacked, > from the point of view of the column count. If you do a R2C FFT out-of-place, the memory strides (# of bytes between two line starts) of input and output image are different, see http://fftw.org/fftw3_doc/Multi_002dDimensional-DFTs-of-Real-Data.html Hendrik vdH
Reply by ●February 26, 20072007-02-26
Hendrik, Thanks for your help. Now I get the forward/inverse pair for the 1042x1032 array in about 0.6 seconds and the result is clean to about 1 part in 10^14 or better. It is a significant improvement over my old FFT code. I do appreciate the difference between the order of parameter passing and whether or not to transpose twice. I know you can't speak for the FFTW authors, but why on earth would the documentation specify "nx,ny, nz" *everywhere*, when it really should always be "nz, ny, nx" ?? That is just so arcane! Which is why it cost me most of 2 days of time and frustration before I realized there was something I was simply not getting about using this library. I am grateful to you for pointing me the right way! Michael>Michael48 wrote: > > There's clearly omething I am missing. The docs say, for everyexample,> > that the arguments are passed as nx, ny, nz. So, I guess that nx doesnot> > mean "number of columns" and ny does not mean "number of rows" ? I am > > confused: Should pass the args in the order nx, ny, nz but transposethe> > data buffer before r2c and after c2r? Or should I reverse the orderof> > parameter passing and leave the data array intact? > >Transposing a 1MP image takes some time. >Passing the args in a different order doesn't cost anything. > > > For the in-place case, I get great precision: > > > Here's the remaining wrinkle: If I use an auxiliary buffer ratherthan> > in-place, then there's problem in how the data are packed andunpacked,> > from the point of view of the column count. > >If you do a R2C FFT out-of-place, the memory strides (# of bytes >between two line starts) of input and output image are different, >see > >http://fftw.org/fftw3_doc/Multi_002dDimensional-DFTs-of-Real-Data.html > > >Hendrik vdH >
Reply by ●February 26, 20072007-02-26
On Feb 26, 10:10 am, "Michael48" <m...@mirametrics.com> wrote:> I do appreciate the difference between the order of parameter passing and > whether or not to transpose twice. I know you can't speak for the FFTW > authors, but why on earth would the documentation specify "nx,ny, nz" > *everywhere*, when it really should always be "nz, ny, nx" ?? That is just > so arcane! Which is why it cost me most of 2 days of time and frustration > before I realized there was something I was simply not getting about using > this library. I am grateful to you for pointing me the right way!I am one of the FFTW authors, and I can point out that FFTW's dimension ordering conforms to the standard for C programs and for most other modern programming languages other than Fortran. In a C program, if you have an array[nx][ny], it is stored with the ny dimension contiguous, and this is specified as an "nx, ny" array in FFTW. This is called "row-major order" for an nx by ny array. The other convention is "column-major" order, in which an nx by ny array is stored with the nx dimension contiguous. This is used in Fortran for an array(nx,ny), and in various other programs derived from Fortran (such as Matlab). A column-major array can be specified in FFTW merely by passing the dimensions in reverse order. We can't help it that there are two common conventions for laying out multidimensional arrays in memory; we have to pick one ordering, and it is a C library so we pick the C convention. I will note, however, that there is an *entire section* of the FFTW manual discussing multidimensional array formats in great detail. I'm not sure what more you can expect. Regards, Steven G. Johnson
Reply by ●February 26, 20072007-02-26
Steve, I really do appreciate your work of FFTW, and I understand how array ordering works in Fortran vs C. But that wasn't my point. My point was that your doc explicltly states the parameter passing order as "foo( nx, ny, nz, ..." So my mistake was to associate (nx) with the number of columns and (ny) with number of rows. If you are looking at a 2-D image on a screen, then don't you think that is somewhat hueristic? If I have a C program, with its multi-D arrays in a native row-major order, and my code calls your C-library and the docs show the parameter order as nx, ny, nz, then can you see that there's room for confusion at the implementation end? Michael>On Feb 26, 10:10 am, "Michael48" <m...@mirametrics.com> wrote: >> I do appreciate the difference between the order of parameter passingand>> whether or not to transpose twice. I know you can't speak for the FFTW >> authors, but why on earth would the documentation specify "nx,ny, nz" >> *everywhere*, when it really should always be "nz, ny, nx" ?? That isjust>> so arcane! Which is why it cost me most of 2 days of time andfrustration>> before I realized there was something I was simply not getting aboutusing>> this library. I am grateful to you for pointing me the right way! > >I am one of the FFTW authors, and I can point out that FFTW's >dimension ordering conforms to the standard for C programs and for >most other modern programming languages other than Fortran. > >In a C program, if you have an array[nx][ny], it is stored with the ny >dimension contiguous, and this is specified as an "nx, ny" array in >FFTW. This is called "row-major order" for an nx by ny array. > >The other convention is "column-major" order, in which an nx by ny >array is stored with the nx dimension contiguous. This is used in >Fortran for an array(nx,ny), and in various other programs derived >from Fortran (such as Matlab). A column-major array can be specified >in FFTW merely by passing the dimensions in reverse order. > >We can't help it that there are two common conventions for laying out >multidimensional arrays in memory; we have to pick one ordering, and >it is a C library so we pick the C convention. I will note, however, >that there is an *entire section* of the FFTW manual discussing >multidimensional array formats in great detail. I'm not sure what >more you can expect. > >Regards, >Steven G. Johnson > >
Reply by ●February 26, 20072007-02-26
On Feb 26, 12:37 pm, "Michael48" <m...@mirametrics.com> wrote:> I really do appreciate your work of FFTW, and I understand how array > ordering works in Fortran vs C. But that wasn't my point. My point was > that your doc explicltly states the parameter passing order as "foo( nx, > ny, nz, ..." So my mistake was to associate (nx) with the number of > columns and (ny) with number of rows. If you are looking at a 2-D image on > a screen, then don't you think that is somewhat hueristic? If I have a C > program, with its multi-D arrays in a native row-major order, and my code > calls your C-library and the docs show the parameter order as nx, ny, nz, > then can you see that there's room for confusion at the implementation > end?There is room for confusion whether we list them as (nx,ny,nz) or (nz,ny,nx): that's why you have to read the manual instead of guessing. In English, it is conventional to name the dimensions "x", "y", "z" listed from left to right. It is also conventional in discussing row- major order to read the dimensions from left to right, with the right- most being the contiguous dimension. Conversely, it's not reasonable to expect FFTW's data formats to be determined by how you happen to display your 2d data on a screen. The fact is, when you use any library that processes multidimensional data, you have to find out how the data must be stored---it is foolish to guess. And we say *over and over* in the manual that the data is in row-major order. In the tutorial. In the reference section. In the section on multi-dimensional array formats. As far as I can tell, in every place the dimensions are discussed. I'm not sure what you expect us to do. If we label the dimensions (nz,ny,nx), then at *least* as many people will be confused in the opposite direction. And for people who just read the function prototype and don't read the accompanying explanations in the manual, nothing we write will make any difference... Regards, Steven G. Johnson






