How can I find the roots of a symbolic polynimial
135 views (last 30 days)
Show older comments
Ron Aditya
on 20 Dec 2014
Commented: Sansit Patnaik
on 23 Mar 2017
I create a symbolic transfer function matrix. I find its inverse. The first element of the matrix is a polynomial. Note that this polynomial is symbolic so no operation can be done on it. I want to convert this to a polynomial and find the roots. How should I go about this? Thanks.
aa =
- 30*s^4 + 300*s^3
>> coeffs(aa)
ans =
[ 300, -30]
Here aa is the polynomial I go ahead and extract the coefficients and then i can do a "aa=double(aa)" to convert it to double. And then find the roots. But the problem is When I do the coeffs(aa) i should get [-30 300 0 0] and not [300 -30]. Even if I get [0 0 300 -30], I can get my way through. But the issue is i need those missing zeros (coefficients of s^2 and s^1).
Thanks,
0 Comments
Accepted Answer
John D'Errico
on 20 Dec 2014
Edited: John D'Errico
on 20 Dec 2014
No. It simply is not true that NO operation can be done on that polynomial.
syms s
p = -30*s^4 + 300*s^3;
solve( p )
ans =
0
0
0
10
vpasolve( p )
ans =
0
0
0
10.0
Both of those tools operate directly on symbolic polynomials. Yes, I could also have converted it into a polymonial as a vector of coefficients, then used roots. But that may, for some polynomials, be more prone to numerical error.
roots(sym2poly(p))
ans =
0
0
0
10
For an extreme case of why the roots path may be less than the best solution, try this:
p = expand((s-1)^15)
p =
s^15 - 15*s^14 + 105*s^13 - 455*s^12 + 1365*s^11 - 3003*s^10 + 5005*s^9 - 6435*s^8 + 6435*s^7 - 5005*s^6 + 3003*s^5 - 1365*s^4 + 455*s^3 - 105*s^2 + 15*s - 1
roots(sym2poly(p))
ans =
1.209 + 0i
1.1857 + 0.091966i
1.1857 - 0.091966i
1.1237 + 0.15986i
1.1237 - 0.15986i
1.0424 + 0.19023i
1.0424 - 0.19023i
0.96223 + 0.18319i
0.96223 - 0.18319i
0.89706 + 0.14756i
0.89706 - 0.14756i
0.85307 + 0.094232i
0.85307 - 0.094232i
0.8314 + 0.032225i
0.8314 - 0.032225i
solve(p)
ans =
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
vpasolve(p)
ans =
1.0
1.0
1.0
1.0
1.0
1.0
1.0
1.0
1.0
1.0
1.0
1.0
1.0
1.0
1.0
As you can see, both solve and vpasolve had no problems, while roots was a bit less accurate. Admittedly, this is a nasty test case for roots. Of course I chose that test case because I knew roots would have a hard time with a problem with many multiple roots.
So had I given a different test case
syms s
p = expand(prod(s - (1:15)))
p =
s^15 - 120*s^14 + 6580*s^13 - 218400*s^12 + 4899622*s^11 - 78558480*s^10 + 928095740*s^9 - 8207628000*s^8 + 54631129553*s^7 - 272803210680*s^6 + 1009672107080*s^5 - 2706813345600*s^4 + 5056995703824*s^3 - 6165817614720*s^2 + 4339163001600*s - 1307674368000
roots(sym2poly(p))
ans =
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
Here roots worked very well. In fact, understanding how roots works can help you to know why this case worked well with roots and the first fails. The problem is, you don't always know when you will find something that will be problematic. So if you are starting with a symbolic polynomial, then it would in general be best to use a tool designed for that if you can do so. So, lets see what happens here...
roots(sym2poly(p-1))
ans =
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
Oops. Subtracting 1 from p should have shifted the roots by just a tiny amount. vpasolve does a lot better.
vpasolve(p-1)
ans =
1.0000000000114707455981575587965
1.9999999998394095616880079532128
3.0000000010438378511402592310782
3.9999999958246486231120653234589
5.0000000114822164548170589408461
5.9999999770355676010939194536657
7.0000000344466493478141158541341
7.9999999606324011085914925439765
9.0000000344466487121507429640661
9.9999999770355670255962156025775
11.000000011482216231837857685089
11.999999995824648581740694564924
13.000000001043837847646550678815
13.99999999983940956157555975473
15.000000000011470745597301890631
1 Comment
Sansit Patnaik
on 23 Mar 2017
Hey, when i use solve(p) here i get the following: ans =
[ 15 Element Column Vector ]
[ Data Type: anything ]
[ Storage: rectangular ]
[ Order: Fortran_order ]
Suggest me please !
More Answers (2)
Azzi Abdelmalek
on 20 Dec 2014
Edited: Azzi Abdelmalek
on 20 Dec 2014
use sym2poly instead of coeffs
syms s
aa=- 30*s^4 + 300*s^3
b=sym2poly(aa)
If you want another order
c=fliplr(b)
4 Comments
John D'Errico
on 20 Dec 2014
Why would you recommend accepting an answer this is less complete, that suggests solving the problem using a less accurate solution, when a better solution is suggested in a different response?
Ron Aditya
on 20 Dec 2014
2 Comments
John D'Errico
on 20 Dec 2014
Edited: John D'Errico
on 20 Dec 2014
It works for me.
clear
syms s
p=30*s^2+40*s+9
p =
30*s^2 + 40*s + 9
solve(p)
ans =
- 130^(1/2)/30 - 2/3
130^(1/2)/30 - 2/3
solve(p,s)
ans =
- 130^(1/2)/30 - 2/3
130^(½)/30 - 2/3
vpa(solve(p,s))
ans =
-1.0467251416997126597120163418556
-0.28660819163362067362131699147775
I would suggest that you have done something wrong. Perhaps you redefined the variable s or p somehow before you called solve. Perhaps you defined a function called solve. Perhaps you defined those variables in some other way, and were not careful when you did that test.
I would suggest using clear before you make that test if you are not sure what you are doing. If all else fails, then you might try this:
which solve -all
Is it possible that you moved some of the functions outside of the symbolic toolbox? This is a very basic operation with that toolbox, so if it does not work as I have shown, then it means you may need to reinstall that toolbox.
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!