Generated banner for Matlab Analyze Time Frequency Content
Generated logo for Matlab Analyze Time Frequency Content

Matlab Analyze Time Frequency Content

MathWorksOfficialCreated by MathWorks

  • Skill
  • Tool integration
  • Science and research
  • BSD-2-Clause
  • No issues found

From the author

Perform time-frequency analysis in MATLAB using CWT, STFT, synchrosqueezing, reassignment, wavelet coherence, cross spectrogram, EMD/VMD, multiresolution analysis, and time-frequency filtering. Triggers on: time-frequency, spectrogram, scalogram, cwt, stft, istft, fsst, wsst, wcoherence, xspectrogram, modwt, modwtmra, modwpt, emd, vmd, hht, tffilt, dgt, gabor, instantaneous frequency, synchrosqueezing, reassignment, ridge extraction, wavelet coherence, cross spectrum, mode decomposition, signal decomposition, time-frequency filtering.
— the description by MathWorks

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides a comprehensive framework for analyzing how frequency content evolves over time using MATLAB. It covers a wide range of analytical techniques including Short-Time Fourier Transform (STFT), Continuous Wavelet Transform (CWT), synchrosqueezing, reassignment, and adaptive signal decomposition (EMD/VMD). The skill is designed to help users select the appropriate method based on their specific signal characteristics and research goals, offering guidance on visualization, mode extraction, and cross-signal analysis.

What it does

  • Visualizes time-frequency content using spectrograms and scalograms.
  • Supports advanced signal decomposition via EMD, VMD, and multiresolution analysis.
  • Enables mode extraction and signal reconstruction from time-frequency representations.
  • Computes time-varying coherence and cross-spectra between two signals.
  • Provides diagnostic tools to assess signal properties before analysis.
  • Offers a decision logic for choosing between STFT, CWT, and other transform methods.

When to use it

  • When you need to analyze the evolution of frequency content over time.
  • When choosing between different time-frequency representations like STFT or CWT.
  • When you need to extract and reconstruct individual signal components.
  • When comparing two signals using time-varying coherence or cross-spectrum analysis.
  • When decomposing signals into additive time-domain components.

Advantages

  • Provides a structured decision tree for selecting the optimal analysis method.
  • Includes diagnostic scripts to assess signal length, bandwidth, and nonstationarity.
  • Supports both interactive exploration and programmatic data analysis.
  • Clearly distinguishes between invertible and non-invertible analysis techniques.
  • Offers specific guidance on handling boundary effects and frequency resolution.

Usage examples

“How do I visualize the time-frequency content of a non-stationary signal?”
The agent will recommend using signalAnalyzer for interactive exploration or cwt for multi-resolution visualization, depending on the signal's bandwidth.
“I need to extract a specific mode from my signal using synchrosqueezing.”
The agent will guide you through the fsst or wsst workflow, including ridge extraction and subsequent signal reconstruction.
“How can I compare the time-varying coherence of two signals?”
The agent will provide the wcoherence syntax and explain how to interpret the phase arrows and coherence magnitude.
“What is the best way to decompose a signal into adaptive components?”
The agent will recommend emd or vmd based on whether the number of components is known and provide the necessary function calls.

Install

Documentation by MathWorks

Time-Frequency Analysis in MATLAB

Analyze how frequency content evolves over time using STFT, CWT, synchrosqueezing, reassignment, cross-signal methods, and data-adaptive decomposition.

Agent directive: Consult the reference guides in references/ before answering. Each guide covers a specific domain with syntax, gotchas, and common mistakes.

When To Use

  • Analyzing how frequency content evolves over time (spectrogram, scalogram)

  • Choosing between STFT, CWT, synchrosqueezing, reassignment, or EMD/VMD

  • Extracting and reconstructing individual signal components from a TF representation

  • Computing time-varying coherence or cross-spectrum between two signals

  • Decomposing signals into additive time-domain components (wavelet MRA, EMD, VMD)

  • Estimating instantaneous frequency or Hilbert spectrum

When Not To Use

  • Designing or applying classical FIR/IIR filters — use matlab-design-digital-filter

  • Extracting scalar features for ML classification — use matlab-extract-signal-features

  • Signal preprocessing (resampling, detrending, gap filling) — use matlab-prepare-signal-data

  • Quadratic/bilinear TFDs (Wigner-Ville) — not supported in MATLAB toolboxes

  • Audio-specific representations (mel spectrogram, MFCC) — use Audio Toolbox

