Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>To help clarify (focusing in 2D as it easily extends to 2D transform of 3D data):</p> <h2>storage</h2> <p>An <code>Nx * Ny</code> array requires <code>Nx * (Ny / 2 + 1)</code> complex elements after a Fourier Transform.</p> <p>First, in the y-direction, the negative frequencies can be reconstructed from the complex conjugate symmetry (that comes from transforming a real sequence). The y modes <code>ky</code> then run from <code>0 to Ny/2</code> inclusive. <strong>So for y we need <code>Ny/2 + 1</code> complex values.</strong></p> <p>Next we transform in the x-direction where we cannot use the same symmetry assumption, as we are acting on complex-valued y values. Therefore we must include positive and negative frequencies, so x-modes <code>kx</code> run from <code>-Nx/2 to Nx/2</code> inclusive. However <code>kx = -Nx/2</code> and <code>kx = Nx/2</code> are equivalent so only one is stored (see <a href="http://www.fftw.org/fftw3_doc/The-1d-Discrete-Fourier-Transform-_0028DFT_0029.html#The-1d-Discrete-Fourier-Transform-_0028DFT_0029" rel="nofollow">here</a>). <strong>So for x we need <code>Nx</code> complex values.</strong></p> <h2>access</h2> <p>As tir38 points out the x index post-transform runs from 0 to Nx-1, however this doesn't mean that modes <code>kx</code> run from 0 to Nx-1. FFTW packs positive frequencies in the first half of the array, then negative frequencies in the second half (in reverse order), like:</p> <pre><code>kx = 0, 1, 2, ..., Nx/2, -Nx/2 + 1, ..., -2, -1 </code></pre> <p>There are two ways we can think about accessing these elements. First as tir38 suggests we can loop through in order and work out the mode <code>kx</code> from the index:</p> <pre><code>for (int i = 0; i &lt; Nx; i++) { // produces the list of kxs above int kx = (i &lt;= Nx/2) ? i : i - Nx; // here we index with i, but with the knowledge that the mode is kx outputRe(i, ...) = some function of kx } </code></pre> <p>or we can loop through the modes <code>kx</code> and convert to an index:</p> <pre><code>for (int kx = -Nx/2; kx &lt; Nx/2; kx++) { // work out index from mode kx int i = (kx &gt;= 0) ? i : Nx + i; // here we index with i, but with the knowledge that the mode is kx outputRe(i, ...) = some function of kx } </code></pre> <p>The two types of indexing along with the rest of the code <a href="https://gist.github.com/hemmer/5916596" rel="nofollow">can found here</a>.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload