How can I use the function coeffs() as the input to the function tf()?

조회 수: 6 (최근 30일)
Paul
Paul 2025년 3월 10일
답변: Paul 2025년 3월 10일
This code works to give me the root locus of my system, but I have to manually enter the coefficients
num = [1, 117/10, 24477/400, 5584/125, -2315137/40000, 36905889/40000, -66965649/160000, -921912043/80000, 34652192177/640000, -4796713113/25600, 62141795103/160000, -223688325847/320000, 32896376299/40000, -7904756769/10000, 708588777/2000, -52514891/800];
den = [1, -4/5, -5929/400, -14969/2000, 56007543/160000, -550116261/400000, 187999365153/64000000, -1333141873017/320000000, 1759926060179/400000000, -120268082137481/32000000000, 819503408996093/320000000000, -4388359670461129/3200000000000, 338687548373223/640000000000, -1907357941873611/12800000000000, 306186935180877/10240000000000, -4892378756049/1024000000000]
sys = tf(num,den);
rlocus(sys);
However, the following code is not working. I imagine that the output of coeffs() &/or fliplr() is not technically an array despite appearing so when I print the output.
syms s
n = (s^2+10*s+50)*(s^2+8.6*s+21.73)*(s^2-0.7*s+0.1625)*(s^2-2*s+3.25)^2*(s^2+4)^2*(s-2.2);
x = expand(n);
d = (s^2+8.6*s+26.33)*(s^2+0.3*s+0.6625)*(s^2+0.09)*(s^2-0.8*s+0.25)*(s^2-0.9*s+0.5625)*(s^2-2*s+2.69)*(s^2-4*s+4.0225)*(s-2);
y = expand(d);
num = coeffs(x);
num = fliplr(num)
den = coeffs(y);
den = fliplr(den)
sys = tf(num,den); %error line
figure(1)
rlocus(sys)
If someone could help me figure out how to modify the second chunk of code so that the transfer function is created that would be much appreaciated.

채택된 답변

Sam Chak
Sam Chak 2025년 3월 10일
syms s
n = (s^2+10*s+50)*(s^2+8.6*s+21.73)*(s^2-0.7*s+0.1625)*(s^2-2*s+3.25)^2*(s^2+4)^2*(s-2.2);
x = expand(n)
x = 
d = (s^2+8.6*s+26.33)*(s^2+0.3*s+0.6625)*(s^2+0.09)*(s^2-0.8*s+0.25)*(s^2-0.9*s+0.5625)*(s^2-2*s+2.69)*(s^2-4*s+4.0225)*(s-2);
y = expand(d)
y = 
num = coeffs(x);
num = double(fliplr(num))
num = 1×16
1.0e+05 * 0.0000 0.0001 0.0006 0.0004 -0.0006 0.0092 -0.0042 -0.1152 0.5414 -1.8737 3.8839 -6.9903 8.2241 -7.9048 3.5429 -0.6564
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
den = coeffs(y);
den = double(fliplr(den))
den = 1×16
1.0e+03 * 0.0010 -0.0008 -0.0148 -0.0075 0.3500 -1.3753 2.9375 -4.1661 4.3998 -3.7584 2.5609 -1.3714 0.5292 -0.1490 0.0299 -0.0048
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
sys = tf(num,den); %error line
figure(1)
rlocus(sys)

추가 답변 (2개)

Voss
Voss 2025년 3월 10일
The error message states:
"The values of the "Numerator" and "Denominator" properties must be row vectors or cell arrays of row vectors, where each vector is nonempty and containing numeric data."
In the first code snippet you posted num and den are numeric, so tf works; in the second num and den are symbolic, so tf throws the error. See: Choose Numeric Or Symbolic Arithmetic
You can convert the symbolic num and den to numeric (specifically, double-precision floating point) values using the double function:
syms s
n = (s^2+10*s+50)*(s^2+8.6*s+21.73)*(s^2-0.7*s+0.1625)*(s^2-2*s+3.25)^2*(s^2+4)^2*(s-2.2);
x = expand(n);
d = (s^2+8.6*s+26.33)*(s^2+0.3*s+0.6625)*(s^2+0.09)*(s^2-0.8*s+0.25)*(s^2-0.9*s+0.5625)*(s^2-2*s+2.69)*(s^2-4*s+4.0225)*(s-2);
y = expand(d);
num = coeffs(x);
num = fliplr(num)
num = 
den = coeffs(y);
den = fliplr(den)
den = 
% sys = tf(num,den); %error line
sys = tf(double(num),double(den));
figure(1)
rlocus(sys)

Paul
Paul 2025년 3월 10일
Unless there are reasons to use syms other then to compute the polynomials, it's probably better and easier to avoid syms altogether.
Instead
s = tf('s');
n = (s^2+10*s+50)*(s^2+8.6*s+21.73)*(s^2-0.7*s+0.1625)*(s^2-2*s+3.25)^2*(s^2+4)^2*(s-2.2);
d = (s^2+8.6*s+26.33)*(s^2+0.3*s+0.6625)*(s^2+0.09)*(s^2-0.8*s+0.25)*(s^2-0.9*s+0.5625)*(s^2-2*s+2.69)*(s^2-4*s+4.0225)*(s-2);
h = n/d;
rlocus(h)
Or find the roots of each term in n and d and go to zpk form.
If really need or want to use syms with coeffs, you're already aware of the fliplr issue. But, using coeffs that way will ignore zero coefficients, which will lead to an error in the Control System Toolbox.
For example
syms s
n = 3*s^3 + 1;
num = double(fliplr(coeffs(n))) % should be [3 0 0 1]
num = 1×2
3 1
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
To get all of the coefficients, use the 'All' option. But with 'All' the coefficients come out from highest to lowest degree, so don't flip
num = double(coeffs(n,'All'))
num = 1×4
3 0 0 1
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>

카테고리

Help CenterFile Exchange에서 Symbolic Math Toolbox에 대해 자세히 알아보기

제품


릴리스

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by