Generated reference › Incremental Classification ECOC Fit — Machine Learning/Incremental Learning
kind: generated#block#machine-learning-incremental-learning

Incremental Classification ECOC Fit — Machine Learning/Incremental Learning

+ - - +

Machine_Learning/Incremental_Learning/Incremental_Classification_ECOC_Fit · 2 input / 1 output port(s) at insert · exports to Python, MATLAB, Java, Rust, C, C++

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.

Incremental Classification ECOC Fit

Machine Learning / Incremental Learning

Fits a K-class classifier online from L binary linear classifiers (error-correcting output codes), and puts the model on a bus every step. Column l of the coding matrix M [K,L] says which classes learner l calls positive (+1), negative (−1) or ignores (0); each step the rows of x are relabelled for each learner in turn and fitted by MATLAB's scale-invariant solver on the hinge loss, as Simulink's IncrementalClassificationECOC Fit block runs it. Feed the bus to an Incremental Classification ECOC Predict block.

Ports

  • x – n observations of the P predictors, a matrix [n,P]: one row per observation. P and n are read off its size.
  • y – their labels, [n,1], each one of the Class Names. A label that is not a class name keeps that row's class from the previous step, as Simulink's block does.
  • mdl (bus) – the model after this step, a bus of nine elements in Simulink's order: AllBeta [P,L] and AllBias [L,1], the learners' coefficients; AllMu and AllSigma [P,L], the standardization each used (0 and 1 without it); AllMajorityClass (u8) [L,1], 1 or 2, the side each learner has seen more of; AllCanPredict (bool) [L,1]; IsWarm (bool); MajorityClass (u16), the index of the most frequent class so far; and SeenBothClasses (bool) [L,1].

Parameters

  • Class Names – the K labels, [1 2 3] by default, two or more different numbers.
  • Coding – the coding design:
    • onevsone (the default) – one learner per pair of classes, in MATLAB's order (1 against 2, 1 against 3, …, 2 against 3, …), the first of the pair positive;
    • onevsall – one learner per class, that class against the rest;
    • custom – the Coding Matrix.
  • Coding Matrix – a K-by-L matrix of −1, 0 and +1, read when Coding is custom; every column needs a +1 and a −1.
  • Standardize – off (the default) or on: center and scale each predictor by its mean and standard deviation over the estimation period.
  • Estimation Period – how many observations the standardization is estimated from, 1000 by default; it applies only with Standardize on. A batch that would run past it is not used for estimation: the period is declared full and the batch trains, as Simulink's block does.
  • Metrics Warmup Period – how many observations make the model warm (IsWarm), 1000 by default, counted from the first.
  • Shuffle – on (the default) or off: the order each learner trains on a step's rows, sorted by draws of MATLAB's twister seeded 5489 at the start of the run, as the Simulink block's private stream is.
  • Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period.

When a run is refused

Class Names that are not two or more different numbers, a coding matrix that is not K-by-L of −1, 0 and +1 with a +1 and a −1 in every column, a negative or fractional period, Standardize on with an Estimation Period of 0, and a y whose height is not x's.

Code export

Six targets: Python, MATLAB, Java, Rust, C and C++, each carrying the learner's whole state and the twister's, and running the same step as the live block in the same arithmetic order. The hardware targets (VHDL, Verilog, SystemVerilog) and PLC Structured Text carry no bus, so an export to one stops and names the block.

Simulink bridge

None. Simulink's block takes its learner as InitialLearner, the name of an incrementalClassificationECOC object in the MATLAB workspace, rather than as dialog parameters, so there is nothing in its dialog to map these configs onto or read them back from.

Notes

  • ⚠ The L learners are ONE learner. As in Simulink's block, a single linear learner is fitted L times a step, once per coding column, and AllBeta(:,l) is that learner after call l – learner 1 at the next step continues from learner L. Fitting L independent learners, as MATLAB's fit does, gives a different model (measured: 0.51 in Beta).
  • The bus at a step has already learnt that step's rows, as in Simulink.
  • Measured quirks kept: IsWarm counts every observation with no estimation offset; MajorityClass is the first index of the largest class count; SeenBothClasses looks at the last positive and the last negative class of each column; while a class's share is zero the binary learner drops its positive rows (Simulink's zero-prior filter); and standardization divides by a zero standard deviation unguarded, so a constant predictor turns Beta NaN for good – all as Simulink's block does.
  • Svm learners only (the hinge loss): Simulink's mask refuses a logistic template, so there is nothing to follow.
  • Any n of 1 or more: Simulink's block needs two rows or more, and this block gives the same answer whenever it runs.
  • Verified against R2026a: the learner, bookkeeping and decoding transcribed here matched Simulink's Fit and Predict blocks with max |diff| = 0 on every bus element over 23 runs (one-vs-one, one-vs-all and a ternary coding; 2, 3 and 4 rows a step; standardized with every estimation-period remainder; labels outside the class names; no shuffle), and the incremental_ecoc suite pins this block against those runs.

Code facts#