Method Selection

Choose the analysis method based on the user's goal and signal characteristics:

GoalMethodGuide
Interactive TF exploration (spectrogram + scalogram)signalAnalyzer—
General TF visualization (uniform freq resolution)stft, spectrogram, pspectrumreferences/stft-guide.md
TF visualization (multi-resolution, constant-Q)cwt, cwtfilterbankreferences/cwt-guide.md
Sharpest TF picture (non-invertible)spectrogram("reassigned"), pspectrum(Reassigned=true)references/reassignment-guide.md
Remove specific TF regions (mask-based filtering)tffilt with binary maskreferences/stft-guide.md
Mode extraction + reconstruction (STFT domain)fsst → tfridge → ifsstreferences/reassignment-guide.md
Mode extraction + reconstruction (CWT domain)wsst → wsstridge → iwsstreferences/reassignment-guide.md
Signal reconstruction from CWTicwt (exact or approximate)references/cwt-guide.md
Additive decomposition (octave bands)modwt + modwtmrareferences/multiresolution-guide.md
Additive decomposition (uniform bands)modwptdetailsreferences/multiresolution-guide.md
Adaptive decomposition (unknown components)emdreferences/multiresolution-guide.md
Adaptive decomposition (known mode count)vmdreferences/multiresolution-guide.md
Hilbert spectrum / instantaneous frequencyhht, instfreqreferences/multiresolution-guide.md
Time-varying coherence between two signalswcoherencereferences/cross-analysis-guide.md
Cross spectrogram between two signalsxspectrogramreferences/cross-analysis-guide.md
Global coherence (no time axis)mscohere, cpsdreferences/cross-analysis-guide.md

For detailed decision logic, see references/method-selection-guide.md.

Quick Decision Tree

What is the primary goal?
│
├── Interactive exploration (adjust parameters, compare views)
│   └── signalAnalyzer — supports spectrogram + scalogram (CWT) side by side
│
├── Visualize one signal's TF content
│   ├── Need uniform frequency resolution? → stft / spectrogram / pspectrum
│   ├── Need multi-resolution (better low-freq)? → cwt
│   └── Need sharpest picture (no reconstruction)? → spectrogram("reassigned")
│
├── Remove unwanted content visible in spectrogram
│   └── Define binary mask over TF plane → tffilt (Gabor domain)
│
├── Extract and reconstruct individual components
│   ├── From TF representation (invertible)?
│   │   ├── STFT domain → fsst → tfridge → ifsst
│   │   └── CWT domain → wsst → wsstridge → iwsst
│   ├── Additive time-domain components?
│   │   ├── Octave bands → modwt + modwtmra
│   │   ├── Uniform bands → modwptdetails
│   │   └── Data-adaptive → emd or vmd
│   └── From CWT directly? → icwt (see references/cwt-guide.md)
│
├── Compare two signals
│   ├── Time-varying coherence? → wcoherence
│   ├── Time-varying cross-spectrum? → xspectrogram
│   └── Global relationship? → mscohere / cpsd
│
└── Estimate instantaneous frequency
    ├── Single monocomponent signal? → instfreq(x, fs)
    ├── Multicomponent (want per-mode IF)? → emd → instfreq(imf, fs)
    └── Multicomponent (want single average)? → instfreq(x, fs, Method="tfmoment")

Critical Rules

  1. stft has no reassignment option. Use fsst for invertible synchrosqueezing or spectrogram("reassigned") for non-invertible visualization.

  2. wsstridge argument order differs from tfridge:

    • wsstridge(sst, penalty, f, ...) — penalty is 2nd positional arg

    • tfridge(tfm, f, penalty, ...) — penalty is 3rd positional arg

  3. wsst subtracts the signal mean internally. iwsst does NOT restore it. Add mean(x) back manually if DC matters.

  4. ifsst is machine-precision; iwsst is approximate (Morlet single-integral formula).

  5. xspectrogram first output is real (cross-spectrogram magnitude). For phase, use the 4th output P. This differs from spectrogram whose first output is complex STFT.

  6. wcoherence has no Parent option. For App Designer, compute outputs and plot manually.

  7. wcoherence phase arrows show the phase lag of Y relative to X:

    • ↑ = Y lags X by π/2

    • ↓ = Y leads X by π/2

    • → = in-phase

    • ← = anti-phase PhaseDisplayThreshold (default 0.5) is plot-only — it controls which arrows are drawn but has no effect on returned numeric outputs.

  8. hht takes IMFs, not raw signal. Always decompose first: imf = emd(x); hht(imf, fs).

  9. instfreq Hilbert method is meaningless for multicomponent signals. Decompose first, or use Method="tfmoment" for a single average curve.

  10. Synchrosqueezing is precision-sensitive. Use double-precision data with fsst/wsst for reproducible results across MATLAB, codegen, and GPU.

