MATLAB根函数在MATLAB和Simulink中的不同行为?
我在MATLAB中实现了以下用户定义的函数:MATLAB根函数在MATLAB和Simulink中的不同行为?,matlab,simulink,matlab-coder,Matlab,Simulink,Matlab Coder,我在MATLAB中实现了以下用户定义的函数: function Q = Calc_Q(Head, freq) b6 = [3.7572E-07 -1.5707E-05 6.0490E-03 5.0018E-02 2.1180E-01]; b5 = [-9.0927E-06 8.9033E-04 -3.2415E-02 5.4525E-01 -8.1649E+00] / 10e2; b4 = [7.5172E-06 -5.6565E-04 1.0024E-02 3.5888E-01 3.8894E
function Q = Calc_Q(Head, freq)
b6 = [3.7572E-07 -1.5707E-05 6.0490E-03 5.0018E-02 2.1180E-01];
b5 = [-9.0927E-06 8.9033E-04 -3.2415E-02 5.4525E-01 -8.1649E+00] / 10e2;
b4 = [7.5172E-06 -5.6565E-04 1.0024E-02 3.5888E-01 3.8894E-02] / 10e5;
b3 = [-4.8767E-06 4.8787E-04 -1.3311E-02 -1.2189E-01 -5.3522E+00] / 10e8;
b2 = [5.9227E-06 -8.1716E-04 3.5392E-02 -4.5413E-01 1.9547E+00] / 10e11;
b1 = [-2.0004E-06 2.9027E-04 -1.3754E-02 2.3490E-01 -1.2363E+00] / 10e14;
a = [polyval(b1,abs(freq)), polyval(b2, abs(freq)), polyval(b3, abs(freq)), polyval(b4, abs(freq)), polyval(b5, abs(freq)), polyval(b6, abs(freq)) - Head];
Q_roots = roots(a);
%Delete roots with imaginary part
i = 1;
while i <= length(Q_roots)
if(imag(Q_roots(i)) ~= 0)
Q_roots(i) = [];
i = i - 1;
end
i = i + 1;
end
%Delete roots with real part greater then 3100
i = 1;
while i <= length(Q_roots)
if(Q_roots(i) >= 3100 || Q_roots(i) < 0)
Q_roots(i) = [];
i = i - 1;
end
i = i +1;
end
if freq < 0
Q = real(Q_roots(1)) * -1;
else
Q = real(Q_roots(1));
end
end
有什么想法吗 我发现了问题 来自不同论坛: 嗨,科斯敏 我看了一下嵌入式MATLAB的根的实现 函数块(\toolbox\eml\lib\matlab\polyfun\root.m)。 上面写着: %限制:%s输出大小始终可变。%输出为 总是很复杂根的顺序可能与MATLAB不同。% 条件较差的多项式的根可能与MATLAB不匹配。最后 句子让你头疼(是的,你的多项式是 条件差!)。如果你看一下情节,你会发现 曲线几乎不接触x轴 不过我有一个建议:值-z/b是一个(非常)好的值 要查找的根的近似值 提图斯 显然,simulink中的根函数并不总能找到给定多项式的所有根。 这是不幸的,不容易解决。但我确实找到了解决办法 对于我要解的所有不同多项式,我知道我感兴趣的根的区间([-3000,3000]) 我基本上只需要从-3000到3000执行50步,直到函数降到0以下。然后我知道根的近似解。我使用这个近似作为牛顿-拉斐逊方法的种子 用给定的种子直接实现牛顿-拉斐逊方法来求解我必须求解的所有多项式是行不通的,因为有时它会迭代到不同的根(我不感兴趣的根) 代码如下:
function Q = Calc_Q(Head, freq)
b6 = [3.7572E-07 -1.5707E-05 6.0490E-03 5.0018E-02 2.1180E-01];
b5 = [-9.0927E-06 8.9033E-04 -3.2415E-02 5.4525E-01 -8.1649E+00] / 10e2;
b4 = [7.5172E-06 -5.6565E-04 1.0024E-02 3.5888E-01 3.8894E-02] / 10e5;
b3 = [-4.8767E-06 4.8787E-04 -1.3311E-02 -1.2189E-01 -5.3522E+00] / 10e8;
b2 = [5.9227E-06 -8.1716E-04 3.5392E-02 -4.5413E-01 1.9547E+00] / 10e11;
b1 = [-2.0004E-06 2.9027E-04 -1.3754E-02 2.3490E-01 -1.2363E+00] / 10e14;
%coeff for the polynominal
a = [polyval(b1,abs(freq)), polyval(b2, abs(freq)), polyval(b3, abs(freq)), polyval(b4, abs(freq)), polyval(b5, abs(freq)), polyval(b6, abs(freq)) - Head];
%coeff for the derrivative of polynominal
da = [5*a(1) 4*a(2) 3*a(3) 2*a(4) a(5)];
Q = -3000;
%Search for point where function goes below 0
while (polyval(a, Q) > 0)
Q = Q + 25;
end
error_max = 0.01
iter_counter = 1;
while abs(polyval(a,Q)) >= error_max && iter_counter <= 1000
Q = Q - polyval(a, Q)/polyval(da, Q);
iter_counter = iter_counter + 1;
error = abs(polyval(a,Q));
end
if(freq < 0)
Q = Q * - 1;
end
end
函数Q=Calc_Q(水头、频率)
b6=[3.7572E-07-1.5707E-05 6.0490E-03 5.0018E-02 2.1180E-01];
b5=[-9.0927E-06 8.9033E-04-3.2415E-02 5.4525E-01-8.1649E+00]/10e2;
b4=[7.5172E-06-5.6565E-04 1.0024E-02 3.5888E-01 3.8894E-02]/10e5;
b3=[-4.8767E-06 4.8787E-04-1.3311E-02-1.2189E-01-5.3522E+00]/10e8;
b2=[5.9227E-06-8.1716E-04 3.5392E-02-4.5413E-01 1.9547E+00]/10e11;
b1=[-2.0004E-06 2.9027E-04-1.3754E-02 2.3490E-01-1.2363E+00]/10e14;
%多项式系数
a=[polyval(b1,abs(频率)),polyval(b2,abs(频率)),polyval(b3,abs(频率)),polyval(b4,abs(频率)),polyval(b5,abs(频率)),polyval(b6,abs(频率))-头部];
%多项式的竞争系数
da=[5*a(1)4*a(2)3*a(3)2*a(4)a(5)];
Q=-3000;
%搜索函数低于0的点
while(polyval(a,Q)>0)
Q=Q+25;
结束
误差_max=0.01
iter_计数器=1;
当abs(polyval(a,Q))>=error\u max&&iter\u counter时,问题很可能是由于您的逻辑消除了虚部中不完全为零的任何根。这是一种数学思维方式,在数值上并不有效,至少在一般情况下不有效。在这两种情况下都可能找到所有的根(没有其他限制),但在Simulink和代码生成中,问题被视为一个复杂的问题,一些根可能带着微小的虚部返回。如果根的虚部不完全为零,则不删除根,而是使用数值上不重要的虚部(相对于实部非常小或全部非常小)消除根。差不多
tol = 10*eps(class(Q_roots));
keepers = abs(imag(Q_roots)) < tol*max(abs(real(Q_roots)),1) & ...
real(Q_roots) >= 0 & real(Q_roots) <= 3100;
Q_roots = Q_roots(keepers);
tol=10*eps(类(Q_根));
keepers=abs(imag(Q_根)) 实(Q_根)>=0&实(Q_根)=0&&r您使用哪个Simulink块调用此函数?Simulink中函数的输入是否正常?我使用了“MATLAB函数”块。。。我猜输入是可以的。。。我刚刚将两个常量连接到inputsMichael,如果我查看函数root()在Matlab和simulink中分别产生的根,simulink确实会产生不同的结果(即找到的根较少,而不是我感兴趣的根)。你能提供给我确切的Head和Freq输入来演示这一点吗?我们希望在数字上有细微的差异和不同的顺序。我们不期望“更少的根”或“不同的根”,除非在极端病态的情况下,在这种情况下,一个或另一个可能会给出更令人满意的结果,但并不一致。MATLAB在这方面的主要优势是能够对实矩阵使用特征值解算器,这将为非实根生成精确的复共轭对。
tol = 10*eps(class(Q_roots));
keepers = abs(imag(Q_roots)) < tol*max(abs(real(Q_roots)),1) & ...
real(Q_roots) >= 0 & real(Q_roots) <= 3100;
Q_roots = Q_roots(keepers);
Q = nan('like',a);
tol = 10*eps(class(a));
for k = 1:numel(Q_roots)
r = real(Q_roots(k));
if abs(imag(Q_roots(k))) < tol*max(abs(r),1) && r >= 0 && r <= 3100;
Q = r;
break
end
end
if freq < 0
Q = -Q;
end