MATLAB中绘制系统零极点图(Pole-Zero Map)的几种方法

以下是 MATLAB中绘制系统零极点图(Pole-Zero Map) 的常见方法及各自适用场景总结,适用于你当前在分析符号表达式/系统传函后的使用需求:

✅ 方法一:pzmap(tf(num, den)) (最常用,推荐)

📌 用法:

num_coeffs = sym2poly(num);
den_coeffs = sym2poly(den);
sys = tf(num_coeffs, den_coeffs);
pzmap(sys);

✅ 优点:

  • 容错性强:即使系统是常数、纯零阶、或奇异形式,也能画。
  • 可用于 传递函数对象 tf
  • 支持绘制多个系统的极点/零点图叠加。

⚠️ 注意事项:

  • 不返回零极点坐标,仅用于绘图

✅ 方法二:[z, p, k] = tf2zp(num, den)(需要系数格式正确)

📌 用法:

[z, p, ~] = tf2zp(num_coeffs, den_coeffs);
plot(real(p), imag(p), 'x'); % 极点
plot(real(z), imag(z), 'o'); % 零点

✅ 优点:

  • 返回极点、零点的具体数值,适用于进一步处理或自定义绘图
  • 可与 plot()scatter() 等灵活搭配。

⚠️ 注意事项:

  • 输入必须为一维行向量,不能含 NaNInf

  • 如果输入是符号表达式处理后得到的,需要使用:

    num_coeffs = double(sym2poly(num(:).'));
    

✅ 方法三:[z, p, k] = zpkdata(tf(...), 'v')(稳定提取数值)

📌 用法:

sys = tf(num_coeffs, den_coeffs);
[z, p, ~] = zpkdata(sys, 'v');

✅ 优点:

  • 更鲁棒,不容易因为格式问题报错。
  • 适合从传递函数对象中提取零极点数值。

⚠️ 注意事项:

  • 需要用 tf(...) 构造系统对象。

✅ 方法四:roots(num)roots(den) (适合单独计算)

📌 用法:

z = roots(num_coeffs);
p = roots(den_coeffs);

✅ 优点:

  • 轻量级函数,只需计算零点/极点而不构造系统。
  • 可用于系统分析或手动画图。

⚠️ 注意事项:

  • 没有增益项 k,只适合基础分析。

✅ 方法五:符号工具箱方式(symbolic)

如果你的系统是符号表达式,可以先转换为多项式,再用上面方法处理:

[num, den] = numden(sym_expr);           % 获取分子分母
num_coeffs = double(sym2poly(num));      % 多项式系数
den_coeffs = double(sym2poly(den));
[z, p, ~] = tf2zp(num_coeffs, den_coeffs);

📊 方法选择建议对比表

方法是否返回零极点数值容错性是否需要系统对象推荐用途
pzmap(tf(...))✅✅✅快速画图
tf2zp(num, den)⚠️精准提取零极点
zpkdata(tf(...))✅✅稳定提取零极点
roots(...)只求零点或极点
符号方法 + sym2poly⚠️⚠️从符号转数值

如你正在处理的是频率响应分析、稳定性边界研究、或者要对极点位置进行分类,建议用 tf2zpzpkdata 提取后自行绘图、分区标色。也可以结合 scatter()text() 自定义标注。

🎯 示例传递函数:

本文选用如下复杂的20阶传递函数作为统一实例:

H(s)=s20+14s19+65s18+⋯+10s+5s20+16s19+85s18+⋯+30s+10 H(s) = \frac{s^{20} + 14 s^{19} + 65 s^{18} + \cdots + 10 s + 5}{s^{20} + 16 s^{19} + 85 s^{18} + \cdots + 30 s + 10} H(s)=s20+16s19+85s18++30s+10s20+14s19+65s18++10s+5

其中分子和分母多项式系数均为给定的20阶多项式系数,充分体现了高阶系统零极点分析的复杂性。

clc; clear; close all;
% -----------------------------
% 构造符号多项式(20阶复杂多项式)
% -----------------------------
syms s

num_poly = s^20 + 14*s^19 + 65*s^18 + 210*s^17 + 500*s^16 + 900*s^15 + ...
           1200*s^14 + 1100*s^13 + 900*s^12 + 700*s^11 + 500*s^10 + ...
           300*s^9 + 200*s^8 + 150*s^7 + 120*s^6 + 90*s^5 + 60*s^4 + ...
           40*s^3 + 20*s^2 + 10*s + 5;

den_poly = s^20 + 16*s^19 + 85*s^18 + 290*s^17 + 650*s^16 + 1100*s^15 + ...
           1500*s^14 + 1400*s^13 + 1200*s^12 + 900*s^11 + 600*s^10 + ...
           400*s^9 + 300*s^8 + 220*s^7 + 180*s^6 + 130*s^5 + 100*s^4 + ...
           70*s^3 + 50*s^2 + 30*s + 10;

% -----------------------------
% 从符号多项式提取数值多项式系数(降幂顺序)
% -----------------------------
num_coeffs = double(coeffs(num_poly, s, 'All'));
den_coeffs = double(coeffs(den_poly, s, 'All'));

% 构造数值传递函数对象
sys_tf = tf(num_coeffs, den_coeffs);

% -----------------------------
% 创建图窗和子图
% -----------------------------
figure('Name','20阶系统极点零点图对比','Color','w','Position',[100 100 1200 800]);

% -----------------------------
% 方法一:pzmap
% -----------------------------
subplot(2,3,1);
pzmap(sys_tf);
title('方法①:pzmap(tf)');
grid on;

% -----------------------------
% 方法二:tf2zp
% -----------------------------
[z2, p2, ~] = tf2zp(num_coeffs, den_coeffs);
subplot(2,3,2);
plot(real(p2), imag(p2), 'rx', 'MarkerSize', 8); hold on;
plot(real(z2), imag(z2), 'bo', 'MarkerSize', 8);
title('方法②:tf2zp + plot');
xlabel('实部'); ylabel('虚部');
axis equal; grid on; legend('极点', '零点');

% -----------------------------
% 方法三:zpkdata
% -----------------------------
[z3, p3, ~] = zpkdata(sys_tf, 'v');
subplot(2,3,3);
scatter(real(p3), imag(p3), 60, 'r', 'x'); hold on;
scatter(real(z3), imag(z3), 60, 'b', 'o');
title('方法③:zpkdata + scatter');
xlabel('实部'); ylabel('虚部');
axis equal; grid on; box on; legend('极点', '零点');

% -----------------------------
% 方法四:roots
% -----------------------------
z4 = roots(num_coeffs);
p4 = roots(den_coeffs);
subplot(2,3,4);
plot(real(p4), imag(p4), 'rx', 'MarkerSize', 8); hold on;
plot(real(z4), imag(z4), 'bo', 'MarkerSize', 8);
title('方法④:roots');
xlabel('实部'); ylabel('虚部');
axis equal; grid on; legend('极点', '零点');

% 方法五:symbolic(修正后)
% -----------------------------
num_sym = poly2sym(num_coeffs, s);
den_sym = poly2sym(den_coeffs, s);
Hs_sym = num_sym / den_sym;

% 提取分子分母多项式
[num_numer, num_denom] = numden(Hs_sym);

% coeffs 默认返回升幂排列,需 flip 为降幂
num_coeffs_sym = double(flip(coeffs(num_numer, s)));
den_coeffs_sym = double(flip(coeffs(num_denom, s)));

% 计算零极点
z5 = roots(num_coeffs_sym);
p5 = roots(den_coeffs_sym);

subplot(2,3,5);
scatter(real(p5), imag(p5), 60, 'r', 'x'); hold on
scatter(real(z5), imag(z5), 60, 'b', 'o'); hold on;
title('方法⑤:symbolic + sym2poly(修正)');
xlabel('实部'); ylabel('虚部');
axis equal; grid on; box on; legend('极点','零点');

% -----------------------------
% 总标题
% -----------------------------
sgtitle('⚙复杂20阶系统极点-零点图五种方法对比', 'FontSize', 14, 'FontWeight', 'bold');

在这里插入图片描述
这段代码展示了五种绘制系统零极点的方法,各有优劣:

  • 方法①(pzmap):调用方便,直接绘图,适合快速观察,但灵活性较低,图形大小和样式受限,无法直接获取极零点数据。
  • 方法②(tf2zp):通过传递函数系数计算零极点,能够获得数值数据,便于自定义绘图,但对高阶多项式可能存在数值精度问题。
  • 方法③(zpkdata):直接从系统对象获取零极点,精度高且简单,但要求传递函数对象格式正确。
  • 方法④(roots):基于多项式根计算,灵活且通用,能处理任意多项式,但多项式系数的准确性对结果影响较大。
  • 方法⑤(symbolic + sym2poly):利用符号计算避免数值误差,适合高精度需求,但计算速度较慢,代码复杂度较高。

综上,快速分析推荐方法①,精确数值计算推荐方法③或方法④,而方法⑤适合符号推导和高精度场景。根据具体需求灵活选择即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱代码的小黄人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值