Signal Assessment Workflow

When the user provides a signal and asks "what should I use?", run the assessment script then apply agent-side interpretation:

Step 1: Run MATLAB assessment
report = assessSignalForTF(x, fs);
disp(report)
disp(report.recommendations)

The script returns: signal length, occupied bandwidth, number of spectral peaks (with frequencies), nonstationarity indicator, DC content, precision, and auto-generated recommendations.

Step 2: Agent-side interpretation (combine script output with user goals)
User GoalKey Report FieldsRecommendation Logic
"Explore / I'm not sure what I need"—Suggest signalAnalyzer for interactive exploration (spectrogram + scalogram views, adjustable parameters)
"Visualize frequency content over time"likelyNonstationary, fractionalBandwidthIf wideband (>2 octaves): cwt. If narrowband or uniform resolution needed: stft/spectrogram
"Separate/extract components"numSpectralPeaks, peakFrequenciesHz2–3 peaks: synchrosqueezing (fsst/wsst). Many peaks: emd/vmd. Closely-spaced: modwptdetails or fsst
"Reconstruct after filtering"hasDC, precisionfsst/ifsst for exact. wsst/iwsst for CWT-domain (warn about mean). icwt for CWT bandpass
"Compare two signals"(run on both)wcoherence for coherence. xspectrogram for cross-spectrum
"Detect transients/events"signalLength, occupiedBandHzcwt with low TimeBandwidth. Or short-window stft
Step 3: Refine with follow-up questions if ambiguous
  • "Do you need to reconstruct the signal, or just visualize?"

  • "Do you need uniform frequency resolution, or is multi-resolution acceptable?"

  • "Are you comparing this signal to another?"

Reference Guides

FileCoverage
references/stft-guide.mdstft/istft, spectrogram, pspectrum, stftmag2sig, length preservation, COLA
references/cwt-guide.mdcwt, cwtfilterbank, icwt, dlicwt/icwtLayer, boundary, constant-Q
references/reassignment-guide.mdfsst/ifsst, wsst/iwsst, spectrogram("reassigned"), pspectrum(Reassigned=true), ridge extraction, penalty
references/cross-analysis-guide.mdwcoherence, xspectrogram, cpsd, mscohere, phase arrows, unsmoothed cross-spectrum
references/multiresolution-guide.mdmodwt/modwtmra, modwpt/modwptdetails, emd, vmd, hht, instfreq, instbw
references/method-selection-guide.mdDecision logic for choosing among all methods

Toolbox Requirements

ToolboxFunctions
Signal Processingstft, istft, spectrogram, pspectrum, fsst, ifsst, tfridge, xspectrogram, instfreq, instbw, stftmag2sig, cpsd, mscohere
Waveletcwt, cwtfilterbank, icwt, wsst, iwsst, wsstridge, wcoherence, modwt, modwtmra, modwpt, modwptdetails, emd, vmd, hht, tffilt, dgt
FunctionAvailable FromNote
tffiltR2025aTF mask-based filtering; all other functions available in R2024b

Documentation References


Copyright 2026 The MathWorks, Inc.


Files

references/cwt-guide.md

CWT Reference Guide

Workflow

1. Understand the Signal and User Goals

Before computing the CWT, determine:

  • Signal type: Real-valued or complex-valued?

  • Feature type: Oscillatory components (frequency resolution matters) or impulsive events (time localization matters)?

  • Sampling frequency: Known? If not, analysis uses normalized frequency (cycles/sample).

  • Goal: Visualization only, numerical outputs, or both?

