Skip to content

File corr2d_core.h

FileList > corr2d > corr2d_core.h

Go to the source code of this file

2-D FFT-based cross-correlator with coherent integrate-and-dump. More...

  • #include "clib_common.h"
  • #include "dp_state.h"
  • #include "fft2d/fft2d_core.h"

Classes

Type Name
struct corr2d_state_t
2-D FFT correlator state.

Public Functions

Type Name
corr2d_state_t * corr2d_create (const float complex * ref, size_t ny, size_t nx, size_t dwell, int nthreads, size_t ny_out, size_t nx_out)
Allocate a 2-D FFT correlator with coherent integrate-and-dump. Two-dimensional extension of corr_create() . The reference is a flat row-major ny×nx CF32 array; its conjugate spectrum is pre-computed once so each execute() call costs two 2-D FFTs plus ny*nx complex multiplies. The Python wrapper requiresref to be a 2-D ndarray with shape (ny, nx); it passes a flat view to C.
void corr2d_destroy (corr2d_state_t * state)
Destroy and free a corr2d instance.
size_t corr2d_execute (corr2d_state_t * state, const float complex * in, size_t n_in, float complex * out)
Correlate one 2-D frame and optionally dump the coherent accumulator. Runs the 2-D pipeline: FFT2 → pointwise multiply with ref_spec → accumulate the cross-spectrum; on dump, IFFT2 → normalise (÷ ny*nx). Accumulating in the frequency domain and inverting once is exactly the per-frame inverse summed, by linearity of the IFFT — valid because the dwell is coherent (a complex sum); a non-coherent (magnitude) integration could not defer the inverse. The Python wrapper accepts a (ny, nx) CF32 ndarray; a dump returns a flat length-ny*nx ndarray, a no-dump returns None.
size_t corr2d_execute_max_out (corr2d_state_t * state)
Maximum output samples per execute call (always == ny*nx).
void corr2d_get_state (const corr2d_state_t * state, void * blob)
void corr2d_reset (corr2d_state_t * state)
Zero the accumulator and reset the integration counter to 0. Equivalent to starting a fresh dwell cycle without rebuilding FFT plans or recomputing ref_spec.
void corr2d_set_ref (corr2d_state_t * state, const float complex * ref)
Replace the reference and recompute conj(FFT2(ref)).
int corr2d_set_state (corr2d_state_t * state, const void * blob)
size_t corr2d_state_bytes (const corr2d_state_t * state)

Macros

