Walsh Hadamard Transform — Control Systems/Transforms
Control_Systems/Transforms/Walsh_Hadamard_Transform · 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.
Walsh-Hadamard Transform
Control Systems / Transforms
The fast Walsh-Hadamard transform of a window – the ±1 relative of the DFT. Its kernel holds nothing but +1 and −1, so the transform costs additions and no multiplies, which makes it the natural choice for a signal that is itself square: a communications spreading code, a switching waveform, a logic-level bus. With W(N) the N×N Walsh-Hadamard matrix:
Forward: y = W(N)·u / N, and Inverse: y = W(N)·u. The two differ only by the 1/N.
Ports
- u – the window to transform, [N,1] or [1,N], with N a power of two of at least 2.
- y – the transform coefficients, the same size and the same orientation as u. A column comes back a column.
Parameters
- Transform
- Forward (fwht) – includes the 1/N scale. The default.
- Inverse (ifwht) – the same kernel with no scale, so it undoes the forward map exactly.
- Ordering – which order the kernel's rows come in. These are
three different answers, not three spellings of one, and the option names
are MATLAB's own.
- sequency – rows sorted by how many sign changes each contains. This is the Walsh order and the default; it is the one analogous to rising frequency in a DFT, so it is what a reader of the output almost always wants.
- hadamard – the natural Kronecker order, obtained by bit-reversing the input first.
- dyadic – the Paley order, which shares sequency's butterfly but not its pre-shuffle.
- 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 kernel follows from the window length, the direction and the ordering – all three settled before the run – so it is resolved once at export time and baked into every target as literals. No butterfly is executed at run time in any of them, and no target needs a loop bound, an index type or a scratch array.
The three HDL targets are simulation-only: they carry the
transform in real arithmetic and quantize only at the port boundary.
The inverse map sums N values with no scale, so its output grows with the window
– a Q16.16 datapath would saturate on windows a user will really
present.
Simulink bridge
No equivalent, so nothing crosses in either direction. The Signal
Processing Toolbox ships fwht and ifwht as MATLAB
functions with no Simulink block behind them, and the DSP System Toolbox's
transform library – FFT, IFFT, Magnitude FFT, DCT, IDCT, the two cepstra,
the two wavelet transforms, Analytic Signal, the two Short-Time FFTs and Zoom FFT
– carries no Walsh or Hadamard block either.
Notes
- Algebraic and stateless: the output depends only on the window presented this step.
- No state space. The map is a genuine D matrix, but one of N² entries carrying no dynamics at all, and every target already emits the kernel directly.
- A window whose length is not a power of two stops the run with a message naming the length. MATLAB instead pads silently to the next power of two, and that is deliberately not copied: N appears in the scale factor, so a pad moves every output rather than only the tail.
- The Inverse is a true inverse of the Forward at the same ordering, and only at the same ordering.
Code facts#
| Fact | Value |
|---|---|
| registered type | Control_Systems/Transforms/Walsh_Hadamard_Transform |
| family | Control_Systems/Transforms |
| solver environment class | ICoreBlock_0_Control_Systems_1_Transforms_2_Walsh_Hadamard_Transform |
| source | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Transforms/Walsh_Hadamard_Transform/ICoreBlock_0_Control_Systems_1_Transforms_2_Walsh_Hadamard_Transform.cpp |
| header | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Transforms/Walsh_Hadamard_Transform/ICoreBlock_0_Control_Systems_1_Transforms_2_Walsh_Hadamard_Transform.h |
| default size on canvas | 140 × 80 px |
| ports at insert | 1 in, 1 out |
| code generators implemented | Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text |
Ports#
| # | Direction | Signal type | Description label |
|---|---|---|---|
| 1 | in | ICoreDouble | u |
| 2 | out | ICoreDouble | y |
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 variable | Default | Simulink parameter |
|---|---|---|
Transform | Forward (fwht)%~%Inverse (ifwht)~~Forward (fwht) | — |
Ordering | sequency%~%hadamard%~%dyadic~~sequency | — |
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.
Simulink bridge#
| support | Support::None |
| Simulink path | — |
| port-count rule | PortsParam::None |
SampleTime parameter | yes |
Caveat (shown to the user): no Simulink equivalent. fwht and ifwht are Signal Processing Toolbox MATLAB functions, not blocks, and the DSP System Toolbox's transform library carries no Walsh or Hadamard block
Catalog contract: src/ICoreBlocks/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:
B0every 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).
Walsh-Hadamard Transform -- the +/-1 relative of the DFT (MATLAB fwht / ifwht) Forward: y = W(N) * u / N fwht Inverse: y = W(N) * u ifwht
The kernel is +/-1 throughout, so the transform costs additions and no multiplies.
⚠ THE BUTTERFLY BELOW IS TRANSCRIBED LINE FOR LINE from R2026a's toolbox/signal/signal/ fwht.m, not reconstructed from the definition, because the three orderings are three different answers and only the source says which is which. It was then diffed against real MATLAB output before any of this was written -- on [3 -1 4 1 -5 9 2 -6], all three orderings and both directions agree to all 17 digits.
Two details in that source are easy to lose in a rewrite and both change every output:
- the first stage's second line reads the UPDATED first line -- x(i+1) = x(i) - 2*x(i+1)
runs after x(i) = x(i) + x(i+1), so it is a-b and not (a+b)-2b of the ORIGINAL a.
- 'hadamard' and 'dyadic' share ONE butterfly branch and differ only in whether the input
is bit-reversed first. Treating dyadic as a third branch, or hadamard as a post-shuffle, produces a plausible-looking permutation of the right numbers.
⚠ N MUST BE A POWER OF TWO, rejected rather than padded. MATLAB pads silently to the next power of two; this block does not, and that is the one MATLAB behaviour deliberately not copied. N is in the scale factor, so a pad moves every output rather than only the tail.
The kernel depends only on N, the direction and the ordering, all settled before the run, so it is resolved once and baked into every backend as literals -- no butterfly runs at export time in any target.
Sample results#
No stimulus produced a sampled output in this rig — Invalid window length at: ICore Blocks/Home/Walsh Hadamard Transform. 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 2b8440534 · produced by docsSample --out <folder> --blocks FFT_Shift Bit_Reverse_Order Walsh_Hadamard_Transform Goertzel --steps 60
Sample data: docs/generated/samples/Control_Systems__Transforms__Walsh_Hadamard_Transform.json