Missing Value Imputer — Machine Learning/Preprocessing
Machine_Learning/Preprocessing/Missing_Value_Imputer · 1 input / 2 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.
Missing Value Imputer
Machine Learning / Preprocessing
Replaces every entry of a feature column that carries the missing marker with a fitted value:
yi = filli when |ui − marker| ≤ tol, otherwise yi = ui.
This is SimpleImputer.transform with statistics_
pasted in. It belongs in front of every scaler in this family: a sentinel like
−999 arriving at Standard Scaler does not merely give a wrong
feature, it gives a hugely wrong one, and nothing downstream can tell that apart
from a genuine extreme.
Ports
- u – the raw feature column, [m,1], matching the rows of Fill Values.
- y – the same column [m,1] with marked entries substituted. Everything else passes through untouched, bit for bit.
- count – a scalar [1,1]: how many entries were substituted this sample. Worth watching – a rate that climbs is a sensor failing, and it is invisible once the values have been filled in.
Parameters
- Fill Values – the [m,1] column substituted per feature,
which is sklearn's
statistics_. Whether it was fitted as a mean, a median or a constant makes no difference here: all three are one baked number per feature at inference time, which is why there is deliberately no Strategy setting to disagree with the numbers pasted beside it. It is also the only source of m. - Missing Marker – the sentinel value that means "absent". −999 by default.
- Marker Tolerance – half-width of the band treated as the marker. It exists because the marker travels through the same finite-precision path as the data; keep it far smaller than the gap between the marker and any real reading.
- 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. The fill column, the marker and the tolerance are baked into the body at export time.
The three HDL targets are genuine synthesizable Q16.16: the
whole block is comparisons, selections and one running count, with no division
and no transcendental. The test is emitted as two comparisons rather than an
absolute value, so no backend needs an abs function.
Simulink bridge
None. Imputation belongs to the Statistics and Machine Learning
Toolbox, which is not installed here, and its interface fills a workspace matrix
rather than a signal – there is no per-sample block whose parameters this
one could map onto. The bridge reports it rather than dropping it silently, and
it has no parity testbench, which is the documented consequence of
Support::None rather than a gap.
Notes
- Algebraic and stateless: each sample is treated independently.
- ⚠ The marker is a configured sentinel, never NaN, and that is forced rather than preferred: Q16.16 has no NaN – there is no bit pattern to test for – so a block keyed on it would work in the six software backends and be silently unimplementable in the three HDL ones. If your data arrives with NaN, map it to the marker upstream.
- Non-marked entries pass through untouched, not re-quantized or rounded, so putting this block in a path costs nothing when nothing is missing.
- A marker that a real reading can reach is a bug in the configuration, not in the block: it will impute perfectly good data and no diagnostic can spot it. Choose one outside the sensor's physical range.
Code facts#
| Fact | Value |
|---|---|
| registered type | Machine_Learning/Preprocessing/Missing_Value_Imputer |
| family | Machine_Learning/Preprocessing |
| solver environment class | ICoreBlock_0_Machine_Learning_1_Preprocessing_2_Missing_Value_Imputer |
| source | src/ICoreSDK/ICoreBlockLibrary/Blocks/Machine_Learning/Preprocessing/Missing_Value_Imputer/ICoreBlock_0_Machine_Learning_1_Preprocessing_2_Missing_Value_Imputer.cpp |
| header | src/ICoreSDK/ICoreBlockLibrary/Blocks/Machine_Learning/Preprocessing/Missing_Value_Imputer/ICoreBlock_0_Machine_Learning_1_Preprocessing_2_Missing_Value_Imputer.h |
| default size on canvas | 140 × 80 px |
| ports at insert | 1 in, 2 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 | u |
| 2 | out | ICoreDouble | y |
| 3 | out | ICoreDouble | count |
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 |
|---|---|---|
Fill Values | [0; 0; 0] | — |
Missing Marker | -999 | — |
Marker Tolerance | 1e-9 | — |
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): no Simulink equivalent available here: imputation belongs to the Statistics and Machine Learning Toolbox, which is not installed on this machine, and its interface fills a workspace MATRIX rather than a signal -- there is no per-sample block whose parameters this one could map onto. There is therefore no parameter set to map onto and no reference to run a parity testbench against
Catalog contract: src/ICoreSDK/ICoreCoder/ICoreCommandSystem/SimulinkBridge/ICoreSimulinkBlockCatalog.h
Description vs code#
The checker has a blind spot here — it could not resolve something (a grouped port bullet, a computed config name), which is reported and never counted as a pass. A reader has to settle it:
B0every stimulus in the sample errored — cross-checks skipped
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).
Missing Value Imputer — substitute a fitted value wherever the marker appears y_i = fill_i when |u_i - marker| <= tol, otherwise u_i n = count of those
The predicate is emitted as TWO COMPARISONS rather than an abs():
(u_i - marker <= tol) and (marker - u_i <= tol)
which needs no absolute-value function in any of the ten languages and stays exact in Q16.16. One_Hot_Encoder's emission shape with a different predicate.
⚠ NaN is deliberately NOT the marker -- see the header. Q16.16 has no NaN, so a block keyed on it would work in six backends and be unimplementable in three.
Sample results#
No stimulus produced a sampled output in this rig — Invalid input size at: ICore Blocks/Home/Missing Value Imputer. That is a fact about the single-block rig, not a verdict on the block: an offline batch fit, a block whose output only appears at onSolverFinish, or one that needs a driven environment cannot be exercised alone.
Category unsampled · sample time 0.1 · 60 steps · commit ccf005c8 · produced by docsSample --out <folder> --steps 60
Sample data: docs/generated/samples/Machine_Learning__Preprocessing__Missing_Value_Imputer.json