Skip to content

File corr_core.h

FileList > corr > corr_core.h

Go to the source code of this file

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

  • #include "clib_common.h"
  • #include "dp_state.h"
  • #include "fft/fft_core.h"

Classes

Type Name
struct corr_state_t
1-D FFT correlator state.

Public Functions

Type Name
corr_state_t * corr_create (const float complex * ref, size_t n, size_t dwell, int nthreads, size_t n_out)
Allocate a 1-D FFT correlator with coherent integrate-and-dump. Pre-computes conj(FFT(ref)) once at construction so each execute() call costs only two FFTs and n complex multiplies. ref may be freed after this returns. Withdwell == 1 every call produces output; with larger values the accumulator absorbsdwell frames before dumping.
void corr_destroy (corr_state_t * state)
Destroy and free a corr instance.
size_t corr_execute (corr_state_t * state, const float complex * in, size_t n_in, float complex * out)
Correlate one frame and optionally dump the coherent accumulator. Runs: forward FFT → pointwise multiply with ref_spec → accumulate the cross-spectrum; on dump, inverse FFT → normalise (÷ n). 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. On thedwell-th callout is written, the accumulator is zeroed, and the counter resets; the function returns n_out. All other calls return 0 and leaveout unmodified. In Python, a dump returns an ndarray and a no-dump returns None.
size_t corr_execute_max_out (corr_state_t * state)
Maximum output samples per execute call (== n_out).
void corr_get_state (const corr_state_t * state, void * blob)
void corr_reset (corr_state_t * state)
Zero the accumulator and reset the integration counter to 0. Equivalent to starting a fresh dwell cycle without tearing down the FFT plans. Does NOT recompute ref_spec; use corr_set_ref() to replace the reference.
void corr_set_ref (corr_state_t * state, const float complex * ref)
Replace the reference signal and recompute conj(FFT(ref)).
int corr_set_state (corr_state_t * state, const void * blob)
size_t corr_state_bytes (const corr_state_t * state)

Macros

Type Name
define CORR_STATE_MAGIC [**DP\_FOURCC**](dp__state_8h.md#define-dp_fourcc) ('C','O','R','R')
define CORR_STATE_VERSION 1u

Detailed Description

Implements the correlation theorem: cross-correlation in the lag domain is equivalent to pointwise multiplication of the forward spectrum with the conjugate reference spectrum, followed by an inverse FFT.

R_xh[τ] = IFFT( FFT(x) · conj(FFT(h)) ) / n

The reference spectrum conj(FFT(h)) is pre-computed at create time and stored in ref_spec, so each execute call costs two FFTs (forward + inverse) plus n complex multiplies — O(n log n).

Integrate-and-dump (int-dump) coherently sums dwell successive correlation maps into an accumulator. On the dwell-th call execute() copies the accumulator to the caller's output buffer, zeroes the accumulator, resets the counter, and returns n. All other calls return 0 (no output produced). With dwell = 1 the object is a pure, zero- latency correlator.

Lifecycle:

float complex ref[N] = { ... };
corr_state_t *c = corr_create(ref, N, 8, 1);   // 8-frame coherent dwell
float complex out[N];
for (int i = 0; i < 8; i++) {
    size_t n_out = corr_execute(c, frame[i], N, out);
    if (n_out) process(out, N);   // fires once, on i == 7
}
corr_destroy(c);

Thread safety: a single state must not be used concurrently from multiple threads; create separate instances per thread.

Public Functions Documentation

function corr_create

Allocate a 1-D FFT correlator with coherent integrate-and-dump. Pre-computes conj(FFT(ref)) once at construction so each execute() call costs only two FFTs and n complex multiplies. ref may be freed after this returns. Withdwell == 1 every call produces output; with larger values the accumulator absorbsdwell frames before dumping.

corr_state_t * corr_create (
    const float complex * ref,
    size_t n,
    size_t dwell,
    int nthreads,
    size_t n_out
) 

Parameters:

  • ref Reference signal, CF32, length n.
  • n Reference / FFT length in samples.
  • dwell Integration depth; must be >= 1. Pass 1 for immediate output on every call.
  • nthreads Accepted for API compatibility; ignored.
  • n_out Inverse/output length; 0 => native (n). Must be >= n. A larger value zero-pads the cross-spectrum before the inverse, returning the band-limited (Dirichlet) interpolation of the correlation on a finer length-n_out grid — same peak, sub-bin lag resolution. Native is bit-exact and allocates no extra buffer.

Returns:

Heap-allocated state, or NULL on allocation failure.

>>> from doppler.spectral import Corr
>>> import numpy as np
>>> ref = np.zeros(4, dtype=np.complex64); ref[0] = 1.0
>>> corr = Corr(ref=ref, dwell=1, nthreads=1)
>>> corr.n, corr.dwell, corr.count
(4, 1, 0)


function corr_destroy

Destroy and free a corr instance.

void corr_destroy (
    corr_state_t * state
) 

Parameters:

  • state May be NULL.

function corr_execute

Correlate one frame and optionally dump the coherent accumulator. Runs: forward FFT → pointwise multiply with ref_spec → accumulate the cross-spectrum; on dump, inverse FFT → normalise (÷ n). 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. On thedwell-th callout is written, the accumulator is zeroed, and the counter resets; the function returns n_out. All other calls return 0 and leaveout unmodified. In Python, a dump returns an ndarray and a no-dump returns None.

size_t corr_execute (
    corr_state_t * state,
    const float complex * in,
    size_t n_in,
    float complex * out
) 

Parameters:

  • state Allocated correlator (non-NULL).
  • in Input frame, CF32, length state->n.
  • n_in Number of input samples; must equal state->n.
  • out Output buffer for the correlation map (CF32, length n_out); written only on a dump call.

Returns:

n_out on a dump call, 0 otherwise (None in Python).

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


function corr_execute_max_out

Maximum output samples per execute call (== n_out).

size_t corr_execute_max_out (
    corr_state_t * state
) 


function corr_get_state

void corr_get_state (
    const corr_state_t * state,
    void * blob
) 

function corr_reset

Zero the accumulator and reset the integration counter to 0. Equivalent to starting a fresh dwell cycle without tearing down the FFT plans. Does NOT recompute ref_spec; use corr_set_ref() to replace the reference.

void corr_reset (
    corr_state_t * state
) 

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

function corr_set_ref

Replace the reference signal and recompute conj(FFT(ref)).

void corr_set_ref (
    corr_state_t * state,
    const float complex * ref
) 

Also resets the accumulator and counter (as if corr_reset() were called). Useful when the reference must change between dwells without tearing down the FFT plans.

Parameters:

  • state Must be non-NULL.
  • ref New reference signal of length state->n.

function corr_set_state

int corr_set_state (
    corr_state_t * state,
    const void * blob
) 

function corr_state_bytes

size_t corr_state_bytes (
    const corr_state_t * state
) 

Macro Definition Documentation

define CORR_STATE_MAGIC

#define CORR_STATE_MAGIC `DP_FOURCC ('C','O','R','R')`

define CORR_STATE_VERSION

#define CORR_STATE_VERSION `1u`


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