direct static method
Float32List
direct(
- Float32List x,
- Float32List h, {
- ConvMode mode = ConvMode.convolution,
- CorrOutMode outMode = CorrOutMode.full,
- bool simd = false,
Computes convolution or cross-correlation directly for one block of data.
mode selects the operation:
- ConvMode.convolution: linear convolution.
- ConvMode.xcorr: linear cross-correlation.
outMode selects output support:
- CorrOutMode.full: length
nx + nh - 1. - CorrOutMode.valid: complete-overlap region only.
- CorrOutMode.same: length
nx, centered w.r.t. full.
simd enables SIMD acceleration (SSE/NEON/etc) when available.
SIMD may produce tiny floating-point differences vs scalar due to
accumulation order.
Example:
final x = Float32List.fromList([1, 2, 3]);
final h = Float32List.fromList([1, 1, 1]);
final yFull = Conv.direct(
x,
h,
mode: ConvMode.convolution,
outMode: CorrOutMode.full,
);
final rSame = Conv.direct(
x,
h,
mode: ConvMode.xcorr,
outMode: CorrOutMode.same,
simd: true,
);
Implementation
static Float32List direct(
Float32List x,
Float32List h, {
ConvMode mode = ConvMode.convolution,
CorrOutMode outMode = CorrOutMode.full,
bool simd = false,
}) {
final nx = x.length;
final nh = h.length;
final ny = outLenMode(nx, nh, outMode: outMode);
ffi.Pointer<ffi.Float> xPtr = ffi.nullptr;
ffi.Pointer<ffi.Float> hPtr = ffi.nullptr;
ffi.Pointer<ffi.Float> yPtr = ffi.nullptr;
try {
xPtr = calloc<ffi.Float>(nx);
hPtr = calloc<ffi.Float>(nh);
yPtr = calloc<ffi.Float>(ny);
xPtr.asTypedList(nx).setAll(0, x);
hPtr.asTypedList(nh).setAll(0, h);
final rc = (outMode == CorrOutMode.full && !simd)
? yl_conv_direct_f32_ffi(xPtr, nx, hPtr, nh, yPtr, mode.value)
: simd
? yl_conv_direct_mode_simd_f32_ffi(
xPtr,
nx,
hPtr,
nh,
yPtr,
mode.value,
outMode.value,
)
: yl_conv_direct_mode_f32_ffi(
xPtr,
nx,
hPtr,
nh,
yPtr,
mode.value,
outMode.value,
);
if (rc != 0) {
throw StateError('Conv.direct native call failed with code $rc');
}
return Float32List.fromList(yPtr.asTypedList(ny));
} finally {
if (xPtr != ffi.nullptr) calloc.free(xPtr);
if (hPtr != ffi.nullptr) calloc.free(hPtr);
if (yPtr != ffi.nullptr) calloc.free(yPtr);
}
}