FactValue
registered typeMachine_Learning/Incremental_Learning/Incremental_Classification_ECOC_Fit
familyMachine_Learning/Incremental_Learning
solver environment classICoreBlock_0_Machine_Learning_1_Incremental_Learning_2_Incremental_Classification_ECOC_Fit
sourcesrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Machine_Learning/Incremental_Learning/Incremental_Classification_ECOC_Fit/ICoreBlock_0_Machine_Learning_1_Incremental_Learning_2_Incremental_Classification_ECOC_Fit.cpp
headersrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Machine_Learning/Incremental_Learning/Incremental_Classification_ECOC_Fit/ICoreBlock_0_Machine_Learning_1_Incremental_Learning_2_Incremental_Classification_ECOC_Fit.h
default size on canvas170 × 80 px
ports at insert2 in, 1 out
code generators implementedPython, MATLAB, Java, Rust, C, C++

Ports#

#DirectionSignal typeDescription label
1inICoreDoublex
2inICoreDoubley
3outICoreBusmdl

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
Class Names[1 2 3]—
Codingonevsone%~%onevsall%~%custom~~onevsone—
Coding Matrix[1 1 0; -1 0 1; 0 -1 -1]—
Standardizeoff%~%on~~off—
Estimation Period1000—
Metrics Warmup Period1000—
Shuffleon%~%off~~on—

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 pathstatsIncremental/Classification/ECOC/IncrementalClassificationECOC Fit
port-count rulePortsParam::None
SampleTime parameteryes

Caveat (shown to the user): no bridge: Simulink's IncrementalClassificationECOC Fit block takes its learner as InitialLearner, the NAME of an incrementalClassificationECOC object in the MATLAB workspace, not as dialog parameters -- there is nothing in its dialog to map the learner configs onto, or read them back from

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

IncrementalClassificationECOC Fit -- K classes from L binary linear learners, fitted online, the model on a bus statsIncremental/Classification/ECOC/IncrementalClassificationECOC Fit, MEASURED on R2026a 2026-10-03 (BLOCKS_TO_ADD_TOOLBOXES.md statsIncremental, on FEATURES_TO_ADD.md BF1). Simulink's block takes its learner as InitialLearner, the name of an incrementalClassificationECOC object in the MATLAB workspace; here the learner's options are configs: Class Names, the Coding (one-vs-one, one-vs-all or a matrix of your own), Standardize, Estimation Period, Metrics Warmup Period and Shuffle. P is x's width and n, the rows a step, its height.

The arithmetic and the measured behaviour -- ONE learner shared by all L binary problems, each step's L calls of it on the batch in a shuffled row order from a private MT19937, the per-call bookkeeping, the unguarded standardization -- are ICoreIncrementalEcocSupport's, which followed the Simulink block with max |diff| = 0 on every bus element over 23 runs.

A label that is not a class name keeps that row's class from the previous step, as the Simulink block does (0 -- no class -- on the first step).

Sample results#

Incremental Classification ECOC Fit — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sampleIncremental Classification ECOC Fit — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample-202012345t (s)in ICoreDouble-Out-0in ICoreDouble-Out-0

This block carries a ICoreBus signal, whose value is text rather than a number and is not something a plot has an axis for. The samples are in the table below, exactly as the run recorded them.

