フィルターのクリア

Matlab equivalent of Maple's remove_RootOf

24 ビュー (過去 30 日間)
Alec Jacobson
Alec Jacobson 2022 年 11 月 8 日
コメント済み: Walter Roberson 2022 年 11 月 8 日
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?

採用された回答

Walter Roberson
Walter Roberson 2022 年 11 月 8 日
編集済み: Walter Roberson 2022 年 11 月 8 日
Use children()
Maybe arrayfun @(X)children(X, 1)
  2 件のコメント
Alec Jacobson
Alec Jacobson 2022 年 11 月 8 日
This is great! from children I can also get z symbolically so I don't have to hard code it.
Walter Roberson
Walter Roberson 2022 年 11 月 8 日
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.

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeSymbolic Math Toolbox についてさらに検索

製品


リリース

R2020a

Community Treasure Hunt

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

Start Hunting!

Translated by