Generated reference › MUSIC Spectrum — Control Systems/Spectral Measurements
kind: generated#block#control-systems-spectral-measurements

MUSIC Spectrum — Control Systems/Spectral Measurements

MUSIC

Control_Systems/Spectral_Measurements/MUSIC_Spectrum · 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.

MUSIC Spectrum

Control Systems / Spectral Measurements

The MUSIC pseudospectrum of a signal frame – MATLAB's pmusic. The frame's correlation matrix R of order m is decomposed as R = V·diag(λ)·V′, eigenvalues in descending order; the p largest span the signal subspace and the other m−p eigenvectors vk the noise subspace orthogonal to it. A sinusoid in the frame lies in the signal subspace, so its frequency is where the noise subspace has almost nothing:

S(f) = 1 ÷ Σk>p |Vk(f)|²,   Vk(f) = Σn vk[n]·e−j2πfn,   f = k/nfft cycles per sample.

R is built by the covariance method: with L = N−m+1, row i of the data matrix X holds samples i+m−1 down to i, and R = X′X/L, exactly corrmtx(x, m−1, 'cov') multiplied by its own transpose. Peaks mark the sinusoids' frequencies; their heights are not powers.

Ports

  • x – the signal frame, an [N,1] column with the oldest sample first. N is read off the wire and must be at least 2m−1 – as many rows in the data matrix as it has columns – and at most 128. A Tapped Delay with Delay Order Oldest turns a stream into such a frame.
  • S – the pseudospectrum, [floor(nfft/2)+1, 1] one-sided (bins 0 to nfft/2, DC first) or [nfft, 1] two-sided; bin k is at frequency k/nfft of the sampling rate.

Parameters

  • Signal Subspace Dimension – p, the number of complex exponentials in the frame: two per real sinusoid. A whole number from 1 to m−1. Defaults to 4, two real sinusoids.
  • Correlation Matrix Order – m, the size of the m×m correlation matrix and the length of each eigenvector, a whole number from 2 to 16. pmusic uses 2p, and so does the default, 8.
  • Dimension Rule – how the signal subspace dimension is decided:
    • Fixed – it is p.
    • Threshold – pmusic's two-element form [p thr]: it is the number of eigenvalues greater than Threshold times the smallest one, but never more than p, and p when none is.
  • Threshold – thr, the multiple of the smallest eigenvalue the Threshold rule compares against; a number of 0 or more. Defaults to 10. Ignored by the Fixed rule.
  • FFT Length – nfft, the number of frequency points around the whole circle, a whole number from 2 to 1024. Defaults to 256, pmusic's. An nfft below m samples each eigenvector's transform at nfft points all the same, which is what pmusic's own transform does.
  • Spectrum Range – One-sided (the default, pmusic's for a real signal): bins 0 to floor(nfft/2), with nothing doubled, because a pseudospectrum is not a density. Two-sided: all nfft bins.
  • 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, all from one program, so every target does the same arithmetic in the same order as the simulation: the correlation matrix, a cyclic Jacobi eigenvalue solve, the sort, and one transform per eigenvector. All six settings and the frame length are structural; re-export after changing any of them.

The three HDL targets run that program in real arithmetic and quantize only at the ports: simulation-only, not offered as synthesizable. An eigenvalue solve takes square roots and divides by the data, which a Q16.16 datapath does not carry.

Simulink bridge

None (Support::None). pmusic is a Signal Processing Toolbox function and that toolbox ships no Simulink library; a search of every DSP System Toolbox and Simulink library on R2026a found no MUSIC, subspace or pseudospectrum block, so there is no path a diagram could name. The bridge reports this block rather than dropping it silently, and it has no parity testbench; code export verification covers all ten languages.

Notes

  • Algebraic: the output depends on this step's frame alone.
  • Verified against R2026a: the same program agrees with pmusic to 2.2e−11 relative on every bin over 1400 frames of tones in noise, the threshold form and both ranges included. With m = 2p the block is pmusic(x, p, nfft); for any other m it is pmusic(corrmtx(x, m−1, 'cov'), p, nfft). Add 'twosided' for the two-sided range and write p as [p thr] for the threshold rule.
  • When the signal subspace is the smaller one (p ≤ m−p) the block does what pmusic does: it sums the p signal eigenvectors and answers 1 ÷ |m − Σ|, the same number by orthonormality.
  • ⚠ There is no rootmusic mode, and the reason is measured. rootmusic roots the noise-subspace polynomial and reports the p frequencies whose roots sit closest to the unit circle, with their powers. Over 500 perturbations of a 24-sample frame the FREQUENCIES were steady (1.5e−14 under a 1e−15 perturbation, 1e−6 rad under one Q16.16 quantum) but the POWERS were not: a 1e−15 perturbation moved them by 1.4e−10 relative and one Q16.16 quantum moved them by 9.8 %, ten times the band the three HDL targets are held to. A mode whose answer no rig can certify is not shipped; the peaks of this pseudospectrum locate the same frequencies.
  • An eigenvector's sign is arbitrary, and this block's solver and MATLAB's SVD choose differently; the pseudospectrum reads each one only through |Vk(f)|², which no sign changes.
  • A frame whose signal and noise eigenvalues are nearly equal – no sinusoid, or more sinusoids than p/2 – has no well-defined split and the answer then depends on rounding. Drive it with tones.
  • The three HDL targets' output port is Q16.16, whose largest value is 32767; a frame with almost no noise gives a peak far beyond it, which those three targets cannot carry while the other seven do.

Code facts#

FactValue
registered typeControl_Systems/Spectral_Measurements/MUSIC_Spectrum
familyControl_Systems/Spectral_Measurements
solver environment classICoreBlock_0_Control_Systems_1_Spectral_Measurements_2_MUSIC_Spectrum
sourcesrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Spectral_Measurements/MUSIC_Spectrum/ICoreBlock_0_Control_Systems_1_Spectral_Measurements_2_MUSIC_Spectrum.cpp
headersrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Spectral_Measurements/MUSIC_Spectrum/ICoreBlock_0_Control_Systems_1_Spectral_Measurements_2_MUSIC_Spectrum.h
default size on canvas150 × 76 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
1inICoreDoublex
2outICoreDoubleS

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
Signal Subspace Dimension4not crossed
Correlation Matrix Order8not crossed
Dimension RuleFixed%~%Threshold~~Fixednot crossed
Threshold10not crossed
FFT Length256not crossed
Spectrum RangeOne-sided%~%Two-sided~~One-sidednot crossed

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
deliberately not crossedSignal Subspace Dimension, Correlation Matrix Order, Dimension Rule, Threshold, FFT Length, Spectrum Range

Caveat (shown to the user): pmusic is a Signal Processing Toolbox function, not a Simulink library block -- that toolbox ships no Simulink library -- and a search of 97 DSP System Toolbox and Simulink libraries (8600 blocks, R2026a) found no MUSIC, subspace or pseudospectrum block, so there is no path a diagram could name; the block is reported rather than dropped when a model crosses

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:

  • B0 every 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).