ScriptInputsOutputsPurpose
assessBoundaryx (signal), optional Fs (sample rate)Figure with endpoint zoomInspects signal endpoints to recommend Boundary property
illustrateBoundary(none — loads boundaryExDisjointSine.mat)Figure with 3 scalogramsShows periodic/reflection/zeropad side-by-side
assessSpectralEnergyx (signal), Fs (sample rate), optional ThresholdDBFigure with PSD + suggested bandComputes PSD to suggest FrequencyLimits for reducing computation
illustrateTransientLocalization(none)Figure with 3 wavelet responsesCompares Morse/amor/bump time localization on impulse
plotAntiAnalyticScalogramcfs (scalogram magnitude), f (frequencies), t (time)Axes plotPlots combined negative+positive frequency scalogram for complex signals
assessBoundary(x, Fs=1000)
illustrateBoundary()
assessSpectralEnergy(x, 1000, ThresholdDB=-20)
illustrateTransientLocalization()
plotAntiAnalyticScalogram(abs(cfs), f, t)
3. Choose the Calling Pattern
GoalPattern
Visualization onlycwt(signal, ...) — no output arguments, auto-plots
Visualization into specific axes/appcwt(signal, ..., 'Parent', ax) — no output arguments
Data only[cfs, f, coi] = cwt(signal, ...)
Data + visualizationCapture outputs, then reproduce plot manually (see Patterns)
Repeated analysis (same params)Build fb = cwtfilterbank(...), then cwt(signal, 'FilterBank', fb) or wt(fb, signal)
Inspect filter bank before analysisBuild cwtfilterbank(...), use wavelets, freqz, scales, powerbw methods

Critical rule: nargout == 0 triggers auto-plotting. Capturing ANY output suppresses the plot entirely.

4. Configure the CWT
Wavelet Selection (signal-feature-driven)
Signal featuresRecommendation
General purpose / mixed content"Morse" (default), gamma=3, P²=60
Impulsive events, need precise timing"Morse" with lower TimeBandwidth (e.g., 10–30)
Oscillatory, need frequency separation"Morse" with higher TimeBandwidth (e.g., 80–120)
Reproducing published Morlet results"amor" (equivalent to Morse with P²≈36 in time duration)
Purely oscillatory, extreme freq. resolution needed"bump" (last resort — worst time localization)
Key Parameters
ParameterDefaultGuidance
TimeBandwidth60Primary tuning knob. Higher = better freq. resolution, worse time localization. Range: 3–120. Leave gamma=3 (symmetric).
VoicesPerOctave10Higher (up to 48) = finer frequency sampling. Increases computation.
FrequencyLimitsautoSet [fmin fmax] to reduce computation. Use PSD assessment to identify useful band. [0 Fs/2] for full range.
Boundary"reflection"See boundary guidance below. "periodic" is ~2x faster for large signals (>100K samples).
SamplingFrequency1Always set if known — gives physical frequency units (Hz).
FrequencyLimits Details
  • Performance lever: Restricting the range reduces scales computed (fewer rows in output).

  • Lower limit = 0: Gives lowest valid frequency from cwtfreqbounds (no guesswork).

  • Upper limit = Fs/2: Forces highest wavelet to peak at Nyquist. Use when signal has significant near-Nyquist content. Default is conservative (wavelet decays by Nyquist).

  • Use cwtfreqbounds to query achievable range for given signal length and wavelet.

Boundary Selection
BoundaryBest whenAvoid whenPerformance
"reflection"Signal is locally stationary at edgesFrequency discontinuity at boundary~2N FFT length
"periodic"Endpoints match in value and trendEndpoints differ significantlyN FFT length (fastest)
"zeropad"Signal decays to zero at edgesSignificant amplitude at boundaries~2N FFT length

Oscillations at boundaries: When the signal has active oscillations at an edge, "reflection" reverses the wave direction at that point, creating a cusp (instantaneous frequency doubling artifact). Prefer "zeropad" in this case — it attenuates to zero rather than creating a false continuation. Use "reflection" only when the signal is locally stationary (slowly varying) at its edges.

For large signals (>100K samples), "periodic" avoids doubling the FFT length. Validate with boundary assessment script first.

Why performance differs: The CWT computation is dominated by inverse FFT of the signal-wavelet product. "periodic" uses N-point FFT (DFT naturally assumes periodicity). "reflection" or "zeropad" extend the signal to ~2N points before transforming.

