Fill Gaps — Control Systems/Resampling
Control_Systems/Resampling/Fill_Gaps · 2 input / 1 output port(s) at insert · exports to Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text
Description#
The block's own DESCRIPTION_HTML, rendered verbatim — the same text the config dialog's info panel and the library navigator show. Fix a wrong sentence in the block's .cpp (R-D9), never here.
Fill Gaps
Control Systems / Resampling
Rebuilds the missing samples of a frame from the samples around them –
MATLAB's fillgaps(x, maxlen, order). Every run of missing samples is
filled twice, once from the data before it and once from the data
after it: each side's segment (at most maxlen samples, mean removed)
gets an autoregressive model of order min(segment length − 1, order)
fitted by Burg's method, the all-pole recursion runs through the gap, and
the two answers are averaged with the weights below, so a gap is a cross-fade
between the model in front of it and the model behind it.
y = (yfwd·wfwd + ybwd·wbwd) / (wfwd + wbwd), where a present sample weighs 1 and a missing sample weighs its distance to the far end of its own gap – except that a gap reaching the end of the frame weighs 1 throughout, and a gap before the first present sample weighs 0, which leaves it to the other sweep alone.
Ports
- x – the frame to repair, an [L,1] column with the oldest sample first, as MATLAB takes its vector. L is read off the wire, is at least 2 and at most 64, and a Tapped Delay with Delay Order Oldest turns a stream into such a frame.
- valid – which samples are present, the same size as x: 0.5 or more means present, anything less means missing. MATLAB marks a missing sample with NaN inside the signal; a fixed-point datapath has no NaN to carry and neither has an exported core's stimulus, so the mark rides this port instead. The value of x at a missing sample is ignored.
- y – the filled frame, [L,1]: the present samples unchanged, and every missing one replaced.
Parameters
- AR Order – the model order, 1 to 12. Each fit uses min(segment length − 1, this), so a short segment is fitted at the order it can support.
- Maximum Segment Length – how far back a fit may look, MATLAB's
maxlen: 0 means every sample available (MATLAB's default of Inf), and a positive value must be at least 3 and at least the AR Order, as MATLAB requires. Samples filled earlier in the sweep count as data for a later gap, exactly as in MATLAB. - Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period.
Code export
All ten targets: Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog and PLC Structured Text, from one program, so every target does the same arithmetic in the same order as the simulation. The frame length, the order and the segment limit are structural; re-export after changing them.
The three HDL targets run the fit in real arithmetic and
quantize only at the ports: simulation-only, not offered as synthesizable.
Burg's recursion divides by a sum of squared prediction errors, which spans a wide
range and does not belong in a Q16.16 datapath.
Simulink bridge
None (Support::None). fillgaps is a Signal
Processing Toolbox function and that toolbox ships no Simulink library, so
there is no path a diagram could name. The bridge reports this block rather than
dropping it silently, and it has no parity testbench; code export
verification covers all ten languages.
Notes
- Verified against R2026a: see the source banner for the frames and the
measured agreement with
fillgaps. - ⚠ MATLAB's default order selection is not offered.
fillgaps(x, maxlen)with no order picks one per segment by minimizing an AIC over every order the segment admits and stopping 30 orders past the best; the length of that search, and the size of the model it lands on, both depend on the data. This block isfillgaps(x, maxlen, order)with the order given, which is that function exactly once the order is fixed. - A gap before the first present sample is carried by the backward sweep alone, and one after the last present sample by the forward sweep alone: that is what the zero weight above means. A frame with no present sample at all answers all zeros – MATLAB answers NaN there, having nothing to predict from, and a fixed-point target has no NaN to answer with.
- A segment of one sample cannot support a model, so the gap after it is filled
with that one value, as MATLAB's
arpredictdoes; a segment whose samples are all equal makes Burg's division 0 / 0, and the gap is then filled with the segment's mean, which is MATLAB'sanynanbranch. - Algebraic: the whole frame is re-filled from the frame on the wires every sample, and the block carries no state of its own. Fed from a Tapped Delay, the repaired sample at the far end of the frame is L−1 samples behind the input.
Code facts#
| Fact | Value |
|---|---|
| registered type | Control_Systems/Resampling/Fill_Gaps |
| family | Control_Systems/Resampling |
| solver environment class | ICoreBlock_0_Control_Systems_1_Resampling_2_Fill_Gaps |
| source | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Resampling/Fill_Gaps/ICoreBlock_0_Control_Systems_1_Resampling_2_Fill_Gaps.cpp |
| header | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Resampling/Fill_Gaps/ICoreBlock_0_Control_Systems_1_Resampling_2_Fill_Gaps.h |
| default size on canvas | 150 × 80 px |
| ports at insert | 2 in, 1 out |
| code generators implemented | Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text |
Ports#
| # | Direction | Signal type | Description label |
|---|---|---|---|
| 1 | in | ICoreDouble | x |
| 2 | in | ICoreDouble | valid |
| 3 | out | ICoreDouble | y |
Ports the constructor creates. A block whose port list changes with its configuration adds or removes ports at load time; the count above is the one a freshly inserted block has.
Configuration variables#
| Config variable | Default | Simulink parameter |
|---|---|---|
AR Order | 4 | — |
Maximum Segment Length | 0 | — |
Every block also carries Sampling Time (s) from ICoreBlockSolverEnvironment: zero or less inherits the solver's rate, a positive value runs the block at that period.
Simulink bridge#
| support | Support::None |
| Simulink path | — |
| port-count rule | PortsParam::None |
SampleTime parameter | yes |
Caveat (shown to the user): fillgaps is a Signal Processing Toolbox function, not a Simulink library block -- that toolbox ships no Simulink library at all -- so there is no path a diagram could name; the block is reported rather than dropped when a model crosses
Catalog contract: src/ICoreBlocks/ICoreCoder/ICoreCommandSystem/SimulinkBridge/ICoreSimulinkBlockCatalog.h
Description vs code#
The lists agree. check_block_descriptions.py finds no disagreement between the description's Ports, Parameters, Code export and Simulink bridge lists and the code's.
The verdict above is
tools/docs/check_block_descriptions.py(P7.1), which compares LISTS. It cannot read a sentence: "stateless" on a block with a state, an initial-value semantic the recursion does not implement, a "not synthesizable" caveat the HDL banner contradicts. That is the agent audit (P7.3) on BLOCK_DESCRIPTION_AUDIT.md, and this tool's green is not a substitute for one.
File banner (developer view)#
The top comment of the block's .cpp — the maths, the realization and the export strategy, addressed to whoever changes it. It must not contradict the description above (P7.5).
Fill Gaps -- MATLAB's fillgaps, missing samples rebuilt from the data around them The frame on the input is swept twice: forward, and backward over the reversed frame. Each sweep fills every gap from the segment of up to maxlen samples immediately before it -- mean removed, an AR model of order min(segment length - 1, order) fitted by Burg's method, and the all-pole recursion run through the gap -- and the two answers are averaged with fillgaps's own weights, so a gap is a cross-fade between the model in front of it and the model behind it.
MISSING SAMPLES ARE MARKED ON A SECOND PORT. MATLAB marks them with NaN inside the signal; neither a Q16.16 datapath nor a verification stimulus has a NaN to carry, so validity rides its own input and a sample counts as present when its validity value is 0.5 or more.
Measured against R2026a over 30 frames of 24 samples -- 6 hand-built validity patterns that between them hold a leading gap, a gap after a one-sample segment, interior gaps, a trailing gap and a frame with only three present samples, plus 24 random ones at ~30 % missing: fillgaps(x, Inf, 4) agrees to 1.1e-15 fillgaps(x, 5, 4) agrees to 4.2e-15 and the EXPORTED code was measured too, not only the transcription: over the 41 frames of each of the three verification rigs, the exported Python core agrees with fillgaps to 3.3e-16 (every sample available), 6.7e-16 (segments limited to 5) and 8.9e-16 (a denser gap pattern).
What is not offered: MATLAB's DEFAULT order selection. fillgaps(x, maxlen) with no order picks one per segment by minimizing an AIC over every order the segment admits, stopping 30 orders past the best; that is a search whose length depends on the data, and the order it lands on changes the size of the model. This block takes the order as a parameter, which is fillgaps(x, maxlen, order) exactly. The description says so.
Support::None: fillgaps is a Signal Processing Toolbox function and that toolbox ships no Simulink library.
Sample results#
Plotted: vector — Sine Wave, [3,1]: amplitudes 1/2/3 at 2 rad/s (tried only because every scalar stimulus was refused)
Category dynamic · sample time 0.1 · 60 steps · commit 875fdbf564cf31a145283edf6a75dc1d64d1090a · produced by docsSample --out <folder> --blocks Wigner_Ville_Distribution Cross_Wigner_Ville_Distribution Inverse_STFT Fourier_Synchrosqueezed_Transform Time_Frequency_Ridges Frequency_Domain_Filter_Identification Fill_Gaps EOM_6DOF_ECEF_Quaternion EOM_6DOF_Custom_Variable_Mass_ECEF_Quaternion EOM_6DOF_Simple_Variable_Mass_ECEF_Quaternion ECI_To_ECEF_Rotation_Matrix ECI_Position_To_LLA LLA_To_ECI_Position ECI_Position_To_AER --steps 60 · data docs/generated/samples/Control_Systems__Resampling__Fill_Gaps.json · the SVG is generated from those numbers by tools/docs/plot_svg.py, so it is a run and not a drawing (R-D10).