Effacer les filtres
Effacer les filtres

Matlab equivalent of Maple's remove_RootOf

24 vues (au cours des 30 derniers jours)
Alec Jacobson
Alec Jacobson le 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?

Réponse acceptée

Walter Roberson
Walter Roberson le 8 Nov 2022
Modifié(e) : Walter Roberson le 8 Nov 2022
Use children()
Maybe arrayfun @(X)children(X, 1)
  2 commentaires
Alec Jacobson
Alec Jacobson le 8 Nov 2022
This is great! from children I can also get z symbolically so I don't have to hard code it.
Walter Roberson
Walter Roberson le 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.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Symbolic Math Toolbox dans Help Center et File Exchange

Produits


Version

R2020a

Community Treasure Hunt

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

Start Hunting!

Translated by