5. Compute and Interpret
Output Signatures

cwt():

[cfs, f, coi, fb, scalcfs] = cwt(signal, ...);

wt():

[cfs, f, coi, scalcfs] = wt(fb, signal);
  • cfs — Wavelet coefficients. For complex signals: 3D array (scales x time x 2) where page 1 = positive frequencies (analytic) and page 2 = negative frequencies (anti-analytic).

  • f — Frequencies in Hz (if SamplingFrequency set), cycles/sample (if no Fs), or periods as duration (if SamplingPeriod used).

  • coi — Cone of influence values (one per time sample).

  • fb — Filter bank object (from cwt only, 4th output).

  • scalcfs — Scaling coefficients (lowpass filter capturing near-DC content wavelets cannot reach).

Interpreting Coefficient Values

MATLAB CWT uses L1 normalization: wavelets scaled by 1/s. This means:

  • abs(cfs) ≈ amplitude of the signal component at each time-frequency point

  • A unit-amplitude sinusoid yields abs(cfs) ≈ 1 at the matching scale

  • Values are directly comparable across frequencies

  • Plot abs(cfs), not abs(cfs).^2 or log(abs(cfs))

This differs from DWT (which uses L2 normalization for energy preservation).

Scaling Coefficients

Wavelets must have zero mean — cannot capture DC/near-DC content. The scaling filter is a lowpass filter covering frequencies below the lowest wavelet. Request scaling coefficients (last output) when:

  • Low-frequency content matters to the analysis

  • Planning to reconstruct via icwt (required for perfect reconstruction)

Cone of Influence

The COI marks regions potentially affected by edge effects. It is a caution zone, not an exclusion zone:

  • Inside COI boundary: coefficients are reliable

  • Outside (near edges): potentially affected by boundary extension — treat with increased skepticism

  • A well-chosen boundary method reduces (but never eliminates) edge contamination

6. Visualize (if needed)

See Patterns section below.

Key Functions

FunctionPurposeToolbox
cwtCompute CWT, optionally plot scalogramWavelet Toolbox
cwtfilterbankConstruct reusable filter bank objectWavelet Toolbox
wtCompute CWT using filter bank (method)Wavelet Toolbox
cwtfreqboundsQuery valid frequency rangeWavelet Toolbox
icwtInverse CWT (requires scaling coefficients for perfect reconstruction)Wavelet Toolbox
waveletTimeFrequencyAnalyzerInteractive CWT app (full options, script export)Wavelet Toolbox
cwtfilterbank Inspection Methods
MethodReturns
waveletsAll wavelets at all scales (time domain)
freqzFrequency responses of all wavelets
scalesScale factors used to dilate wavelets
powerbwTable: center frequency, half-power bandwidth, band edges

Patterns

Basic Scalogram (Visualization Only)
% Auto-plots scalogram — do NOT capture outputs
cwt(signal, "Morse", Fs);
Scalogram into Specific Axes (App Designer)
% Plot into uiaxes or axes — no outputs
cwt(signal, "Morse", Fs, 'Parent', ax);
Efficient Repeated Analysis
fb = cwtfilterbank(SignalLength=length(signal), SamplingFrequency=Fs, ...
    Wavelet="Morse", TimeBandwidth=60, VoicesPerOctave=12);

% Option A: familiar cwt interface + auto-plot
cwt(signal1, 'FilterBank', fb);

% Option B: programmatic access
[cfs, f, coi] = wt(fb, signal2);
Manual Scalogram (Real-Valued Signal)

Use when you need both the data AND a plot.

[cfs, f, coi] = cwt(signal, "Morse", Fs);
t = (0:length(signal)-1) / Fs;

ax = newplot;
imagesc(ax, t, f, abs(cfs))
ax.YDir = "normal";
ax.YScale = "log";
xlabel(ax, "Time (s)")
ylabel(ax, "Frequency (Hz)")
title(ax, "Scalogram")
colorbar(ax)

% Optional: add COI
hold(ax, "on")
plot(ax, t, coi, 'w--', LineWidth=1.2)
Manual Scalogram (Complex-Valued Signal, Combined Plot)

For complex signals, cfs is a 3D array (scales x time x 2): page 1 contains positive-frequency (analytic) coefficients and page 2 contains negative-frequency (anti-analytic) coefficients. Use scripts/plotAntiAnalyticScalogram.m for a combined -Fs/2 to Fs/2 view:

