Generated reference › Input Domain Monitor — Machine Learning/Anomaly Detection
kind: generated#block#machine-learning-anomaly-detection

Input Domain Monitor — Machine Learning/Anomaly Detection

Machine_Learning/Anomaly_Detection/Input_Domain_Monitor · 1 input / 3 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.

Input Domain Monitor

Machine Learning / Anomaly Detection

Reports how far the current input sits outside the envelope the model was fitted on. For each feature, with lo and hi the fitted bounds:

eᵢ = max(0, loᵢ − uᵢ, uᵢ − hiᵢ) · invᵢ

and the three outputs are the fraction of features outside their range, the largest excursion, and which feature produced it. A model is only trustworthy inside the region its training data covered; this is the cheapest guard there is against one being asked to extrapolate, and it needs no fitted object at all – just two columns any training run can report.

It is not Check Static Range, which asserts on one scalar bound and stops the run. This block scores a whole vector and keeps going, so a controller can weigh the answer rather than being halted by it.

Ports

  • u – the feature vector, a column [m,1] matching the height of Feature Minimum.
  • frac – a scalar [1,1] in [0,1]: how many features are outside their range, divided by m. 0 means fully inside the fitted domain.
  • excess – a scalar [1,1]: the largest single excursion, 0 when every feature is inside. Under Relative to range it reads as a fraction of the fitted span, so 0.5 means "half a training range beyond the edge".
  • idx – a scalar [1,1]: which feature that was, plus Index Base. It is only meaningful when excess > 0 – with every feature inside, all excursions are 0 and the scan reports the first feature. Gate on excess or frac, not on this.

Parameters

  • Feature Minimum – an [m,1] column: the lowest value of each feature over the training set. Its height sets m and therefore the expected input size.
  • Feature Maximum – an [m,1] column, the highest value of each feature. Entry by entry it must not sit below Feature Minimum, and under Relative to range it must sit strictly above it.
  • Excursion Scaling – what an excursion is measured in:
    • Relative to range – divided by (hi − lo), so features in different units are comparable and excess is dimensionless. The default, and what makes idx meaningful across a mixed feature vector.
    • Absolute – in the feature's own units, for a vector whose features already share a scale.
  • Index Base – what the first feature is called: Zero-based (PyTorch, numpy) or One-based (MATLAB). It shifts idx and nothing else. The same parameter, with the same two settings, as Argmax Decision.
  • 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. Both envelopes, the range reciprocals and 1/m are baked into the body at export time; there is no tunable parameter.

The three HDL targets are genuine synthesizable Q16.16: the reciprocals are folded at config load, so the datapath multiplies rather than divides and carries no transcendental. Every feature is unrolled with its own literals, so no backend needs a table or a bounds check.

Simulink bridge

None. Nothing in the installed libraries scores a vector against a fitted envelope: Check Static Range asserts on a scalar and halts, and the model-monitoring blocks that would compare belong to the Statistics and Machine Learning Toolbox, which is not installed on this machine. The bridge reports the block rather than dropping it silently, and it has no parity testbench, which is the documented consequence of Support::None rather than a gap. Code export verification still covers it across all ten languages, in both scaling modes.

Notes

  • Algebraic and stateless: the outputs depend only on the current input.
  • Ties go to the lowest index, the same rule Argmax Decision uses – the scan replaces its best only on a strictly greater excursion.
  • Nonlinear and partly discontinuous, and deliberately carries no state space: frac and idx step rather than vary, so no A/B/C/D describes the block and model reduction correctly refuses it.
  • The three HDL targets can rank two near-equal excursions differently, for the reason Argmax Decision documents: they compare Q16.16 values, one quantum of which is about 1.5e-5, where the in-app run compares doubles. That moves idx by a whole feature while excess moves by a rounding error. It is inherent to reducing a continuous quantity to a discrete choice in fixed point.
  • An envelope is not a certificate. Being inside the per-feature ranges does not put a sample inside the training distribution – a combination never seen can still lie within every individual range. Pair this with Mahalanobis Distance, which sees the correlations this block cannot.

Code facts#

FactValue
registered typeMachine_Learning/Anomaly_Detection/Input_Domain_Monitor
familyMachine_Learning/Anomaly_Detection
solver environment classICoreBlock_0_Machine_Learning_1_Anomaly_Detection_2_Input_Domain_Monitor
sourcesrc/ICoreSDK/ICoreBlockLibrary/Blocks/Machine_Learning/Anomaly_Detection/Input_Domain_Monitor/ICoreBlock_0_Machine_Learning_1_Anomaly_Detection_2_Input_Domain_Monitor.cpp
headersrc/ICoreSDK/ICoreBlockLibrary/Blocks/Machine_Learning/Anomaly_Detection/Input_Domain_Monitor/ICoreBlock_0_Machine_Learning_1_Anomaly_Detection_2_Input_Domain_Monitor.h
default size on canvas140 × 90 px
ports at insert1 in, 3 out
code generators implementedPython, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text

Ports#

#DirectionSignal typeDescription label
1inICoreDoubleu
2outICoreDoublefrac
3outICoreDoubleexcess
4outICoreDoubleidx

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 variableDefaultSimulink parameter
Feature Minimum[-1; -1; -1]
Feature Maximum[1; 1; 1]
Excursion ScalingRelative to range%~%Absolute~~Relative to range
Index BaseZero-based (PyTorch, numpy)%~%One-based (MATLAB)~~Zero-ba…

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.

supportSupport::None
Simulink path
port-count rulePortsParam::None
SampleTime parameteryes

Caveat (shown to the user): no Simulink equivalent available here: Check Static Range asserts on a scalar bound and halts the run rather than scoring a vector, and the model-monitoring blocks that would compare belong to the Statistics and Machine Learning Toolbox, which is not installed on this machine. 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:

  • B0 every 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).

Input Domain Monitor — is the model being asked to extrapolate? e[i] = max(0, lo[i] - u[i], u[i] - hi[i]) * inv[i] frac = (number of e[i] > 0) / m excess = max e[i] idx = argmax e[i] + base

Three decisions carry this block, and each one is why a column of the export matrix is green rather than merely present:

  1. THE RECIPROCALS ARE FOLDED AT CONFIG LOAD -- inv[i] = 1/(hi[i]-lo[i]) and 1/m -- so the

emitted body multiplies where the obvious spelling would divide. That is Standard_Scaler's move, and it is what keeps the three HDL targets genuine synthesizable Q16.16 instead of the simulation-only real path a per-sample divider would force.

  1. THE TIE RULE IS Argmax_Decision's, to the operator: strictly greater, scanning up, so the

LOWEST index wins. Copied on purpose rather than re-decided -- a diagram holding both blocks must not be able to get two different answers to "which feature".

  1. THE SCALING IS A MODE, not a flag read at run time. Relative emits a multiply per feature

and Absolute emits none, so they are genuinely different bodies in all ten languages, and each gets a rig row of its own.

⚠ Every unrolled feature is emitted with its OWN literals. There is no loop and no constant table in any backend, so nothing needs an index type, a bounds check, or a memory.

Sample results#

No stimulus produced a sampled output in this rig — Invalid input size at: ICore Blocks/Home/Input Domain Monitor. 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__Anomaly_Detection__Input_Domain_Monitor.json