MUSIC Spectrum -- MATLAB's pmusic, the subspace pseudospectrum of a frame R = corrmtx(x, m-1, 'cov')' * corrmtx(x, m-1, 'cov') order m, L = N - m + 1 rows R = V diag(lambda) V', lambda descending cyclic Jacobi S(f) = 1 / SUM_{k > p} |V_k(f)|^2, f = 0, 1/nfft, ... the noise subspace

Read out of R2026a's pmusic.m, private/music.m, private/musicOptions.m and corrmtx.m, then measured. What that pinned, each a wrong answer if guessed:

  • pmusic builds the correlation matrix of order 2p from a vector by corrmtx's COVARIANCE

method -- N - m + 1 rows, each the m newest-first samples, scaled by 1/sqrt(N - m + 1) -- and takes the SVD of that data matrix; the squared singular values are the eigenvalues. This block takes the eigenvalues of X'X by Jacobi instead: the same subspaces.

  • pmusic sums the SIGNAL eigenvectors when they are the fewer (p <= m - p) and answers

1 / |m - SUM|, the noise sum by orthonormality; this block does the same.

  • The [p thr] form keeps p_eff = min(p, #{lambda > thr * lambda_min}), or p when no

eigenvalue clears the bar.

  • freqz(v, 1, nfft, 'whole') with nfft below the vector length WRAPS the vector (the DTFT

sampled at nfft points: 1.1e-15 from the wrapped DFT, 2.1 from the truncated one), which is what a direct transform at 2 pi k / nfft does too.

  • One-sided is bins 0 .. floor(nfft/2) with NOTHING doubled: a pseudospectrum is not a density.

Measured: a prototype of exactly this program against pmusic on 7 configurations x 200 frames of two tones plus noise (N 16..32, m 4..12, nfft 5..64, one- and two-sided, the threshold form, p above and below m/2): worst relative disagreement 2.2e-11 on any bin -- the peaks, where 1/D amplifies the rounding of forming X'X rather than taking the SVD of X.

Support::None: a sweep of 97 Simulink libraries (8600 blocks) found no MUSIC, subspace or pseudospectrum block, and pmusic is a Signal Processing Toolbox function, which ships none.

Sample results#

No stimulus produced a sampled output in this rig — The frame has 1 samples; it must have at least 2m - 1 = 15 (as many data-matrix rows as the order m = 8) and at most 128.. 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 ee1ac01a4e538ed0c5e24de27bed3622cf0687b7 · produced by docsSample --out <folder> --blocks MUSIC_Spectrum Eigenvector_Spectrum Lomb_Scargle_Periodogram --steps 60

Sample data: docs/generated/samples/Control_Systems__Spectral_Measurements__MUSIC_Spectrum.json