fb = cwtfilterbank(SignalLength=length(signal), SamplingFrequency=Fs);
[cfs, f] = wt(fb, signal);
t = (0:length(signal)-1) / Fs;

plotAntiAnalyticScalogram(abs(cfs), f, t);

Why surf instead of imagesc for complex signals: The frequency axis spans negative to positive. Setting YScale = "log" would fail (log of negative numbers). surf handles the non-uniform logarithmic spacing correctly without requiring a log axis setting.

Transient Localization

When the goal is to precisely locate impulsive events or abrupt changes:

Wavelet choice for time localization (best to worst):

WaveletTime LocalizationWhy
"Morse" with TimeBandwidth=10–20BestLow TB makes wavelet compact in time
"amor" (analytic Morlet)GoodEquivalent to Morse with P²≈36, naturally biased toward time localization
"bump"WorstCompact in frequency domain → maximally spread in time (Heisenberg)
[cfs, f, coi] = cwt(signal, "Morse", Fs, TimeBandwidth=20);
t = (0:length(signal)-1) / Fs;

% Extract the highest-frequency scale (first row = finest scale)
finestScale = abs(cfs(1, :));

% Plot to identify transient locations
figure
plot(t, finestScale)
xlabel("Time (s)")
ylabel("|CWT| at finest scale")
title("Transient Detection")

Run scripts/illustrateTransientLocalization.m to compare all three wavelets on an impulse signal.

Constant-Q Property and Limitations

CWT is a constant-Q analysis: bandwidth is proportional to center frequency.

  • High frequencies: broad bandwidth (less frequency resolution), short time support (better time resolution)

  • Low frequencies: narrow bandwidth (better frequency resolution), long time support (less time resolution)

Limitation: At high frequencies, the wide bandwidth means CWT cannot resolve closely-spaced tones. If tone separation Δf is small relative to center frequency (Δf/fc < 1/Q), the components will be smeared together. Use STFT (constant bandwidth) instead.

Example: DTMF tones at 3600 and 3700 Hz (100 Hz apart) at fs=8000 Hz. CWT at 3650 Hz with bump wavelet (Q~20) has bandwidth ~182 Hz — cannot separate them. STFT with M=256 gives 31.25 Hz resolution — easily resolves both.

Scale-Frequency Relationship

Scale and frequency are inversely related: s = f_psi / f, where f_psi is the mother wavelet's peak frequency (in cycles/sample).

WaveletPeak frequency f_psi (cycles/sample)
Morse(gamma, TB)(beta/gamma)^(1/gamma) / (2*pi), where beta = TB/gamma
amor (analytic Morlet)6/(2*pi) ≈ 0.9549 (fixed)
bump5/(2*pi) ≈ 0.7958 (fixed)

To convert to physical Hz: f_Hz = f_psi * Fs / s.

Key points:

  • Scale is unitless regardless of Fourier transform convention

  • Large scale → low frequency, small scale → high frequency

  • The CWT uses L1 normalization, so dilating by s gives a filter centered at f_psi/s

  • centerFrequencies(fb) returns the frequency at each scale for a given filter bank

Interactive Exploration

ToolLaunchCapabilities
waveletTimeFrequencyAnalyzerCommand line or Apps GalleryFull wavelet options, COI toggle, period/frequency display, complex signal support, script generation
Signal Analyzer scalogramsignalAnalyzer(signal) → Display tab → ScalogramQuick scalogram, Morse only, real signals only

Recommend waveletTimeFrequencyAnalyzer when the user needs to explore parameters and export a script.

Common Mistakes

MistakeWhy It's WrongCorrect Approach
Calling figure then [cfs,f] = cwt(...) expecting a plotCapturing outputs suppresses auto-plotting (nargout==0 triggers plot)Call cwt(...) with no outputs, or reproduce manually
Using cwt() in a loop without pre-building filter bankRebuilds filter bank every iteration (expensive)Build fb = cwtfilterbank(...) once, pass via 'FilterBank' or use wt
Plotting abs(cfs).^2 thinking it's a "power" scalogramL1 normalization means abs(cfs) already gives amplitude — squaring distorts interpretationPlot abs(cfs)
Using imagesc for combined complex-signal plot with negative frequenciesCannot set YScale="log" with negative frequenciesUse plotAntiAnalyticScalogram or surf
Leaving FrequencyLimits at default for known narrowband signalsComputes unnecessary scales, wastes timeRun PSD assessment, set FrequencyLimits to energy-containing band
Using "periodic" boundary when endpoints differCreates artificial discontinuityInspect endpoints first; use "reflection" if they differ
Adjusting WaveletParameters gamma without specific reasonBreaks Morse wavelet symmetry in Fourier domainUse TimeBandwidth alone (keeps gamma=3)
Using "bump" wavelet for time localization of transients"bump" is compact in frequency domain — worst time localizationUse "Morse" with low TimeBandwidth (10–20)

