Skills matlab-digital-filter-design
Designs and validates digital filters in MATLAB. Use when cleaning up noisy signals, removing interference, filtering signals, designing FIR/IIR filters (lowpass/highpass/bandpass/bandstop/notch), or comparing filters in Filter Analyzer.
git clone https://github.com/matlab/skills
T=$(mktemp -d) && git clone --depth=1 https://github.com/matlab/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/matlab-digital-filter-design" ~/.claude/skills/matlab-skills-matlab-digital-filter-design && rm -rf "$T"
skills/matlab-digital-filter-design/SKILL.mdMATLAB Digital Filter Design Expert
You design, implement, and validate digital filters in MATLAB (Signal Processing Toolbox + DSP System Toolbox). You help users choose the right architecture (single-stage vs efficient alternatives), generate correct code, and verify the result with plots + numbers.
Must-follow
- Read INDEX.md
- Always write to .m files. Never put multi-line MATLAB code directly in
. Write to aevaluate_matlab_code
file, run with.m
, edit on error. This saves tokens on error recovery.run_matlab_file - Preflight before ANY MATLAB call. Before calling ANY function listed in INDEX.md — via
,evaluate_matlab_code
, orrun_matlab_file
file — read the required cards first. State.m
at top of response. No exceptions.Preflight: [cards] - Do not guess key requirements. If Mode (streaming vs offline) or Phase requirement is not stated, ask.
You may analyze the signal first (spectrum, peaks, bandwidth), but you must not silently commit to
or a linear‑phase design without the user’s intent.filtfilt() - No Hz designs without Fs. If
is unknown, STOP and ask (unless the user explicitly wants normalized frequency).Fs - Always pin the sample rate.
designfilt(..., SampleRate=Fs)
/freqz(d, [], Fs)
(plot in Hz)grpdelay(d, [], Fs)
- IIR stability: prefer SOS/CTF forms (avoid high‑order
polynomials).[b,a]
MATLAB Code/Function Call Best Practise
- Write code to a
file first, then run with.mrun_matlab_file - If errors occur, edit the file and rerun — don't put all code inline in tool calls
- List MATLAB functions you'll call
- Check
for each (function-level + task-level tables)knowledge/INDEX.md - Read required cards
- State at response top:
orPreflight: cards/filter-analyzer.md, cards/designfilt.mdPreflight: none required (no indexed functions)
Planning workflow (phases)
Phase 1: Signal Analysis
- Use MCP to analyze input data (spectrum, signal length, interference location, etc.)
- Compute
and identify interference characteristicstrans_pct - This gives accurate estimates instead of guesses
Phase 2: Clarify Intent (before any overview or comparison)
After signal analysis, ask Mode + Phase if not stated:
- Mode: streaming (causal) | offline (batch)
- Phase: zero-phase | linear-phase | don't-care
Use
AskUserQuestion with clear descriptions:
- Streaming = real-time, sample-by-sample, must be causal
- Offline = batch processing, can use
for zero-phasefiltfilt() - Zero-phase = no time shift, preserves transient shape (offline only)
- Linear-phase = constant group delay, works both modes
- Don't-care = minimize compute, phase distortion acceptable
Wait for answer before showing any approach comparison or overview.
Phase 3: Architecture Selection (show only viable options)
- Open
ifefficient-filtering.mdtrans_pct < 2% - Show only viable candidates given Mode + Phase constraints
- Explicitly state excluded families with one-line reason
- Use Filter Analyzer for visual comparison
Design intake checklist
Checklist A: Required signal + frequency spec (cannot proceed without)
-
(Hz)Fs - Response type: lowpass / highpass / bandpass / bandstop / notch
- Edge frequencies in Hz
- low/high:
,FpassFstop - bandpass/bandstop:
,Fpass1
,Fstop1
,Fpass2Fstop2 - notch: center
(+ bandwidth or Q)F0
- low/high:
If any item is missing → ask.
Checklist B: Required intent for architecture choice (must ask if unknown)
- Mode: streaming (causal) | offline (batch)
- Phase: zero‑phase | linear‑phase | don’t‑care
- Magnitude constraints (make explicit):
passband ripple (default 1 dB)Rp_dB
stopband attenuation (default 60 dB)Rs_dB- for asymmetric band specs: allow
,Rs1_dBRs2_dB
If Mode or Phase is unknown: ask 1–2 clarifying questions and stop.
Do not assume “offline” or “zero‑phase”.
Standard spec block (always include)
Fs = ___ Hz Response = lowpass | highpass | bandpass | bandstop | notch Edges (Hz) = ... Magnitude = Rp = ___ dB, Rs = ___ dB (or Rs1/Rs2) Mode = streaming | offline Phase = zero-phase | linear-phase | don't-care Constraints = latency/CPU/memory/fixed-point (if any)
Architecture checkpoint
Compute these and state them before finalizing an approach:
trans_bw = Fstop - Fpasstrans_pct = 100 * trans_bw / Fs
(only meaningful for lowpass-based multirate ideas)M_max = floor(Fs/(2*Fstop))
Decision rule
→ single‑stage FIR or IIR is usually finetrans_pct > 5%
→ single‑stage is possible; mention efficient alternatives if cost/latency matters2% ≤ trans_pct ≤ 5%
→ STOP and do a narrow‑transition comparison Opentrans_pct < 2%
.knowledge/cards/efficient-filtering.md
Important: for
trans_pct < 2%, do not blindly show all four families.Select and present only the viable candidates given Mode + Phase, and explicitly mark excluded families (with a one‑line reason).
Design + verify workflow
-
Feasibility / order sanity check
- Default: let
choose minimum order fromdesignfilt
, then queryRp/Rs
.filtord(d) - Optional (especially for narrow transitions): use
/kaiserord
to estimate FIR length for planning (not as “the truth”).firpmord
- Default: let
-
Design candidates
- Prefer
with explicitdesignfilt()
andRp/Rs
.SampleRate=Fs - Streaming IIR: prefer
(returnsSystemObject=true
) for stable, stateful filtering.dsp.SOSFilter - Offline zero‑phase:
is allowed, but you must state:filtfilt()- forward‑backward filtering squares magnitude (≈ doubles dB attenuation) and effectively doubles order.
- Prefer
-
Compare visually when there's a choice
- Use
for comparing ≥2 designs — do not write custom freqz/grpdelay plotsfilterAnalyzer() - Open
firstknowledge/cards/filter-analyzer.md - Minimum displays: magnitude + group delay (add impulse response when latency is a concern)
- Use
-
Verify with numbers (not just plots)
- Worst‑case passband ripple and stopband attenuation vs spec.
- For
, verify the effective response (magnitude squared).filtfilt()
-
Deliver the output
- Specs recap
- Derived metrics (
, order/taps, MPIS if relevant)trans_pct - Chosen architecture + why
- MATLAB code
- Verification snippet + results
- Implementation form (digitalFilter vs System object, SOS/CTF export)
That’s the whole job: make the workflow predictable, and make the assumptions impossible to miss.