Generated reference › Pade Approximant — Control Systems/Polynomials
kind: generated#block#control-systems-polynomials

Pade Approximant — Control Systems/Polynomials

P(s) Q(s) e⁻ˢᵀ

Control_Systems/Polynomials/Pade_Approximant · 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.

Pade Approximant

Control Systems / Polynomials

Reports the [m/n] Padé approximant of a dead time e−sT as two coefficient vectors, with the delay T arriving on a port. In descending powers of s,

P(s) = Σk ak·(−T)k·sk and Q(s) = Σk bk·Tk·sk, where ak = (m+n−k)! m! / ((m+n)! k! (m−k)!) and bk is the same with n in place of m. At m = n = 1 that is the textbook (1 − Ts/2) / (1 + Ts/2).

It reports the coefficients; it does not delay anything. Wire the two outputs into Continuous / Transfer Function for the approximated delay itself. For a true dead time reach for Continuous / Transport Delay instead – the reason to approximate is to keep the model finite-dimensional, and so linearizable.

Ports

  • T – the dead time in seconds. Scalar. Zero is valid and gives the constant 1 on both sides; a negative value is accepted and describes a lead rather than a lag.
  • num – P's coefficients, descending powers of s, as a column of m + 1 entries.
  • den – Q's coefficients, descending, as a column of n + 1 entries.

Parameters

  • Numerator Order – m, a whole number from 0 to 8. The numerator then has m + 1 entries. Default 2.
  • Denominator Order – n, the same range; the denominator has n + 1 entries. Default 2. Equal orders are the usual choice and are what MATLAB's pade(T, N) produces; m < n gives a strictly proper approximation, which a state space needs.
  • 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 two orders are structural and are baked into the generated body – they decide how many coefficients exist – so nothing is exposed as a tunable parameter on the generated core.

Every emitted body raises T to one power at a time and scales it by an inlined constant, so no target divides, iterates or evaluates a factorial at run time. The three HDL targets are therefore genuine synthesizable Q16.16. Note that a high power of T there is formed by repeated multiplication in fixed point, so each power carries one more rounding than the last – at Q16.16 that is about 1.5×10−5 per step.

Simulink bridge

None (Support::None). pade is a MATLAB function, and the Symbolic Math Toolbox this block answers ships no Simulink library at all, so there is no library path a diagram could name. Simulink's own Transport Delay is a different thing – it delays a signal rather than reporting an approximation's coefficients – so mapping onto it would be wrong rather than partial. The bridge reports this block instead of dropping it silently, and it therefore has no parity testbench; code export verification still covers it across all ten languages. No configuration of it crosses either, including "Sampling Time (s)", which has no counterpart to be written to.

Notes

  • Algebraic, with no state: the output depends only on the current input.
  • The normalization is P(0) = Q(0) = 1, and MATLAB's is not. Control System Toolbox scales both polynomials so the leading coefficient is 1; this leaves the constant term at 1. They are the same transfer function – both sides carry the same factor. Measured at T = 1.3, m = n = 2: pade(1.3, 2) gives [1, −4.615384615384615, 7.1005917159763312] over [1, 4.615384615384615, 7.1005917159763312], and this block gives [0.14083333333333334, −0.65, 1] over [0.14083333333333334, 0.65, 1] – the same numbers divided by 0.14083333333333334 on both sides. The choice is deliberate: MATLAB's divisor is proportional to Tm and so runs to infinity as the delay approaches zero, which a block whose delay is a signal cannot afford.
  • A delay of zero is not a special case. Every power of T above the zeroth vanishes and both outputs become the constant 1, so the ratio is 1 – which is what e0 is. Nothing divides by T anywhere.
  • No state space: the map is a polynomial in the input rather than a linear one, so there is no A/B/C/D to merge and model reduction correctly declines it. The approximation has a state space; feed these coefficients to Transfer Function to get it.

Code facts#