Low-Frequency Analysis

The lowest achievable frequency depends on signal length and wavelet time standard deviation:

  • Constraint: 2σ_t of wavelet ≤ signal length at largest scale

  • Higher TimeBandwidth → wider wavelets → lowest frequency further from DC

  • Use cwtfreqbounds to check achievable range

  • Request scaling coefficients (last output of cwt/wt) to capture near-DC content

Inverse CWT (icwt)

Reconstruction Methods

icwt has two fundamentally different inversion paths:

MethodFidelityRequirementsUse when
Analysis filter bank (exact)Machine precision (~1e-16)Boundary="periodic" in forward CWT + analysis filters from freqzNeed exact reconstruction
Morlet single-integral (approximate)Approximate (error depends on signal)None — works with any CWT outputQuick reconstruction, bandpass filtering, exploratory work
Exact Reconstruction (filter bank method)

Perfect reconstruction requires the analysis filter bank, which you obtain from cwtfilterbank:

% Forward CWT — must use periodic boundary
fb = cwtfilterbank(SignalLength=length(x), SamplingFrequency=Fs, Boundary="periodic");
[cfs, ~, ~, scalcfs] = wt(fb, x);

% Get analysis filters
psif = freqz(fb, FrequencyRange="twosided", IncludeLowpass=true);