Type Name
define CORR2D_STATE_MAGIC [**DP\_FOURCC**](dp__state_8h.md#define-dp_fourcc) ('C','R','2','D')
define CORR2D_STATE_VERSION 1u

Detailed Description

Two-dimensional extension of corr_core: all buffers are ny×nx row-major flat arrays of length ny*nx. The correlation theorem extends naturally:

R_xh[i,j] = IFFT2( FFT2(x) · conj(FFT2(h)) ) / (ny*nx)

The reference spectrum is pre-computed at create time. The int-dump semantics are identical to the 1-D case: coherently sum dwell frames, then dump.

Lifecycle:

float complex ref[NY * NX] = { ... };    // row-major 2-D reference
corr2d_state_t *c = corr2d_create(ref, NY, NX, 4, 1);
float complex out[NY * NX];
for (int i = 0; i < 4; i++) {
    size_t n_out = corr2d_execute(c, frame[i], NY*NX, out);
    if (n_out) process_2d(out, NY, NX);   // fires once, on i == 3
}
corr2d_destroy(c);

Public Functions Documentation

function corr2d_create

Allocate a 2-D FFT correlator with coherent integrate-and-dump. Two-dimensional extension of corr_create() . The reference is a flat row-major ny×nx CF32 array; its conjugate spectrum is pre-computed once so each execute() call costs two 2-D FFTs plus ny*nx complex multiplies. The Python wrapper requiresref to be a 2-D ndarray with shape (ny, nx); it passes a flat view to C.

corr2d_state_t * corr2d_create (
    const float complex * ref,
    size_t ny,
    size_t nx,
    size_t dwell,
    int nthreads,
    size_t ny_out,
    size_t nx_out
) 

Parameters:

  • ref Reference image, 2-D (ny, nx) CF32 ndarray in Python.
  • ny Number of rows in the reference and input frames.
  • nx Number of columns in the reference and input frames.
  • dwell Integration depth; must be >= 1.
  • nthreads Accepted for API compatibility; ignored.
  • ny_out Inverse/output rows; 0 => native (ny). Must be >= ny. A larger output zero-pads the cross-spectrum before the inverse, returning the band-limited (Dirichlet) interpolation of the correlation on a finer (ny_out, nx_out) grid — same peak, sub-bin resolution. Native is bit-exact and allocates no extra buffers.
  • nx_out Inverse/output columns; 0 => native (nx). Must be >= nx.

Returns:

Heap-allocated state, or NULL on failure.

>>> from doppler.spectral import Corr2D
>>> import numpy as np
>>> ref = np.zeros((4, 4), dtype=np.complex64); ref[0, 0] = 1.0
>>> c = Corr2D(ref=ref, dwell=1, nthreads=1)
>>> c.ny, c.nx, c.dwell, c.count
(4, 4, 1, 0)


function corr2d_destroy

Destroy and free a corr2d instance.

void corr2d_destroy (
    corr2d_state_t * state
) 

Parameters:

  • state May be NULL.

function corr2d_execute

Correlate one 2-D frame and optionally dump the coherent accumulator. Runs the 2-D pipeline: FFT2 → pointwise multiply with ref_spec → accumulate the cross-spectrum; on dump, IFFT2 → normalise (÷ ny*nx). Accumulating in the frequency domain and inverting once is exactly the per-frame inverse summed, by linearity of the IFFT — valid because the dwell is coherent (a complex sum); a non-coherent (magnitude) integration could not defer the inverse. The Python wrapper accepts a (ny, nx) CF32 ndarray; a dump returns a flat length-ny*nx ndarray, a no-dump returns None.

size_t corr2d_execute (
    corr2d_state_t * state,
    const float complex * in,
    size_t n_in,
    float complex * out
) 

Parameters:

  • state Allocated 2-D correlator (non-NULL).
  • in Input frame, flat row-major CF32, length ny*nx.
  • n_in Number of input samples; must equal ny*nx.
  • out Output buffer for the correlation map (CF32, length ny*nx); written only on a dump call.

Returns:

ny*nx on a dump, 0 otherwise (None in Python).

>>> from doppler.spectral import Corr2D
>>> import numpy as np
>>> ref = np.zeros((2, 2), dtype=np.complex64); ref[0, 0] = 1.0
>>> c = Corr2D(ref=ref, dwell=2)
>>> x = np.ones((2, 2), dtype=np.complex64)
>>> c.execute(x) is None   # frame 1  no dump
True
>>> c.execute(x).tolist()  # frame 2  dump
[(2+0j), (2+0j), (2+0j), (2+0j)]


function corr2d_execute_max_out

Maximum output samples per execute call (always == ny*nx).

size_t corr2d_execute_max_out (
    corr2d_state_t * state
) 


function corr2d_get_state

void corr2d_get_state (
    const corr2d_state_t * state,
    void * blob
) 

function corr2d_reset

Zero the accumulator and reset the integration counter to 0. Equivalent to starting a fresh dwell cycle without rebuilding FFT plans or recomputing ref_spec.

void corr2d_reset (
    corr2d_state_t * state
) 

>>> from doppler.spectral import Corr2D
>>> import numpy as np
>>> ref = np.zeros((2, 2), dtype=np.complex64); ref[0, 0] = 1.0
>>> c = Corr2D(ref=ref, dwell=3)
>>> _ = c.execute(np.ones((2, 2), dtype=np.complex64))
>>> c.count
1
>>> c.reset()
>>> c.count
0

function corr2d_set_ref

Replace the reference and recompute conj(FFT2(ref)).

void corr2d_set_ref (
    corr2d_state_t * state,
    const float complex * ref
) 

Also resets accumulator and counter.

Parameters:

  • state Must be non-NULL.
  • ref New reference, flat row-major CF32, length ny*nx.

function corr2d_set_state

int corr2d_set_state (
    corr2d_state_t * state,
    const void * blob
) 

function corr2d_state_bytes

size_t corr2d_state_bytes (
    const corr2d_state_t * state
) 

Macro Definition Documentation

define CORR2D_STATE_MAGIC

#define CORR2D_STATE_MAGIC `DP_FOURCC ('C','R','2','D')`

define CORR2D_STATE_VERSION

#define CORR2D_STATE_VERSION `1u`


The documentation for this class was generated from the following file native/inc/corr2d/corr2d_core.h