Generated reference › Gaussian Mixture Model — Machine Learning/Classical Models
kind: generated#block#machine-learning-classical-models

Gaussian Mixture Model — Machine Learning/Classical Models

Machine_Learning/Classical_Models/Gaussian_Mixture_Model · 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.

Gaussian Mixture Model

Machine Learning / Classical Models

A fitted Gaussian mixture, evaluated one sample at a time. Each component scores the sample by its own full-covariance Gaussian:

logp[k] = log(w[k]) − ½·d·log(2π) + ½log(det Sinv[k]) − ½·(u − mu[k])'· Sinv[k]·(u − mu[k])

This is sklearn.mixture.GaussianMixture with weights_, means_ and precisions_ pasted in. It is Gaussian Naive Bayes with a full covariance: that block's per-feature variances make the quadratic form diagonal, and carrying the off-diagonal terms is exactly the difference between "naive" and a mixture component.

Use it as a soft clustering (which component does this sample belong to, and how strongly) or as a density model (how likely is this sample at all, which is what makes a mixture a novelty detector).

Ports

  • u – the sample, a [d,1] column, d being the number of COLUMNS of Component Means.
  • idx[1,1], the winning component, plus Index Base. It is always present, whatever Output is set to.
  • p[K,1], one entry per component: either their log-likelihoods or their responsibilities, per Output. K is the number of ROWS of Component Means.

Parameters

  • Component Meansmu, a [K,d] matrix, one component per ROW: sklearn's means_ orientation. Its shape decides both K and d.
  • Inverse Covariances – the precision matrices, STACKED VERTICALLY as [K·d, d]: component k occupies rows k·d to k·d+d−1. A configuration matrix is 2-D, so a [K,d,d] tensor needs a flattening convention and this is it. From sklearn, numpy.vstack(gm.precisions_) produces exactly this layout. Each block must be symmetric and positive definite – both are checked, because a transposed or mis-stacked paste is otherwise a silently different model.
  • Component Weights[K,1], sklearn's weights_. Every entry must be greater than zero.
  • Output – what the p port carries. The two are different code paths rather than a scaling, so each is verified as its own mode:
    • Log Likelihood – the raw per-component log-likelihoods, in component order. Their differences are what matter; the winner's own value is p[idx]. This is the mode to use for novelty scoring.
    • Responsibility – the posterior probability of each component, non-negative and summing to one: the E-step of the algorithm that fitted the model. This is the mode to use for soft clustering.
  • Index Base – what the first component is numbered, spelled exactly as Argmax Decision, K Means Assign and both Naive Bayes blocks spell it:
    • Zero-based (PyTorch, numpy) – the first component is 0.
    • One-based (MATLAB) – the first component is 1.
  • 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. Every component's quadratic form is unrolled at export time, and the constant baked in front of it is the FOLDED one: the log weight, the d/2 log(2π) and the half log-determinant together, computed once when the configuration loads. No logarithm and no determinant reaches the generated code.

The two modes differ in the HDL targets: Log Likelihood is genuine synthesizable Q16.16 – a subtract, two multiplies and an add per term, then a comparison chain. Responsibility exponentiates and divides by a sum that depends on the sample, neither of which belongs in a Q16.16 datapath, so the three HDL targets carry that mode in simulation-only real arithmetic.

In that mode the HDL cores also exponentiate the quantized log-likelihood, since the scores pass through the fixed-point output vector on their way; the difference is about one quantum in the exponent and stays far inside the verification band.

Simulink bridge

None. Simulink's mixture and clustering blocks live in the Statistics and Machine Learning Toolbox, which is not installed on this machine, so there is nothing here to map onto and a bridge could not be verified even if it were written. Those blocks also take a fitted model OBJECT rather than parameter matrices. The block therefore has no parity testbench, which is the documented consequence of Support::None.

Notes

  • Stateless and algebraic.
  • The maximum is subtracted before exponentiating, exactly as Softmax does and for the same reason: a component log-likelihood of −40 is entirely ordinary, and exp(−40) underflows to zero in single precision and in Q16.16 alike. Subtracting the winner makes the largest term exactly 1 and costs nothing, since the winner has already been found for the idx port.
  • Ties go to the LOWEST component indexArgmax Decision's rule, spelled identically in every backend.
  • The index is a DISCONTINUOUS function of the input, so the three HDL targets can rank two near-equal components the other way round; one Q16.16 quantum is about 1.5×10−5. The p output is continuous and does not have that property.
  • No matrix is inverted here. The precisions are configuration, as they are for Mahalanobis Distance – no block body inverts a matrix, and sklearn hands you precisions_ already.
  • For a single component this block is a log-density, and Mahalanobis Distance is the same quadratic form without the normalizer. For a DIAGONAL covariance use Gaussian Naive Bayes, which carries d terms instead of d².

Code facts#

FactValue
registered typeMachine_Learning/Classical_Models/Gaussian_Mixture_Model
familyMachine_Learning/Classical_Models
solver environment classICoreBlock_0_Machine_Learning_1_Classical_Models_2_Gaussian_Mixture_Model
sourcesrc/ICoreSDK/ICoreBlockLibrary/Blocks/Machine_Learning/Classical_Models/Gaussian_Mixture_Model/ICoreBlock_0_Machine_Learning_1_Classical_Models_2_Gaussian_Mixture_Model.cpp
headersrc/ICoreSDK/ICoreBlockLibrary/Blocks/Machine_Learning/Classical_Models/Gaussian_Mixture_Model/ICoreBlock_0_Machine_Learning_1_Classical_Models_2_Gaussian_Mixture_Model.h
default size on canvas138 × 90 px
ports at insert1 in, 2 out
code generators implementedPython, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text

Ports#

#DirectionSignal typeDescription label
1inICoreDoubleu
2outICoreDoubleidx
3outICoreDoublep

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
Component Means[-0.5 0.3; 0.8 -0.2]
Inverse Covariances[2.5 0.6; 0.6 1.8; 1.4 -0.5; -0.5 2.2]
Component Weights[0.6; 0.4]
OutputLog Likelihood%~%Responsibility~~Log Likelihood
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: its mixture and clustering blocks live in the Statistics and Machine Learning Toolbox, which is not installed on this machine, so no mapping could be verified; and those blocks take a fitted model OBJECT rather than the parameter matrices this block configures

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).

Gaussian Mixture Model — a fitted GaussianMixture evaluated at inference logp[k] = c[k] + SUM_a SUM_b W[k][a][b] * e[a] * e[b] e[a] = u[a] - mu[k][a] r[k] = exp(logp[k] - best) / SUM_j exp(logp[j] - best) best = max_j logp[j] idx = argmax_k logp[k] + base

Read the header before this file: it records the [K*d,d] stacking convention for the inverse covariances, the fold (log weights AND the determinant, at config load), why the argmax is a PORT rather than the third mode the board row asked for, and the per-mode HDL split.

⚠ ONE EMISSION SHAPE FOR ALL TEN BACKENDS: write each component's score into the output vector, scan those elements for the winner, and -- in Responsibility mode -- re-read them to exponentiate and normalize. That needs only two scratch values beyond the output itself, which is what lets VHDL (whose entire scratch is acc and acc2) spell the same algorithm as Python.

Sample results#

No stimulus produced a sampled output in this rig — Invalid input size at: ICore Blocks/Home/Gaussian Mixture Model. 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__Classical_Models__Gaussian_Mixture_Model.json