sm::hexfft

The hexagonal fast Fourier transform

import sm.hexfft;

Module file: sm/hexfft.cppm. Test code: tests/hexfft1

Table of Contents

Summary

The Hexagonal FFT algorithm, following Nicholas I. Rummelt’s PhD thesis Array set addressing: Enabling efficient hexagonally sampled image processing, University of Florida, 2010.

With this code, you can present data arranged over a hexgrid (specifically, a sm::hexgrid<F, hexalign::point_up>) with an arbitrary boundary, and compute the two dimensional spatial Fourier transform. A hexgrid in the frequency space (a sm::hexgrid<F, hexalign::flat_up>) is created alongside a data container with the FFT result in it.

Defined as:

template<typename F = double, bool construct_hg_asa = false>
struct fft

Floating point type F is used for hexgrid coordinates and as the element type for std::complex<F> values. construct_hg_asa is a boolean which may be set true to create an optional hexgrid that is useful for debugging, but not required for the forward or inverse transforms.

The algorithm is made fast by splitting the hexgrid into two rectangular grids of alternating rows. For this reason, the input hexgrid must be enclosed by a perfect rectangular hexgrid (with zero-padding of new elements). Alternating rows are placed in two Array Set Addressing (ASA) grids, then the standard two dimensional, rectangular FFT can be applied.

For a practical, visualized example implementation, you can see the hex_fft repository.

Quick usage guide

Create a hexgrid. The hexgrid constructor args are hex-hex distance, grid width and grid ‘z’ value (usually set to 0).

import sm.hexgrid;

sm::hexgrid<float sm::hexalign::point_up> hg(0.01f, 4.0f, 0.0f);
hg.set_circular_boundary (1.0f); // or any other boundary setting function in hexgrid

Create some data. The order of the data is defined by the hexgrid indexing. Each hexgrid element has a ‘vector iterator’, vi and provides access to the location of the hex.

import sm.vvec;

sm::vvec<float> data (hg.num(), 0.0f);
for (auto h : hg.hexen) {
    data[h.vi] = some_function_of (h.x, h.y);
}

Create an sm::hexfft::fft object and perform a forward transform. The result is stored in hfft.X_hexgrid, which is a sm::vvec of std::complex<> values.

import sm.hexfft;

sm::hexfft::fft<float> hfft (&hg); // construct and initialize
hfft.forward (data); // Perform forward FFT transform

You can modify the values in X_hexgrid to make filters. The values in X_hexgrid are associated with a frequency hexgrid, hexfft::fft::hgf, which is created when hfft is initialized.

for (auto h : hfft.hgf->hexen) { // hgf is a unique_ptr to a hexgrid
    std::cout << "FFT Frequency " << h.x << ", " << h.y
              << " has magnitude " << std::real(hfft.X_hexgrid[h.vi]) << std::endl;
}

After changing values in hfft.X_hexgrid (perhaps by masking) you can then inverse transform from frequency space to image space

sm::vvec<std::complex<float>> invimg = hfft.inverse();

The returned data is defined over your original hexgrid, hg.

fft members

Attributes populated during initialization

hexfft::asa_rows and hexfft::asa_cols (both uint32_t are populated with the dimensions of the two ASA grids.

hexfft::ri_min and hexfft::gi_min are configured with the hex::ri, hex::gi of the padded rectangular hexgrid’s (a=0, r=0, c=0) corner.

The hexgrid pointer hexfft::hg is the point your provide at construction/init.

The hexgrid hexfft::hgf is constructed to match hg for the frequency space. It has alignment hexalign::flat_up.

hexfft::Uscale is a scaling factor (computed from image data hexgrid spacing) for the frequency hexgrid, hgf. Uscale allows the user to visualize the frequency hexgrid on a similar size scale to the input data, regardless of the spacing on the input data.

Data attributes

hexfft::d0 and hexfft::d1 hold copies of the input data (or inverse-transformed data) in ASA format. d0 holds even rows, d1, odd rows. They are both sm::vmat containers of std::complex<F> values.

hexfft::X0 and hexfft::X1 are similar containers that hold the (ASA format) result of the forward transformation of d0 and d1.

The data in X0 and X1 are manipulated, and then rearranged into a vvec of std::complex<F> values, hexfft::X_hexgrid. X_hexgrid is spatially defined by the frequency hexgrid hexfft::hgf.


This site uses Just the Docs, a documentation theme for Jekyll.