Matlab equivalent of Maple's remove_RootOf
2 views (last 30 days)
Show older comments
Alec Jacobson
on 8 Nov 2022
Commented: Walter Roberson
on 8 Nov 2022
I have a symbolic expression of the form root(…). I'd to recover the operand as a symbolic expression itself. I believe this would require the symbolic toolbox equivalent of maple's remove_RootOf function.
Here's a minified example (also interested in workarounds for what I'm trying to do, but I'd appreciate an answer to the direct original question, too):
syms('a');
syms('b');
syms('t');
sres = solve( b + (a - b)/t^2 - (t*b)/(t - 1)^2 == 0,t)
This results in:
sres =
root(b*z^4 - 3*b*z^3 + a*z^2 + 2*b*z - 2*a*z - b + a, z, 1)
root(b*z^4 - 3*b*z^3 + a*z^2 + 2*b*z - 2*a*z - b + a, z, 2)
root(b*z^4 - 3*b*z^3 + a*z^2 + 2*b*z - 2*a*z - b + a, z, 3)
root(b*z^4 - 3*b*z^3 + a*z^2 + 2*b*z - 2*a*z - b + a, z, 4)
What I'd like as an expression is
b*z^4 - 3*b*z^3 + a*z^2 + 2*b*z - 2*a*z - b + a
The reason that I want this is that I'd like to call roots to numerically solve for t given (many different) numerical values of a and b. I realize I could also do:
% Build a function that computes numerical roots using vpa
vroots = @(A,B) double(vpa(subs(sres,{a,b},[A,B])));
but this is 100× to 1000× slower than it's roots counterpart:
% Extreme hack to strip off 'roots('; strsplit is needed because str2sym will
% choke on longer inputs
spoly = sum(cellfun(@(s) str2sym(s),strsplit(regexprep(sprintf('%s',sres(1)),'^root\((.*),.*,.*$','$1'),' + ')));
syms('z');
polyfun = matlabFunction(flip(coeffs(spoly,z)),'Vars',{a,b});
% Build a function that computes numerical roots using roots. 100× to 1000×
% faster than vroots
nroots = @(A,B) roots(polyfun(A,B));
For example:
timeit(@()vroots(1,1)) / timeit(@()nroots(1,1))
results in something like 700 on my machine and both answers are high enough precision.
So, as you can see above. I currently have a pretty wild hack to get the expression from inside root(…) using string manipulation. Is there a more direct and less fragile way?
0 Comments
Accepted Answer
Walter Roberson
on 8 Nov 2022
Edited: Walter Roberson
on 8 Nov 2022
Use children()
Maybe arrayfun @(X)children(X, 1)
2 Comments
Walter Roberson
on 8 Nov 2022
Yes, getting the variable from the expression is best. I have very seldom seen it generate anything other than z even for nested rootOf, but I have seen z1 and z2 a small number of times.
More Answers (0)
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!