FactValue
registered typeControl_Systems/Polynomials/Pade_Approximant
familyControl_Systems/Polynomials
solver environment classICoreBlock_0_Control_Systems_1_Polynomials_2_Pade_Approximant
sourcesrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Polynomials/Pade_Approximant/ICoreBlock_0_Control_Systems_1_Polynomials_2_Pade_Approximant.cpp
headersrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Polynomials/Pade_Approximant/ICoreBlock_0_Control_Systems_1_Polynomials_2_Pade_Approximant.h
default size on canvas122 × 80 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
1inICoreDoubleT
2outICoreDoublenum
3outICoreDoubleden

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
Numerator Order2—
Denominator Order2—

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): the Pade approximant of a dead time is a MATLAB function (pade), not a Simulink library block -- the Symbolic Math Toolbox this block answers ships no Simulink library at all -- and Simulink's Transport Delay is a different thing, delaying a signal rather than reporting an approximation's coefficients, so mapping onto it would be wrong rather than partial; the block is reported rather than dropped when a model crosses

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

Pade Approximant -- a dead time as a ratio of polynomials, with the dead time on a wire Every coefficient of the [m/n] approximant of exp(-sT) is a CONSTANT times a power of T:

P(s) = SUM(k) (m+n-k)! m! / ((m+n)! k! (m-k)!) * (-T)^k * s^k k = 0..m Q(s) = SUM(k) (m+n-k)! n! / ((m+n)! k! (n-k)!) * ( T)^k * s^k k = 0..n

The constants depend on the two ORDERS alone and are settled when the configuration is read; every target then multiplies a running power of T by them. No solve, no iteration and no division survives into a generated core, which is what makes this exportable to all ten targets and synthesizable in the three fixed-point ones.

⚠ THE RUNNING POWER IS SHARED BETWEEN THE TWO OUTPUTS AND BUILT ASCENDING. T^k is formed once per k and used by both polynomials, so the emitted body has one multiply per power rather than one per coefficient -- and it walks k UPWARDS while both outputs are written in DESCENDING order, which is why the two index expressions run opposite ways.

Verified against MATLAB R2026a rather than asserted. At T = 1.3, m = n = 2, pade(1.3, 2) returns [1, -4.615384615384615, 7.1005917159763312] over [1, 4.615384615384615, 7.1005917159763312]. This block returns [0.14083333333333334, -0.65, 1] over [0.14083333333333334, 0.65, 1] -- the same ratio, both sides divided by 0.14083333333333334. The normalization is different on purpose and the header says why: MATLAB's divides by a coefficient proportional to T^m, which is unbounded as the delay goes to zero.

Sample results#

Pade Approximant — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per samplePade Approximant — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample-202012345t (s)in ICoreDouble-Out-0out ICoreDouble-Out-0 [3x1] entry 0out ICoreDouble-Out-1 [3x1] entry 0
tin ICoreDouble-Out-0out ICoreDouble-Out-0 [3x1] entry 0out ICoreDouble-Out-1 [3x1] entry 0
0-2[0.3333, 1, 1][0.3333, -1, 1]
0.40.5[0.02083, -0.25, 1][0.02083, 0.25, 1]
0.8-2[0.3333, 1, 1][0.3333, -1, 1]
1.20.5[0.02083, -0.25, 1][0.02083, 0.25, 1]
1.6-2[0.3333, 1, 1][0.3333, -1, 1]
20.5[0.02083, -0.25, 1][0.02083, 0.25, 1]
2.4-2[0.3333, 1, 1][0.3333, -1, 1]
2.80.5[0.02083, -0.25, 1][0.02083, 0.25, 1]
3.2-2[0.3333, 1, 1][0.3333, -1, 1]
3.60.5[0.02083, -0.25, 1][0.02083, 0.25, 1]
4-2[0.3333, 1, 1][0.3333, -1, 1]
4.40.5[0.02083, -0.25, 1][0.02083, 0.25, 1]
4.8-2[0.3333, 1, 1][0.3333, -1, 1]
5.20.5[0.02083, -0.25, 1][0.02083, 0.25, 1]

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)0 … 0.08333
rampRamp: slope 1 from t = 00 … 2.803
sineSine Wave: amplitude 1, 2 rad/s, no phase, no bias0 … 0.08333
stepStep: 0 -> 1 at t = 1 s0 … 0.08333

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 ba0d5f47abbf16b9e248ecce5a0d14210ec2f9d7 · produced by docsSample --out <folder> --blocks Polynomial_Coefficients Characteristic_Polynomial Pade_Approximant --steps 60 · data docs/generated/samples/Control_Systems__Polynomials__Pade_Approximant.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).