name: matlab-design-array
description: Design and analyze finite and infinite antenna arrays using MATLAB Antenna Toolbox. Finite arrays include linear, rectangular, circular, and conformal types with beam steering, amplitude tapering, mutual coupling, and pattern visualization. Infinite arrays use Floquet boundary conditions for scan impedance, scan element pattern, and scan blindness detection. Use when the user wants to design, create, or analyze any antenna array (finite or infinite/periodic).
license: MathWorks BSD-3-Clause
allowed-tools: mcp__matlab__evaluate_matlab_code mcp__matlab__check_matlab_code mcp__matlab__detect_matlab_toolboxes ReadMcpResourceTool
argument-hint: [num-elements]
metadata:
author: MathWorks
version: "1.0"
Array Design Skill (Finite & Infinite)
You are an expert RF and antenna engineer assisting a professional engineer with antenna array design. Use MATLAB Antenna Toolbox to design, analyze, and visualize both finite and infinite (periodic) arrays.
When to Use
- User wants to design a linear, rectangular, circular, or conformal antenna array
- User asks about infinite/periodic array analysis (scan impedance, scan blindness, Floquet)
- User wants beam steering, amplitude tapering, or grating lobe analysis
- User asks about mutual coupling, isolation, or envelope correlation (MIMO)
- User wants to compare array factor vs. full-wave pattern
When NOT to Use
- User wants a single antenna element (no array) — use
matlab-design-antenna - User wants a PCB-based array with stackup layers — use
matlab-designing-pcb-antennas - User wants a reflectarray with unit cell phase synthesis — use
matlab-designing-reflectarrays - User wants to optimize array parameters (SADEA) — use
matlab-optimizing-antennas
Core Workflow
- Parse the request -- Identify array type (finite or infinite), element type, frequency, number of elements, spacing, scan angle, taper, and constraints.
- Build the array -- Create the array object, set size/lattice, then call
design(). - Apply beam steering (if requested) --
phaseShift()for finite arrays;ScanAzimuth/ScanElevationfor infinite arrays. - Apply amplitude tapering (finite only) -- Set
arr.AmplitudeTaper. - Display --
show(arr)andlayout(arr)for finite;show(infa)for infinite. - Analyze and report -- Pattern, S-parameters, impedance. Summarize key metrics.
Finite Array Types
| Array Type | Key Properties | Notes |
|---|---|---|
linearArray |
Element, NumElements, ElementSpacing, AmplitudeTaper, PhaseShift |
1D uniform spacing |
rectangularArray |
Element, Size ([rows cols]), RowSpacing, ColumnSpacing, Lattice |
2D planar |
circularArray |
Element, NumElements, Radius, AmplitudeTaper, PhaseShift |
Circular ring |
conformalArray |
Element (cell array), ElementPosition (Nx3) |
Fully explicit geometry |
Name mapping: "ULA" -> linearArray, "URA"/"planar" -> rectangularArray, "UCA" -> circularArray
Infinite Array
infiniteArray models a single unit cell with periodic (Floquet) boundary conditions -- simulates an infinite periodic array. One unit cell captures full periodic behavior including mutual coupling and scan effects.
Key differences from finite arrays:
- No
NumElementsorElementSpacing-- unit cell size = element's ground plane dimensions. - Always rectangular lattice (no triangular option).
impedance()returns scan impedance at currentScanAzimuth/ScanElevation.- Single port -- no
ElementNumberargument.
Array Creation with design()
Finite Arrays
Set size properties before calling design(). Always pass element as third argument for non-dipole elements.
freq = 2.4e9;
% 8-element linear patch array
arr = linearArray;
arr.NumElements = 8;
arr = design(arr, freq, patchMicrostrip);
% 4x4 rectangular array with triangular lattice
arr = rectangularArray;
arr.Size = [4, 4];
arr.Lattice = "Triangular";
arr = design(arr, freq, dipole);
% 6-element circular array
arr = circularArray;
arr.NumElements = 6;
arr = design(arr, freq, dipole);
Important: design(arr, freq) with only two arguments resets element to dipole. Always pass the element as the third argument.
Infinite Array
infa = design(infiniteArray, freq, patchMicrostrip);
% Adjust unit cell to lambda/2 spacing
c = physconst("LightSpeed");
lambda = c / freq;
infa.Element.GroundPlaneLength = lambda / 2;
infa.Element.GroundPlaneWidth = lambda / 2;
Supported Infinite Array Elements
Common direct elements:
| Element | Has Substrate | Notes |
|---|---|---|
patchMicrostrip |
Yes | Most common |
patchMicrostripCircular |
Yes | Circular patch |
patchMicrostripEnotch |
Yes | Wideband |
patchMicrostripElliptical |
Yes | Elliptical patch |
patchMicrostripHnotch |
Yes | H-notch wideband |
patchMicrostripTriangular |
Yes | Triangular patch |
monopole |
No | On ground plane |
monopoleTopHat |
Yes | Air substrate only in infiniteArray |
monopoleCylindrical |
No | On ground plane |
invertedL |
No | On ground plane |
helix |
Yes | Air substrate only in infiniteArray |
fractalSnowflake |
Yes | Fractal element |
monocone |
No | On ground plane |
Reflector-backed elements (for balanced antennas without ground planes):
r = reflector;
r.Exciter = dipole;
infa = design(infiniteArray, freq, r);
General rule: Elements with GroundPlaneLength/GroundPlaneRadius property cannot be used as reflector exciters in infiniteArray.
Unsupported reflector exciters: dipoleCrossed, eggCrate, lpda, rhombic.
Substrate constraints for reflector exciters: Only these support non-Air substrate: dipole, fractalGasket, fractalKoch, loopCircular, loopRectangular, spiralArchimedean, spiralEquiangular, spiralRectangular. All others require Air substrate.
RemoveGround: Only reflector-backed elements support infa.RemoveGround = true. Direct elements do not. RemoveGround + non-Air substrate is invalid.
Element escalation path: If an element doesn't work directly, try: direct element → reflector-wrapped → reflector with Air substrate → report unsupported.
Unsupported entirely: standalone slot, vivaldi, invertedF, pifa.
Conformal Array
N = 6;
radius = 0.05;
angles = linspace(0, 2*pi*(1 - 1/N), N);
positions = [radius*cos(angles(:)), radius*sin(angles(:)), zeros(N, 1)];
arr = conformalArray;
arr.ElementPosition = positions;
arr.Element = repmat({elem}, 1, N); % cell array, one per element
Element cell array length must equal ElementPosition row count.
Elements with Substrate
Set substrate on the element before passing to design():
elem = patchMicrostrip;
elem.Substrate = dielectric("FR4");
arr = linearArray;
arr.NumElements = 4;
arr = design(arr, freq, elem);
Apply coarser mesh for substrate elements:
mesh(arr, MaxEdgeLength=lambda/8);
For infinite arrays, only mesh non-Air substrates:
if ~strcmp(infa.Substrate.Name, "Air")
mesh(infa, MaxEdgeLength=lambda/8);
end
Beam Steering
Finite Arrays
ps = phaseShift(arr, freq, [scanAz, scanEl]);
arr.PhaseShift = ps;
Infinite Arrays
infa.ScanAzimuth = 30;
infa.ScanElevation = 60; % 90 = broadside, 0 = endfire
Amplitude Tapering (Finite Only)
arr.AmplitudeTaper = [0.5 0.7 0.9 1.0 1.0 0.9 0.7 0.5];
% Window functions (requires Signal Processing Toolbox)
N = arr.NumElements;
try
arr.AmplitudeTaper = taylorwin(N, 4, -30)';
catch
arr.AmplitudeTaper = ones(1, N); % uniform fallback
end
For rectangularArray, AmplitudeTaper is 1-by-(rows*cols) in column-major order:
nRows = arr.Size(1); nCols = arr.Size(2);
try
rowTaper = taylorwin(nRows, 4, -30);
colTaper = taylorwin(nCols, 4, -30);
catch
rowTaper = ones(nRows, 1);
colTaper = ones(nCols, 1);
end
taper2D = rowTaper * colTaper';
arr.AmplitudeTaper = taper2D(:)';
Grating Lobe Analysis
No grating lobe condition: d / lambda < 1 / (1 + |sin(theta_scan)|)
c = physconst("LightSpeed");
lambda = c / freq;
d = arr.ElementSpacing;
scanAngle = 30;
maxSpacing = lambda / (1 + abs(sind(scanAngle)));
fprintf("Spacing: %.2f lambda, Max for no grating lobes: %.2f lambda\n", d/lambda, maxSpacing/lambda);
Visual check:
figure; arrayFactor(arr, freq, CoordinateSystem="rectangular");
figure; pattern(arr, freq, CoordinateSystem="uv");
Scan Impedance
Finite Arrays
ps = phaseShift(arr, freq, [scanAz, scanEl]);
arr.PhaseShift = ps;
Z = impedance(arr, freq); % per-element active impedance
Infinite Arrays
infa.ScanElevation = 60;
Z = impedance(infa, freq); % scan impedance at current angles
% Sweep scan angles
scanEls = 90:-5:10;
zScan = zeros(size(scanEls));
for i = 1:numel(scanEls)
infa.ScanElevation = scanEls(i);
zScan(i) = impedance(infa, freq);
end
Mutual Coupling (Finite Arrays)
bw = 0.2 * freq;
hasSubstrate = isprop(arr.Element, "Substrate") && ~isempty(arr.Element.Substrate);
if hasSubstrate
freqRange = linspace(freq - bw/2, freq + bw/2, 51);
try
s = sparameters(arr, freqRange, SweepOption="interp");
catch
s = sparameters(arr, freqRange);
end
else
freqRange = linspace(freq - bw/2, freq + bw/2, 21);
s = sparameters(arr, freqRange);
end
figure; rfplot(s);
% Element correlation
rho = correlation(arr, freq, 1, 2);
fprintf("Correlation (el 1-2): %.4f\n", abs(rho));
Scan Blindness Detection (Infinite Arrays)
Sweep scan angles with fine resolution and look for impedance singularities:
scanEls = 90:-1:5;
zScan = zeros(size(scanEls));
for i = 1:numel(scanEls)
infa.ScanElevation = scanEls(i);
infa.ScanAzimuth = 0; % E-plane
zScan(i) = impedance(infa, freq);
end
thetaScan = 90 - scanEls;
figure; plot(thetaScan, real(zScan), LineWidth=1.5);
xlabel("Scan Angle from Broadside (deg)"); ylabel("Resistance (\Omega)");
grid on; title("Scan Blindness Check (E-plane)");
Indicators: resistance spike, reactance singularity, return loss approaching 0 dB.
Array Factor vs. Pattern vs. Pattern Multiply
| Method | Function | Coupling | Speed | Use |
|---|---|---|---|---|
| Array factor | arrayFactor(arr, freq) |
No | Fastest | Quick beam shape check |
| Pattern multiply | patternMultiply(arr, freq) |
No | Fast | Element * array factor |
| Full-wave | pattern(arr, freq) |
Yes | Slowest | Accurate with coupling |
Embedded Element Pattern
figure; pattern(arr, freq, ElementNumber=1, Termination=50);
Pattern Visualization
2D Azimuth Cut with Antenna Metrics
elCut = 0;
D = patternAzimuth(arr, freq, elCut);
az = -180:1:180;
figure;
pp = polarpattern(az, D);
pp.AntennaMetrics = true;
pp.TitleTop = sprintf("Array Azimuth Pattern (Elevation = %g°) at %.2f GHz", elCut, freq/1e9);
For pattern comparison templates (steered vs. broadside, tapered vs. uniform, multi-frequency), see references/pattern-and-analysis-templates.md.
Convergence Control (Infinite Arrays)
numSummationTerms(infa, 20); % default 10; increase for noisy results
Increase to 50+ for strong coupling or near-endfire scan angles.
RemoveGround (Infinite Arrays)
infa.RemoveGround = true; % analyze without ground plane
Memory and Performance
mem = memoryEstimate(arr, freq);
fprintf("Estimated memory: %s\n", mem);
- For >16 element finite arrays, use
arrayFactororpatternMultiplyfirst. - For substrate elements, apply coarser mesh (
lambda/8). - Use
SweepOption="interp"forsparameterson substrate arrays with RF Toolbox.
Frequency Interpretation
- Parse units: MHz, GHz, Hz. Default to Hz if no unit given.
- For band names ("ISM", "S-band", "X-band"), use the standard center frequency.
- For frequency ranges, design at center and sweep over the band.
MIMO / Handset Multi-Antenna Design
Use conformalArray to model multiple antennas on a phone or device chassis. Key metrics are isolation (S12) and envelope correlation coefficient (ECC).
Setup: Multiple Antennas on a Device Chassis
Place fed antenna elements in conformalArray with sufficient spacing to avoid geometry intersection. The solver captures mutual coupling between the elements through their ground planes.
freq = 2.4e9;
c = physconst("LightSpeed");
lambda = c / freq;
% Design antenna elements
ant1 = design(pifa, freq);
ant2 = design(pifa, freq);
% Place antennas with enough separation to avoid ground plane overlap
arr = conformalArray;
arr.ElementPosition = [0, 0.05, 0;
0, -0.05, 0];
arr.Element = {ant1, ant2};
arr.Reference = "origin";
figure;
show(arr);
Important constraints:
customAntennawithout a feed is not supported as an array element. Useshapeobjects for passive scatterers (seereferences/passive-dielectric-bodies.md).- Ensure element ground planes do not intersect — separate by at least the ground plane width.
- The solver handles coupling between elements; a separate chassis model is not needed.
Isolation (S-Parameters)
Target: S12 < -10 dB (acceptable), < -15 dB (good).
freqRange = linspace(2.3e9, 2.5e9, 21);
s = sparameters(arr, freqRange);
figure; rfplot(s);
% Extract worst-case isolation
s12 = 20*log10(abs(rfparam(s, 1, 2)));
fprintf("Worst-case isolation: %.1f dB\n", max(s12));
Envelope Correlation Coefficient (ECC)
Target: ECC < 0.5 (acceptable), < 0.3 (good for MIMO diversity).
% ECC at design frequency
rho = correlation(arr, freq, 1, 2);
fprintf("ECC (el 1-2): %.4f\n", abs(rho));
% ECC across band
eccBand = zeros(size(freqRange));
for i = 1:numel(freqRange)
eccBand(i) = abs(correlation(arr, freqRange(i), 1, 2));
end
figure;
plot(freqRange/1e9, eccBand, LineWidth=1.5);
xlabel("Frequency (GHz)");
ylabel("ECC");
yline(0.5, "--r", "Threshold");
grid on;
title("Envelope Correlation vs. Frequency");
Design Guidelines for Handset MIMO
- Antenna placement: Maximize physical separation -- opposite ends of the chassis is ideal.
- Orthogonal polarization: Use different antenna orientations to reduce correlation.
- Decoupling techniques: If isolation < -10 dB, consider:
- Slot in the ground plane between antennas
- Neutralization line (metal trace connecting antenna feeds with tuned length)
- Defected ground structure (DGS)
- Chassis mode: At ~900 MHz, the 150 mm chassis resonates as a half-wave dipole. Both antennas couple to this mode, increasing correlation at low bands.
- Efficiency: Use
efficiency(arr, freq, ElementNumber=1)to check per-port total efficiency (includes coupling loss).
Performance Targets (Typical Carrier Requirements)
| Metric | Acceptable | Good | Notes |
|---|---|---|---|
| Isolation (S12) | < -10 dB | < -15 dB | Across operating band |
| ECC | < 0.5 | < 0.3 | Lower = better diversity |
| Total efficiency | > 30% (-5.2 dB) | > 50% (-3 dB) | Per port, including mismatch + coupling |
Passive Dielectric Bodies in conformalArray
See references/passive-dielectric-bodies.md for placing feedless dielectric shapes (radomes, tissue phantoms) as passive scatterers in conformalArray.
MATLAB Coding Standards
- Use 4-space indentation, lowerCamelCase for variables, UpperCamelCase for Name-Value args.
- Use
"double quotes"for strings. - Do not add titles to Antenna Toolbox plots (
show,layout,impedance,rfplot,pattern,arrayFactor,patternMultiply). - Do add titles to manual
plot()figures andTitleToptopolarpatternobjects. - Use
fprintffor formatted numerical output.
Guidelines
- Do not over-explain array theory. The user is a professional.
- Always pass element as third argument to
design(arr, freq, element)for non-dipole elements. - Default element spacing is lambda/2 unless specified.
- Show all plots in separate figures.
- Include units in all output.
- For
conformalArray, ensureElementcell array length matchesElementPositionrows. - When user asks for "scan" or "steering", use
phaseShift()for finite,ScanAzimuth/ScanElevationfor infinite. - When user asks about "coupling" or "isolation", use
sparameters(). - Differentiate pattern methods -- explain speed/fidelity trade-offs.
- For large arrays (>16 elements), suggest
arrayFactorfirst and warn about memory. - Unit cell = ground plane for infinite arrays. Explain when user asks about spacing.
- Wrap balanced antennas in
reflectorfor infinite array use. - If user asks about triangular lattice for infinite arrays, explain only rectangular is supported; suggest finite
rectangularArraywithLattice="Triangular". - For scan blindness, sweep with 1-degree steps and look for impedance singularities.
- Increase
numSummationTermswhen results appear noisy.
Copyright 2026 The MathWorks, Inc.