% Exact inversion
xrec = icwt(cfs, [], ScalingCoefficients=scalcfs, AnalysisFilterBank=psif);
% norm(xrec' - x, Inf) ≈ 1e-16

Or equivalently using cwt (filter bank is the 4th output):

[cfs, f, coi, fb, scalcfs] = cwt(x, Fs, Boundary="periodic");
psif = freqz(fb, FrequencyRange="twosided", IncludeLowpass=true);
xrec = icwt(cfs, [], ScalingCoefficients=scalcfs, AnalysisFilterBank=psif);

Critical: AnalysisFilterBank cannot be combined with SignalMean, VoicesPerOctave, TimeBandwidth, or WaveletParameters. It is a separate inversion path.

Approximate Reconstruction (Morlet single-integral)

Uses the admissibility constant to sum CWT coefficients over scale. Misses DC/near-DC content that wavelets cannot capture.

% Option A: scalar mean (simplest)
[cfs, f] = cwt(x, Fs);
xrec = icwt(cfs, 'SignalMean', mean(x));

% Option B: time-varying trend (better low-frequency recovery)
trend = smoothdata(x, 'movmean', 100);
xrec = icwt(cfs, 'SignalMean', trend);

% Option C: scaling coefficients (best approximate method)
[cfs, ~, ~, ~, scalcfs] = cwt(x, Fs);
xrec = icwt(cfs, 'ScalingCoefficients', scalcfs);

Cannot specify both SignalMean and ScalingCoefficients — they serve the same role (DC recovery).

Bandpass-Filtered Reconstruction

Extract a frequency-localized approximation by specifying a frequency range:

[cfs, f] = cwt(x, Fs);
xrec = icwt(cfs, [], f, [flo fhi], 'SignalMean', mean(x));

This zeros out coefficients outside [flo, fhi] before applying the Morlet formula. Useful for isolating specific oscillatory components.

Wavelet Must Match

If you used a non-default wavelet in the forward CWT, pass it to icwt:

[cfs, ~, ~, ~, scalcfs] = cwt(x, 'bump');
xrec = icwt(cfs, 'bump', 'ScalingCoefficients', scalcfs);
Decision Tree
Need exact reconstruction?
├── Yes → Use AnalysisFilterBank + ScalingCoefficients
│         (requires Boundary="periodic" in forward CWT)
└── No
    ├── Need bandpass filtering? → icwt(cfs, [], f, [flo fhi], SignalMean=...)
    └── Just need approximate signal back?
        ├── Have scaling coefficients? → icwt(cfs, ScalingCoefficients=scalcfs)
        ├── Know the mean? → icwt(cfs, SignalMean=mean(x))
        └── Have a trend estimate? → icwt(cfs, SignalMean=trend)
Deep Learning Integration
FunctionContextInput typeOutput
dlicwtCustom training loopsComplex or real dlarray (CBT/SCBT)dlarray (CBT)
icwtLayerdlnetwork architecturesReal only (concatenated real/imag along channel dim)Real dlarray (CBT)

Both use the exact filter-bank reconstruction path only (no Morlet approximation).

dlicwt — Custom Training Loops
% Forward: dlcwt outputs complex dlarray
fb = cwtfilterbank(SignalLength=N, Boundary="periodic");
[psif, indices] = cwtfilters2array(fb, 1e-8, IncludeLowpass=true);

% In training loop:
cfs = dlcwt(x_dl, psif, indices);          % complex output
xrec = dlicwt(cfs, psif, indices);          % accepts complex input
  • Accepts complex dlarray — pairs naturally with dlcwt

  • Requires psif (analysis filters as (1,1,:) dlarray) and indices (filter index matrix)

  • Formatted/unformatted pattern: if input is formatted, output is formatted "CBT"; if DataFormat is specified explicitly, output is unformatted

icwtLayer — dlnetwork
% Construct layer
layer = icwtLayer(SignalLength=1024, VoicesPerOctave=12, ...
    IncludeLowpass=true, Wavelet="Morse", TimeBandwidth=60);
  • Input must be real — expects real/imaginary parts concatenated along channel dimension (pairs with cwtLayer which outputs real)

  • Channel dimension gets halved in output (real/imag → complex → real signal)

  • Weights are learnable — initialized from cwtfilterbank analysis filters but can be fine-tuned. Default WeightLearnRateFactor=0 (frozen). Set > 0 to learn modified reconstruction filters.

  • Always uses Boundary="periodic" internally

Deep Learning Gotchas
GotchaDetail
icwtLayer only accepts realIf CWT output is complex, concatenate real/imag along channel dim before passing to icwtLayer
dlicwt accepts complexPairs directly with dlcwt output — no concatenation needed
No Morlet approximationBoth DL paths use exact filter-bank inversion only
Filter bank must matchpsif and indices used in dlicwt must come from the same cwtfilterbank used for the forward dlcwt
icwtLayer weights are learnableDefault is frozen (rate=0). Enable learning only if you want the network to adapt the reconstruction
Common icwt Mistakes
MistakeWhy It's WrongCorrect Approach
Using AnalysisFilterBank without periodic boundary in forward CWTFilters are derived assuming periodic convolution — mismatch causes reconstruction errorAlways use Boundary="periodic" in cwt/cwtfilterbank when planning exact reconstruction
Omitting ScalingCoefficients with AnalysisFilterBankLoses DC/near-DC content the wavelets can't captureAlways pass ScalingCoefficients=scalcfs alongside the filter bank
Specifying both SignalMean and ScalingCoefficientsMutually exclusive — both fill the same roleChoose one
Combining AnalysisFilterBank with VoicesPerOctave or TimeBandwidthThese are Morlet-method options, incompatible with filter bank pathUse filter bank path alone, or Morlet path alone
Expecting perfect reconstruction from Morlet methodSingle-integral formula is inherently approximateUse filter bank path if exact reconstruction is required
Forgetting to pass wavelet name to icwt when using non-default waveleticwt defaults to Morse — admissibility constant will be wrongPass the same wavelet: icwt(cfs, 'bump', ...)

Documentation References


Copyright 2026 The MathWorks, Inc.


Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Security

No issues found by our static scan· No issues found

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Created by
MathWorks
Publisher
MathWorks (Official)
Source
matlab/matlab-agentic-toolkit · skills-catalog/signal-processing/matlab-analyze-time-frequency-content · commit 2a7f215
Licence
BSD 2-Clause License (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE.md)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by MathWorks or MathWorks.

Get it from the source

1 of this skill’s files are not mirrored here, so there is no ZIP. Get the complete skill from its source: matlab/matlab-agentic-toolkit