Mercurial > hg > sv-dependency-builds
view src/fftw-3.3.8/doc/html/Reversing-array-dimensions.html @ 167:bd3cc4d1df30
Add FFTW 3.3.8 source, and a Linux build
author | Chris Cannam <cannam@all-day-breakfast.com> |
---|---|
date | Tue, 19 Nov 2019 14:52:55 +0000 |
parents | |
children |
line wrap: on
line source
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <!-- This manual is for FFTW (version 3.3.8, 24 May 2018). Copyright (C) 2003 Matteo Frigo. Copyright (C) 2003 Massachusetts Institute of Technology. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation. --> <!-- Created by GNU Texinfo 6.3, http://www.gnu.org/software/texinfo/ --> <head> <title>FFTW 3.3.8: Reversing array dimensions</title> <meta name="description" content="FFTW 3.3.8: Reversing array dimensions"> <meta name="keywords" content="FFTW 3.3.8: Reversing array dimensions"> <meta name="resource-type" content="document"> <meta name="distribution" content="global"> <meta name="Generator" content="makeinfo"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <link href="index.html#Top" rel="start" title="Top"> <link href="Concept-Index.html#Concept-Index" rel="index" title="Concept Index"> <link href="index.html#SEC_Contents" rel="contents" title="Table of Contents"> <link href="Calling-FFTW-from-Modern-Fortran.html#Calling-FFTW-from-Modern-Fortran" rel="up" title="Calling FFTW from Modern Fortran"> <link href="FFTW-Fortran-type-reference.html#FFTW-Fortran-type-reference" rel="next" title="FFTW Fortran type reference"> <link href="Extended-and-quadruple-precision-in-Fortran.html#Extended-and-quadruple-precision-in-Fortran" rel="prev" title="Extended and quadruple precision in Fortran"> <style type="text/css"> <!-- a.summary-letter {text-decoration: none} blockquote.indentedblock {margin-right: 0em} blockquote.smallindentedblock {margin-right: 0em; font-size: smaller} blockquote.smallquotation {font-size: smaller} div.display {margin-left: 3.2em} div.example {margin-left: 3.2em} div.lisp {margin-left: 3.2em} div.smalldisplay {margin-left: 3.2em} div.smallexample {margin-left: 3.2em} div.smalllisp {margin-left: 3.2em} kbd {font-style: oblique} pre.display {font-family: inherit} pre.format {font-family: inherit} pre.menu-comment {font-family: serif} pre.menu-preformatted {font-family: serif} pre.smalldisplay {font-family: inherit; font-size: smaller} pre.smallexample {font-size: smaller} pre.smallformat {font-family: inherit; font-size: smaller} pre.smalllisp {font-size: smaller} span.nolinebreak {white-space: nowrap} span.roman {font-family: initial; font-weight: normal} span.sansserif {font-family: sans-serif; font-weight: normal} ul.no-bullet {list-style: none} --> </style> </head> <body lang="en"> <a name="Reversing-array-dimensions"></a> <div class="header"> <p> Next: <a href="FFTW-Fortran-type-reference.html#FFTW-Fortran-type-reference" accesskey="n" rel="next">FFTW Fortran type reference</a>, Previous: <a href="Overview-of-Fortran-interface.html#Overview-of-Fortran-interface" accesskey="p" rel="prev">Overview of Fortran interface</a>, Up: <a href="Calling-FFTW-from-Modern-Fortran.html#Calling-FFTW-from-Modern-Fortran" accesskey="u" rel="up">Calling FFTW from Modern Fortran</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html#Concept-Index" title="Index" rel="index">Index</a>]</p> </div> <hr> <a name="Reversing-array-dimensions-1"></a> <h3 class="section">7.2 Reversing array dimensions</h3> <a name="index-row_002dmajor-6"></a> <a name="index-column_002dmajor-1"></a> <p>A minor annoyance in calling FFTW from Fortran is that FFTW’s array dimensions are defined in the C convention (row-major order), while Fortran’s array dimensions are the opposite convention (column-major order). See <a href="Multi_002ddimensional-Array-Format.html#Multi_002ddimensional-Array-Format">Multi-dimensional Array Format</a>. This is just a bookkeeping difference, with no effect on performance. The only consequence of this is that, whenever you create an FFTW plan for a multi-dimensional transform, you must always <em>reverse the ordering of the dimensions</em>. </p> <p>For example, consider the three-dimensional (L × M × N ) arrays: </p> <div class="example"> <pre class="example"> complex(C_DOUBLE_COMPLEX), dimension(L,M,N) :: in, out </pre></div> <p>To plan a DFT for these arrays using <code>fftw_plan_dft_3d</code>, you could do: </p> <a name="index-fftw_005fplan_005fdft_005f3d-2"></a> <div class="example"> <pre class="example"> plan = fftw_plan_dft_3d(N,M,L, in,out, FFTW_FORWARD,FFTW_ESTIMATE) </pre></div> <p>That is, from FFTW’s perspective this is a N × M × L array. <em>No data transposition need occur</em>, as this is <em>only notation</em>. Similarly, to use the more generic routine <code>fftw_plan_dft</code> with the same arrays, you could do: </p> <div class="example"> <pre class="example"> integer(C_INT), dimension(3) :: n = [N,M,L] plan = fftw_plan_dft_3d(3, n, in,out, FFTW_FORWARD,FFTW_ESTIMATE) </pre></div> <p>Note, by the way, that this is different from the legacy Fortran interface (see <a href="Fortran_002dinterface-routines.html#Fortran_002dinterface-routines">Fortran-interface routines</a>), which automatically reverses the order of the array dimension for you. Here, you are calling the C interface directly, so there is no “translation” layer. </p> <a name="index-r2c_002fc2r-multi_002ddimensional-array-format-2"></a> <p>An important thing to keep in mind is the implication of this for multidimensional real-to-complex transforms (see <a href="Multi_002dDimensional-DFTs-of-Real-Data.html#Multi_002dDimensional-DFTs-of-Real-Data">Multi-Dimensional DFTs of Real Data</a>). In C, a multidimensional real-to-complex DFT chops the last dimension roughly in half (N × M × L real input goes to N × M × L/2+1 complex output). In Fortran, because the array dimension notation is reversed, the <em>first</em> dimension of the complex data is chopped roughly in half. For example consider the ‘<samp>r2c</samp>’ transform of L × M × N real input in Fortran: </p> <a name="index-fftw_005fplan_005fdft_005fr2c_005f3d-2"></a> <a name="index-fftw_005fexecute_005fdft_005fr2c-1"></a> <div class="example"> <pre class="example"> type(C_PTR) :: plan real(C_DOUBLE), dimension(L,M,N) :: in complex(C_DOUBLE_COMPLEX), dimension(L/2+1,M,N) :: out plan = fftw_plan_dft_r2c_3d(N,M,L, in,out, FFTW_ESTIMATE) ... call fftw_execute_dft_r2c(plan, in, out) </pre></div> <a name="index-in_002dplace-9"></a> <a name="index-padding-5"></a> <p>Alternatively, for an in-place r2c transform, as described in the C documentation we must <em>pad</em> the <em>first</em> dimension of the real input with an extra two entries (which are ignored by FFTW) so as to leave enough space for the complex output. The input is <em>allocated</em> as a 2[L/2+1] × M × N array, even though only L × M × N of it is actually used. In this example, we will allocate the array as a pointer type, using ‘<samp>fftw_alloc</samp>’ to ensure aligned memory for maximum performance (see <a href="Allocating-aligned-memory-in-Fortran.html#Allocating-aligned-memory-in-Fortran">Allocating aligned memory in Fortran</a>); this also makes it easy to reference the same memory as both a real array and a complex array. </p> <a name="index-fftw_005falloc_005fcomplex-4"></a> <a name="index-c_005ff_005fpointer"></a> <div class="example"> <pre class="example"> real(C_DOUBLE), pointer :: in(:,:,:) complex(C_DOUBLE_COMPLEX), pointer :: out(:,:,:) type(C_PTR) :: plan, data data = fftw_alloc_complex(int((L/2+1) * M * N, C_SIZE_T)) call c_f_pointer(data, in, [2*(L/2+1),M,N]) call c_f_pointer(data, out, [L/2+1,M,N]) plan = fftw_plan_dft_r2c_3d(N,M,L, in,out, FFTW_ESTIMATE) ... call fftw_execute_dft_r2c(plan, in, out) ... call fftw_destroy_plan(plan) call fftw_free(data) </pre></div> <hr> <div class="header"> <p> Next: <a href="FFTW-Fortran-type-reference.html#FFTW-Fortran-type-reference" accesskey="n" rel="next">FFTW Fortran type reference</a>, Previous: <a href="Overview-of-Fortran-interface.html#Overview-of-Fortran-interface" accesskey="p" rel="prev">Overview of Fortran interface</a>, Up: <a href="Calling-FFTW-from-Modern-Fortran.html#Calling-FFTW-from-Modern-Fortran" accesskey="u" rel="up">Calling FFTW from Modern Fortran</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html#Concept-Index" title="Index" rel="index">Index</a>]</p> </div> </body> </html>