Generated reference › Detrend — Control Systems/Signal Smoothing
kind: generated#block#control-systems-signal-smoothing

Detrend — Control Systems/Signal Smoothing

Control_Systems/Signal_Smoothing/Detrend · 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.

Detrend

Control Systems / Signal Smoothing

Removes the trend from a stream: it fits a least-squares constant or least-squares straight line to the last N samples and outputs what the newest sample has left over after that fit is subtracted – y = u − fit(u), the streaming counterpart of MATLAB's detrend.

The residual of a least-squares fit is a linear function of the window, so the block is one FIR filter: N weights, derived once from the two parameters, applied to a shift register. In constant mode the weights are δ − 1/N, which is the input minus the window mean; in linear mode they additionally remove the fitted slope.

Ports

  • u – the trending signal. Scalar – see Notes.
  • y – the residual at the newest sample. Same size as the input, so scalar.

Parameters

  • Window Length – N, how many samples the fit sees. A whole number from 2 to 256. Larger N follows a slower trend and leaves more of the signal; smaller N tracks the signal itself and leaves less.
  • Trend Order – what is fitted and removed:
    • constant – the window mean, so the output is a zero-mean residual. This is detrend(x, 0).
    • linear – a straight line through the window by least squares, so a constant ramp is removed as well as a constant offset. This is detrend(x, 1), and it is the default.
  • 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 N weights are structural and are inlined into the arithmetic at export time rather than exposed as tunable parameters – they follow from Window Length and Trend Order, and changing either changes how many multiplies the core contains, which no runtime parameter can do. Re-export after changing them.

The three HDL targets are genuine synthesizable Q16.16: a shift register and a fixed multiply-accumulate, with the products accumulated at full width and shifted back once at the end rather than per term.

Simulink bridge

No equivalent (Support::None). The Signal Processing Toolbox ships no Simulink library at all – detrend is a MATLAB function, and no block in the Simulink standard library or in DSP System Toolbox removes a least-squares trend over a sliding window. The bridge reports this block rather than dropping it silently, and it therefore has no parity testbench. Code export verification still covers it across all ten languages.

Notes

  • Stateful, and discrete by nature (setDiscreteOnlyBlock(true)): the window advances once per sample.
  • The window is zero-prefilled, and the zeros count. Before N samples have arrived the buffer still holds its initial zeros and they take part in the fit, so the first N−1 outputs of a run are a startup transient rather than a detrended signal. MATLAB's detrend is a batch function with the whole vector in hand and has no transient; a streaming block cannot avoid one. The convention matches Moving Median, whose zero-prefill was measured against Simulink.
  • Verified against MATLAB. With N set to a whole 9-sample vector's length, this block's output at that vector's last sample matches detrend(x, 0) and detrend(x, 1) in R2026a to within 1e−15.
  • Scalar only. One channel and its own history; wire one block per channel. The size is checked rather than silently detrending the first element.
  • No state space. The block is linear in its input, but its output depends on N past samples through a fixed FIR rather than through an A/B/C/D pair seeded here, so it carries none and model reduction correctly declines to merge it.

Code facts#

FactValue
registered typeControl_Systems/Signal_Smoothing/Detrend
familyControl_Systems/Signal_Smoothing
solver environment classICoreBlock_0_Control_Systems_1_Signal_Smoothing_2_Detrend
sourcesrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Signal_Smoothing/Detrend/ICoreBlock_0_Control_Systems_1_Signal_Smoothing_2_Detrend.cpp
headersrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Signal_Smoothing/Detrend/ICoreBlock_0_Control_Systems_1_Signal_Smoothing_2_Detrend.h
default size on canvas124 × 72 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
1inICoreDoubleu
2outICoreDoubley

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
Window Length32—
Trend Orderconstant%~%linear~~linear—

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: detrend() is a MATLAB function and the Signal Processing Toolbox ships no Simulink library at all, while nothing in the Simulink standard library or in DSP System Toolbox removes a least-squares trend over a sliding window. Reported rather than dropped, and it carries no parity testbench

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

Detrend -- the residual of a least-squares constant or straight line over the last N samples ONE WEIGHT VECTOR, TEN IDENTICAL DOT PRODUCTS. The residual of a least-squares fit is a LINEAR functional of the window, so the fit is never recomputed per sample: the weights are derived once when the configuration is read, and every target emits the same multiply-accumulate over a shift register. The emitted core has no division and no branch, which is what keeps the three hardware targets a fixed-latency pipeline.

MEASURED AGAINST MATLAB R2026a rather than asserted. Driven with the window set to a whole 9-sample vector, this block's output at that vector's last sample equals detrend(x, 0) to 4e-16 and detrend(x, 1) to 7e-16. The probe is recorded in the notes of the toolbox-blocks plan, Family B.

⚠ THE WINDOW IS ZERO-PREFILLED AND THE ZEROS COUNT -- the same convention Moving Median carries, which was itself measured against Simulink. The first N-1 outputs of a run are a startup transient. MATLAB's detrend() has the whole vector in hand and has no transient at all; a streaming block cannot avoid one, so the choice is which one to document.

Sample results#

Detrend — Step: 0 -> 1 at t = 1 sDetrend — 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.1136 … 0.8807
rampRamp: slope 1 from t = 0-1.513e-15 … 0.4375
sineSine Wave: amplitude 1, 2 rad/s, no phase, no bias-1.298 … 1.292
tableRepeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample-2.665 … 2.545

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

Category dynamic · sample time 0.1 · 60 steps · commit 6db3032c0 · produced by docsSample --out <folder> --blocks Detrend Savitzky_Golay_Filter Hampel_Filter Envelope_Detector --steps 60 · data docs/generated/samples/Control_Systems__Signal_Smoothing__Detrend.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).