如何在MATLAB中统计多项式的重根?
如何在MATLAB中统计多项式的重根?
看起来你已经尝试用roots()和uniquetol()处理多项式根,但对复数根的唯一性判断、重根统计还有点拿不准对吧?别着急,咱们一步步来解决这个问题。
首先要告诉你一个好消息:uniquetol()本身是支持复数比较的!它会同时对比复数的实部和虚部,默认用欧几里得距离来判断两个复数是否“足够接近”(也就是你传入的精度阈值)。不过你当前的代码里有个小问题——最后又调用了一次不带参数的uniquetol(r),这会覆盖之前用指定精度处理的结果,得把这个多余的调用删掉才行。
接下来,咱们聊聊怎么统计重根的数量和每个根的重数,还能顺便验证根的准确性:
改进后的函数实现
function [unique_roots, multiplicities, root_errors] = polyroots(coeffs, varargin) % 设置默认精度,用户也可以自定义传入 tol = 1e-6; if nargin == 2 tol = varargin{1}; end % 获取所有根(包括复数根) all_roots = roots(coeffs); % 去重,同时获取每个根对应的分组索引 [unique_roots, ~, group_idx] = uniquetol(all_roots, tol); % 统计每个唯一根的重数 multiplicities = histcounts(group_idx, length(unique_roots)); % 验证根的精度:将根代入多项式,计算误差(越接近0越准确) root_errors = abs(polyval(coeffs, unique_roots)); % 可选:输出重根信息 fprintf('多项式次数:%d\n', length(coeffs)-1); fprintf('唯一根数量:%d\n', length(unique_roots)); fprintf('重根总重复次数:%d\n', length(all_roots)-length(unique_roots)); end
代码说明
- 复数根的去重:
uniquetol(all_roots, tol)会自动处理复数,只要两个复数的实部和虚部差异都在tol范围内,就会被判定为同一个根。 - 重数统计:
group_idx数组记录了原根列表中每个元素属于哪个唯一根组,用histcounts统计每个组的元素个数,就是对应根的重数。 - 精度验证:用
polyval()把每个根代入原多项式,计算绝对值误差——如果误差远大于你设置的tol,说明这个根的数值精度可能有问题,需要调整阈值或者检查多项式系数。
使用示例
比如对于多项式(x-2)^3*(x+1)^2,它的系数是[1 -4 -3 18 -8],调用函数:
[ur, mult, err] = polyroots([1 -4 -3 18 -8], 1e-6);
你会得到:
ur = [-1; 2]:两个唯一根mult = [2; 3]:-1是2重根,2是3重根err会是非常小的数值(接近0),说明根的精度没问题
注意事项
- 精度阈值
tol的选择:太小可能会把数值误差导致的“近似重根”当成不同根;太大则可能把相近的不同根误判为重根。一般可以参考eps * norm(all_roots)来设置,或者根据你的计算需求调整。 - 符号计算备选方案:如果你的多项式系数是精确值(比如整数),也可以用符号计算来准确获取重根,示例如下:
不过符号计算对于高次多项式来说,速度可能会慢一些,适合小次数的精确计算场景。syms x; p = poly2sym([1 -4 -3 18 -8]); symbolic_roots = roots(p); % 用factor()还能直接看到多项式的因式分解,直观看到重根 factor(p)
备注:内容来源于stack exchange,提问作者Snork Maiden
相关产品推荐
相关产品推荐

