Generated reference › Descriptor State Space — Control Systems/Continues
kind: generated#block#control-systems-continues

Descriptor State Space — Control Systems/Continues

E A B C D

Control_Systems/Continues/Descriptor_State_Space · 1 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.

Descriptor State Space

Control Systems / Continues

A continuous-time linear system in descriptor (generalized, implicit) form, where a mass matrix E multiplies the derivative:

E·dx/dt = A·x + B·u
y = C·x + D·u

with n states, m inputs and p outputs, so E and A are [n,n], B is [n,m], C is [p,n] and D is [p,m]. The block solves the mass matrix away once, and runs the equivalent explicit system dx/dt = (E\A)·x + (E\B)·u. With E = I it is exactly the State Space block.

Ports

  • Input – the input vector u, [m,1], sized from the B and D column count.
  • Output – the output vector y, [p,1], sized from C's row count.

Parameters

  • E – the mass matrix, [n,n]. It must be square and nonsingular; see the note below on why a singular E is refused rather than approximated.
  • A, B, C, D – the system matrices. Their dimensions must agree with each other, with E, and with the connected input; a mismatch stops the run with a message naming the block.
  • Initial State Vector – x at the start of the run, [n,1]. This is the state itself, not E·x.
  • 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. A deployable target runs a discrete model, so the export carries the reduced system discretized by the run's method, and the generated code matches the in-app simulation. E is solved away at export time – the generated core carries the reduced A and B as constants and performs no matrix inversion at run time, so a descriptor block costs a target exactly what a plain state space costs.

Simulink bridge

Import and export, mapped to simulink/Continuous/Descriptor State-Space. "E", "A", "B", "C" and "D" to E, A, B, C and D; "Initial State Vector" to InitialCondition – note the parameter is not called X0 here, as it is on the plain State-Space block. "Sampling Time (s)" does NOT cross: this Simulink block defines no SampleTime parameter, so the rate stays on the ICore side and an explicitly set one is reported rather than written. The solver-tuning parameters DirectFeedthrough, LinearizeToSparse, ParameterTunability, AbsoluteTolerance and ContinuousStateAttributes have no ICore counterpart and are left at their Simulink defaults.

Notes

  • Stateful and continuous: the solver integrates the reduced state between steps.
  • E must be nonsingular. With a singular E the system is a genuine differential-algebraic equation – part of the state is fixed by algebraic constraints instead of being integrated – and it needs a DAE solver. Simulink itself refuses ode4/ode45 on this block and demands ode15s, ode23t or ode14x. ICore's solver integrates ODEs, so a singular E is reported rather than quietly approximated into a system the user did not write.
  • Being linear, the reduced block is directly usable by the model reduction and linear-analysis commands.

Code facts#

FactValue
registered typeControl_Systems/Continues/Descriptor_State_Space
familyControl_Systems/Continues
solver environment classICoreBlock_0_Control_Systems_1_Continues_2_Descriptor_State_Space
sourcesrc/ICoreSDK/ICoreBlockLibrary/Blocks/Control_Systems/Continues/Descriptor_State_Space/ICoreBlock_0_Control_Systems_1_Continues_2_Descriptor_State_Space.cpp
headersrc/ICoreSDK/ICoreBlockLibrary/Blocks/Control_Systems/Continues/Descriptor_State_Space/ICoreBlock_0_Control_Systems_1_Continues_2_Descriptor_State_Space.h
default size on canvas140 × 90 px
ports at insert1 in, 1 out
code generators implementedPython, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text

Ports#

#DirectionSignal typeDescription label
1inICoreDouble
2outICoreDouble

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
E[1 0; 0 1]E
A[0 1;-1 -1]A
B[0; 1]B
C[1 0]C
D[0]D
Initial State Vector[0; 0]InitialCondition

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::Both
Simulink pathsimulink/Continuous/Descriptor State-Space
port-count rulePortsParam::None
SampleTime parameterno — the counterpart defines none; the rate stays on the ICore side
ICore configSimulink parameterValue translation
EEpasses through
AApasses through
BBpasses through
CCpasses through
DDpasses through
Initial State VectorInitialConditionpasses through

Caveat (shown to the user): the block runs at the surrounding Simulink rate; "Sampling Time (s)" does not cross. ICore requires a nonsingular E and integrates the reduced explicit system, so a singular E - a true DAE, which Simulink runs only under ode15s/ode23t/ode14x - does not cross either and is reported instead

Catalog contract: src/ICoreSDK/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).

Descriptor State Space block — E*dx/dt = A*x + B*u, y = C*x + D*u The descriptor (generalized / implicit) form puts a mass matrix E in front of the derivative. ICore carries it as the EXPLICIT system it is equivalent to whenever E is invertible: dx/dt = (E\A) x + (E\B) u, y = C x + D u and everything downstream — the RK solver, discretization, model reduction, all ten code generators — sees only that explicit pair. E is reduced away exactly once, in loadBlockConfig(), so no target ever has to carry a matrix solve.

WHY E MUST BE NONSINGULAR. With singular E the system is a true differential-ALGEBRAIC equation: part of the state is pinned by algebraic constraints rather than integrated, and it needs a DAE solver (Simulink itself refuses ode4/ode45 on this block and demands ode15s/ode23t/ode14x). ICore's solver integrates ODEs, so a singular E is REPORTED at verifyInitializedPortSignals() rather than silently producing a system that is not the one the user wrote. With E = I the block is exactly the plain State Space block.

Verified against Simulink R2026a: the descriptor block under ode14x and a State-Space block carrying E\A and E\B under the same solver agree to 1.5e-14 over a 500-sample run, which is what licenses the reduction above.

Simulation: identical to the plain State Space block once reduced — compute_f/compute_h run the products on the continuous SS, the discrete pair runs them on the discretized SS.

Code export: targets cannot integrate an ODE, so every generator realizes the DISCRETIZED recursion y[k] = C x[k] + D u[k], x[k+1] = A x[k] + B u[k] with A,B already the reduced and discretized pair. See ssDiscreteExport() and the per-language sections below.

Sample results#

Descriptor State Space — Step: 0 -> 1 at t = 1 sDescriptor State Space — Step: 0 -> 1 at t = 1 s00.51012345t (s)in ICoreDouble-Out-0out ICoreDouble-Out-0

The same rig also ran:

StimulusWhat it isOutput range
impulseImpulse: one sample of 1 at k = 5, 0 elsewhere (Repeating Sequence Stair)-0.008893 … 0.05458
rampRamp: slope 1 from t = 00 … 4.847
sineSine Wave: amplitude 1, 2 rad/s, no phase, no bias-0.3041 … 0.4966
tableRepeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample-0.162 … 0.4821

Plotted: step — Step: 0 -> 1 at t = 1 s

Category dynamic · sample time 0.1 · 60 steps · commit ccf005c8 · produced by docsSample --out <folder> --steps 60 · data docs/generated/samples/Control_Systems__Continues__Descriptor_State_Space.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).