annotate src/fftw-3.3.3/doc/html/Reversing-array-dimensions.html @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents 37bf6b4a2645
children
rev   line source
Chris@10 1 <html lang="en">
Chris@10 2 <head>
Chris@10 3 <title>Reversing array dimensions - FFTW 3.3.3</title>
Chris@10 4 <meta http-equiv="Content-Type" content="text/html">
Chris@10 5 <meta name="description" content="FFTW 3.3.3">
Chris@10 6 <meta name="generator" content="makeinfo 4.13">
Chris@10 7 <link title="Top" rel="start" href="index.html#Top">
Chris@10 8 <link rel="up" href="Calling-FFTW-from-Modern-Fortran.html#Calling-FFTW-from-Modern-Fortran" title="Calling FFTW from Modern Fortran">
Chris@10 9 <link rel="prev" href="Overview-of-Fortran-interface.html#Overview-of-Fortran-interface" title="Overview of Fortran interface">
Chris@10 10 <link rel="next" href="FFTW-Fortran-type-reference.html#FFTW-Fortran-type-reference" title="FFTW Fortran type reference">
Chris@10 11 <link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
Chris@10 12 <!--
Chris@10 13 This manual is for FFTW
Chris@10 14 (version 3.3.3, 25 November 2012).
Chris@10 15
Chris@10 16 Copyright (C) 2003 Matteo Frigo.
Chris@10 17
Chris@10 18 Copyright (C) 2003 Massachusetts Institute of Technology.
Chris@10 19
Chris@10 20 Permission is granted to make and distribute verbatim copies of
Chris@10 21 this manual provided the copyright notice and this permission
Chris@10 22 notice are preserved on all copies.
Chris@10 23
Chris@10 24 Permission is granted to copy and distribute modified versions of
Chris@10 25 this manual under the conditions for verbatim copying, provided
Chris@10 26 that the entire resulting derived work is distributed under the
Chris@10 27 terms of a permission notice identical to this one.
Chris@10 28
Chris@10 29 Permission is granted to copy and distribute translations of this
Chris@10 30 manual into another language, under the above conditions for
Chris@10 31 modified versions, except that this permission notice may be
Chris@10 32 stated in a translation approved by the Free Software Foundation.
Chris@10 33 -->
Chris@10 34 <meta http-equiv="Content-Style-Type" content="text/css">
Chris@10 35 <style type="text/css"><!--
Chris@10 36 pre.display { font-family:inherit }
Chris@10 37 pre.format { font-family:inherit }
Chris@10 38 pre.smalldisplay { font-family:inherit; font-size:smaller }
Chris@10 39 pre.smallformat { font-family:inherit; font-size:smaller }
Chris@10 40 pre.smallexample { font-size:smaller }
Chris@10 41 pre.smalllisp { font-size:smaller }
Chris@10 42 span.sc { font-variant:small-caps }
Chris@10 43 span.roman { font-family:serif; font-weight:normal; }
Chris@10 44 span.sansserif { font-family:sans-serif; font-weight:normal; }
Chris@10 45 --></style>
Chris@10 46 </head>
Chris@10 47 <body>
Chris@10 48 <div class="node">
Chris@10 49 <a name="Reversing-array-dimensions"></a>
Chris@10 50 <p>
Chris@10 51 Next:&nbsp;<a rel="next" accesskey="n" href="FFTW-Fortran-type-reference.html#FFTW-Fortran-type-reference">FFTW Fortran type reference</a>,
Chris@10 52 Previous:&nbsp;<a rel="previous" accesskey="p" href="Overview-of-Fortran-interface.html#Overview-of-Fortran-interface">Overview of Fortran interface</a>,
Chris@10 53 Up:&nbsp;<a rel="up" accesskey="u" href="Calling-FFTW-from-Modern-Fortran.html#Calling-FFTW-from-Modern-Fortran">Calling FFTW from Modern Fortran</a>
Chris@10 54 <hr>
Chris@10 55 </div>
Chris@10 56
Chris@10 57 <h3 class="section">7.2 Reversing array dimensions</h3>
Chris@10 58
Chris@10 59 <p><a name="index-row_002dmajor-517"></a><a name="index-column_002dmajor-518"></a>A minor annoyance in calling FFTW from Fortran is that FFTW's array
Chris@10 60 dimensions are defined in the C convention (row-major order), while
Chris@10 61 Fortran's array dimensions are the opposite convention (column-major
Chris@10 62 order). See <a href="Multi_002ddimensional-Array-Format.html#Multi_002ddimensional-Array-Format">Multi-dimensional Array Format</a>. This is just a
Chris@10 63 bookkeeping difference, with no effect on performance. The only
Chris@10 64 consequence of this is that, whenever you create an FFTW plan for a
Chris@10 65 multi-dimensional transform, you must always <em>reverse the
Chris@10 66 ordering of the dimensions</em>.
Chris@10 67
Chris@10 68 <p>For example, consider the three-dimensional (L&nbsp;&times;&nbsp;M&nbsp;&times;&nbsp;N) arrays:
Chris@10 69
Chris@10 70 <pre class="example"> complex(C_DOUBLE_COMPLEX), dimension(L,M,N) :: in, out
Chris@10 71 </pre>
Chris@10 72 <p>To plan a DFT for these arrays using <code>fftw_plan_dft_3d</code>, you could do:
Chris@10 73
Chris@10 74 <p><a name="index-fftw_005fplan_005fdft_005f3d-519"></a>
Chris@10 75 <pre class="example"> plan = fftw_plan_dft_3d(N,M,L, in,out, FFTW_FORWARD,FFTW_ESTIMATE)
Chris@10 76 </pre>
Chris@10 77 <p>That is, from FFTW's perspective this is a N&nbsp;&times;&nbsp;M&nbsp;&times;&nbsp;L array.
Chris@10 78 <em>No data transposition need occur</em>, as this is <em>only
Chris@10 79 notation</em>. Similarly, to use the more generic routine
Chris@10 80 <code>fftw_plan_dft</code> with the same arrays, you could do:
Chris@10 81
Chris@10 82 <pre class="example"> integer(C_INT), dimension(3) :: n = [N,M,L]
Chris@10 83 plan = fftw_plan_dft_3d(3, n, in,out, FFTW_FORWARD,FFTW_ESTIMATE)
Chris@10 84 </pre>
Chris@10 85 <p>Note, by the way, that this is different from the legacy Fortran
Chris@10 86 interface (see <a href="Fortran_002dinterface-routines.html#Fortran_002dinterface-routines">Fortran-interface routines</a>), which automatically
Chris@10 87 reverses the order of the array dimension for you. Here, you are
Chris@10 88 calling the C interface directly, so there is no &ldquo;translation&rdquo; layer.
Chris@10 89
Chris@10 90 <p><a name="index-r2c_002fc2r-multi_002ddimensional-array-format-520"></a>An important thing to keep in mind is the implication of this for
Chris@10 91 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
Chris@10 92 chops the last dimension roughly in half (N&nbsp;&times;&nbsp;M&nbsp;&times;&nbsp;L real input
Chris@10 93 goes to N&nbsp;&times;&nbsp;M&nbsp;&times;&nbsp;L/2+1 complex output). In Fortran, because
Chris@10 94 the array dimension notation is reversed, the <em>first</em> dimension of
Chris@10 95 the complex data is chopped roughly in half. For example consider the
Chris@10 96 &lsquo;<samp><span class="samp">r2c</span></samp>&rsquo; transform of L&nbsp;&times;&nbsp;M&nbsp;&times;&nbsp;N real input in Fortran:
Chris@10 97
Chris@10 98 <p><a name="index-fftw_005fplan_005fdft_005fr2c_005f3d-521"></a><a name="index-fftw_005fexecute_005fdft_005fr2c-522"></a>
Chris@10 99 <pre class="example"> type(C_PTR) :: plan
Chris@10 100 real(C_DOUBLE), dimension(L,M,N) :: in
Chris@10 101 complex(C_DOUBLE_COMPLEX), dimension(L/2+1,M,N) :: out
Chris@10 102 plan = fftw_plan_dft_r2c_3d(N,M,L, in,out, FFTW_ESTIMATE)
Chris@10 103 ...
Chris@10 104 call fftw_execute_dft_r2c(plan, in, out)
Chris@10 105 </pre>
Chris@10 106 <p><a name="index-in_002dplace-523"></a><a name="index-padding-524"></a>Alternatively, for an in-place r2c transform, as described in the C
Chris@10 107 documentation we must <em>pad</em> the <em>first</em> dimension of the
Chris@10 108 real input with an extra two entries (which are ignored by FFTW) so as
Chris@10 109 to leave enough space for the complex output. The input is
Chris@10 110 <em>allocated</em> as a 2[L/2+1]&nbsp;&times;&nbsp;M&nbsp;&times;&nbsp;N array, even though only
Chris@10 111 L&nbsp;&times;&nbsp;M&nbsp;&times;&nbsp;N of it is actually used. In this example, we will
Chris@10 112 allocate the array as a pointer type, using &lsquo;<samp><span class="samp">fftw_alloc</span></samp>&rsquo; to
Chris@10 113 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
Chris@10 114 same memory as both a real array and a complex array.
Chris@10 115
Chris@10 116 <p><a name="index-fftw_005falloc_005fcomplex-525"></a><a name="index-c_005ff_005fpointer-526"></a>
Chris@10 117 <pre class="example"> real(C_DOUBLE), pointer :: in(:,:,:)
Chris@10 118 complex(C_DOUBLE_COMPLEX), pointer :: out(:,:,:)
Chris@10 119 type(C_PTR) :: plan, data
Chris@10 120 data = fftw_alloc_complex(int((L/2+1) * M * N, C_SIZE_T))
Chris@10 121 call c_f_pointer(data, in, [2*(L/2+1),M,N])
Chris@10 122 call c_f_pointer(data, out, [L/2+1,M,N])
Chris@10 123 plan = fftw_plan_dft_r2c_3d(N,M,L, in,out, FFTW_ESTIMATE)
Chris@10 124 ...
Chris@10 125 call fftw_execute_dft_r2c(plan, in, out)
Chris@10 126 ...
Chris@10 127 call fftw_destroy_plan(plan)
Chris@10 128 call fftw_free(data)
Chris@10 129 </pre>
Chris@10 130 <!-- -->
Chris@10 131 </body></html>
Chris@10 132