tin ICoreDouble-Out-0in ICoreDouble-Out-0out ICoreBus-Out-0
0-2-2{'AllBeta': [0, 0, 0], 'AllBias': [0, 0, 0], 'AllMu': [0, 0, 0], 'AllSigma': [1, 1, 1], 'AllMajorityClass': [2, 2, 2], 'AllCanPredict': [1, 1, 1], 'IsWarm': 0, 'MajorityClass': 1, 'SeenBothClasses': [0, 0, 0]}
0.40.50.5{'AllBeta': [0, 0, 0], 'AllBias': [0, 0, 0], 'AllMu': [0, 0, 0], 'AllSigma': [1, 1, 1], 'AllMajorityClass': [2, 2, 2], 'AllCanPredict': [1, 1, 1], 'IsWarm': 0, 'MajorityClass': 1, 'SeenBothClasses': [0, 0, 0]}
0.8-2-2{'AllBeta': [-0.04444444444, -0.04444444444, -0.04444444444], 'AllBias': [0, 0, 0], 'AllMu': [0, 0, 0], 'AllSigma': [1, 1, 1], 'AllMajorityClass': [2, 2, 2], 'AllCanPredict': [1, 1, 1], 'IsWarm': 0, 'MajorityClass': 3, 'SeenBothClasses': [0, 0, 0]}
1.20.50.5{'AllBeta': [-0.04444444444, -0.04444444444, -0.04444444444], 'AllBias': [0, 0, 0], 'AllMu': [0, 0, 0], 'AllSigma': [1, 1, 1], 'AllMajorityClass': [2, 2, 2], 'AllCanPredict': [1, 1, 1], 'IsWarm': 0, 'MajorityClass': 3, 'SeenBothClasses': [0, 0, 0]}
1.6-2-2{'AllBeta': [0.01665702718, 0.01665702718, 0.01665702718], 'AllBias': [0.1151177576, 0.1151177576, 0.1151177576], 'AllMu': [0, 0, 0], 'AllSigma': [1, 1, 1], 'AllMajorityClass': [2, 2, 2], 'AllCanPredict': [1, 1, 1], 'IsWarm': 0, 'MajorityClass': 3, 'SeenBothClasses': [0, 0, 0]}
20.50.5{'AllBeta': [0.01665702718, 0.01665702718, 0.01665702718], 'AllBias': [0.1151177576, 0.1151177576, 0.1151177576], 'AllMu': [0, 0, 0], 'AllSigma': [1, 1, 1], 'AllMajorityClass': [2, 2, 2], 'AllCanPredict': [1, 1, 1], 'IsWarm': 0, 'MajorityClass': 3, 'SeenBothClasses': [0, 0, 0]}
2.4-2-2{'AllBeta': [0.03181567111, 0.03181567111, 0.03181567111], 'AllBias': [0.160472333, 0.160472333, 0.160472333], 'AllMu': [0, 0, 0], 'AllSigma': [1, 1, 1], 'AllMajorityClass': [2, 2, 2], 'AllCanPredict': [1, 1, 1], 'IsWarm': 0, 'MajorityClass': 3, 'SeenBothClasses': [0, 0, 0]}
2.80.50.5{'AllBeta': [0.03181567111, 0.03181567111, 0.03181567111], 'AllBias': [0.160472333, 0.160472333, 0.160472333], 'AllMu': [0, 0, 0], 'AllSigma': [1, 1, 1], 'AllMajorityClass': [2, 2, 2], 'AllCanPredict': [1, 1, 1], 'IsWarm': 0, 'MajorityClass': 3, 'SeenBothClasses': [0, 0, 0]}
3.2-2-2{'AllBeta': [0.04222834665, 0.04222834665, 0.04222834665], 'AllBias': [0.1785217182, 0.1785217182, 0.1785217182], 'AllMu': [0, 0, 0], 'AllSigma': [1, 1, 1], 'AllMajorityClass': [2, 2, 2], 'AllCanPredict': [1, 1, 1], 'IsWarm': 0, 'MajorityClass': 3, 'SeenBothClasses': [0, 0, 0]}
3.60.50.5{'AllBeta': [0.04222834665, 0.04222834665, 0.04222834665], 'AllBias': [0.1785217182, 0.1785217182, 0.1785217182], 'AllMu': [0, 0, 0], 'AllSigma': [1, 1, 1], 'AllMajorityClass': [2, 2, 2], 'AllCanPredict': [1, 1, 1], 'IsWarm': 0, 'MajorityClass': 3, 'SeenBothClasses': [0, 0, 0]}
4-2-2{'AllBeta': [0.0522824452, 0.0522824452, 0.0522824452], 'AllBias': [0.199294742, 0.199294742, 0.199294742], 'AllMu': [0, 0, 0], 'AllSigma': [1, 1, 1], 'AllMajorityClass': [2, 2, 2], 'AllCanPredict': [1, 1, 1], 'IsWarm': 0, 'MajorityClass': 3, 'SeenBothClasses': [0, 0, 0]}
4.40.50.5{'AllBeta': [0.0522824452, 0.0522824452, 0.0522824452], 'AllBias': [0.199294742, 0.199294742, 0.199294742], 'AllMu': [0, 0, 0], 'AllSigma': [1, 1, 1], 'AllMajorityClass': [2, 2, 2], 'AllCanPredict': [1, 1, 1], 'IsWarm': 0, 'MajorityClass': 3, 'SeenBothClasses': [0, 0, 0]}
4.8-2-2{'AllBeta': [0.05377150527, 0.05377150527, 0.05377150527], 'AllBias': [0.2224425007, 0.2224425007, 0.2224425007], 'AllMu': [0, 0, 0], 'AllSigma': [1, 1, 1], 'AllMajorityClass': [2, 2, 2], 'AllCanPredict': [1, 1, 1], 'IsWarm': 0, 'MajorityClass': 3, 'SeenBothClasses': [0, 0, 0]}
5.20.50.5{'AllBeta': [0.05377150527, 0.05377150527, 0.05377150527], 'AllBias': [0.2224425007, 0.2224425007, 0.2224425007], 'AllMu': [0, 0, 0], 'AllSigma': [1, 1, 1], 'AllMajorityClass': [2, 2, 2], 'AllCanPredict': [1, 1, 1], 'IsWarm': 0, 'MajorityClass': 3, 'SeenBothClasses': [0, 0, 0]}

Every 4th of 60 samples, from the table stimulus.

The same rig also ran:

StimulusWhat it isOutput range
impulseImpulse: one sample of 1 at k = 5, 0 elsewhere (Repeating Sequence Stair)—
rampRamp: slope 1 from t = 0—
sineSine Wave: amplitude 1, 2 rad/s, no phase, no bias—
stepStep: 0 -> 1 at t = 1 s—

Plotted: table — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample

Category static · sample time 0.1 · 60 steps · commit 6e08e972e · produced by docsSample --out <folder> --blocks Incremental_Classification_ECOC_Fit Incremental_Classification_ECOC_Predict --steps 60 · data docs/generated/samples/Machine_Learning__Incremental_Learning__Incremental_Classification_ECOC_Fit.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).