用伪位置法计算matlab问题中的绝对和相对误差
我在我的错误定位算法中使用函数用伪位置法计算matlab问题中的绝对和相对误差,matlab,Matlab,我在我的错误定位算法中使用函数f=@(x)2*sin(x)-exp(x)/4-1。给出了根-5.7591是正确的根。然而,在我的算法中,计算误差的不同方法是不正确的。如果没有计数器来停止while循环,那么每当我使用绝对近似值(flag=1)或相对误差(flag=2)时,它就会一直持续下去 使用的范围为[-7,-5],当误差降至10^6以下时,循环应停止 下面是代码及其下面的输入和输出: function [root,counter] = FalsePosition(f,x1,x2,d,flag
f=@(x)2*sin(x)-exp(x)/4-1
。给出了根-5.7591
是正确的根。然而,在我的算法中,计算误差的不同方法是不正确的。如果没有计数器来停止while循环,那么每当我使用绝对近似值(flag=1)或相对误差(flag=2)时,它就会一直持续下去
使用的范围为[-7,-5],当误差降至10^6以下时,循环应停止
下面是代码及其下面的输入和输出:
function [root,counter] = FalsePosition(f,x1,x2,d,flag)
sx1 = x1;
sx2 = x2;
if(f(x1)*f(x2) >= 0)
disp("x1 and x2 are not correct")
return
end
while(flag > 3 || flag < 1)
flag = input("Flag used incorrectly! please enter a value 1 - 3: ");
end
i = 0;
E = d;
while(i < 100 && E >= d)
x3 = x2 - f(x2)*(x2-x1)/(f(x2)-f(x1));
i = i + 1;
if(f(x1)*f(x3) < 0)
x2 = x3;
x = x1;
else
x1 = x3;
x = x2;
end
if(flag == 1)
E = abs(x - x3); % abs approx error
elseif(flag == 2)
e = abs(x - x3);
E = e/abs(x3); % abs relative error
else
E = abs(f(x3)); % true error
end
end
counter = i;
root = x3;
if(flag == 1)
method = "Absolute approximate error";
elseif(flag == 2)
method = "Absolute relative approximate error";
else
method = "True absolute error";
end
disp("Method used: " + method);
disp("Brackets: " + sx1 + " and " + sx2);
disp("The root is " + root);
disp("Iterations: " + counter);
disp(" ");
其中v是根,c是while循环的迭代次数我意识到假位置法(以及割线法)对系统中的初始括号非常敏感。在我的示例中,我使用了括号-7和-5,这导致了问题。我切换到一个不同的(更集中的)括号-6和-5.5,这给了我一个期望的结果:
>> [v,c] = FalsePosition(f,-6,-5.5,10^-6,2)
Method used: Absolute relative approximate error
Brackets: -6 and -5.5
The root is -5.7591
Iterations: 13
v =
-5.7591
c =
13
所以实际上我还发现了第二种解决方法。除了更改括号外,还可以检查迭代次数是否大于1,如果大于1,则使x=x3,然后更新x3:
function [root,counter] = FalsePosition(funct,x1,x2,d,flag)
f = matlabFunction(funct);
sx1 = x1;
sx2 = x2;
if(f(x1)*f(x2) >= 0)
disp("x1 and x2 are not correct")
return
end
while(flag > 3 || flag < 1)
flag = input("Flag used incorrectly! please enter a value 1 - 3: ");
end
x3 = (f(x2)*x1-f(x1)*x2)/(f(x2)-f(x1));
i = 0;
E = d;
while(E >= d)
x3 = (f(x2)*x1-f(x1)*x2)/(f(x2)-f(x1));
i = i + 1;
if(f(x1)*f(x3) < 0)
x2 = x3;
x = x1;
else
x1 = x3;
x = x2;
end
if(i > 1)
x = x3;
x3 = (f(x2)*x1-f(x1)*x2)/(f(x2)-f(x1));
end
if(flag == 1)
E = abs(x - x3); % abs approx error
elseif(flag == 2)
e = abs(x - x3);
E = e/abs(x3); % abs relative error
else
E = abs(f(x3)); % true error
end
end
counter = i;
root = x3;
if(flag == 1)
method = "Absolute approximate error";
elseif(flag == 2)
method = "Absolute relative approximate error";
else
method = "True absolute error";
end
disp("Method used: " + method);
disp("Brackets: " + sx1 + " and " + sx2);
disp("The root is " + root);
disp("Iterations: " + counter);
disp(" ");
现在,如果我使用原始括号运行相同的设置,我会得到一个没有迭代问题的答案:
>> [v,c] = FalsePosition(f,-7,-5,10^-6,2)
Method used: Absolute relative approximate error
Brackets: -7 and -5
The root is -5.7591
Iterations: 6
v =
-5.7591
c =
6
这两个选项似乎都有效,但归根结底是偏好问题我认为这可能与计算
x3
中的计算机算术问题一样简单。尝试这个重新排列的版本(根据维基百科限制舍入误差):x3=(f(x2)*x1-f(x1)*x2)/(f(x2)-f(x1))
@David我用你建议的计算替换了我原来的计算。我仍然有同样的问题。然而,我试着用一个不同的方程来测试它(这是在二分法中使用的x3方程),这使它工作了,所以我想你肯定对x3方程的问题有所了解。
function [root,counter] = FalsePosition(funct,x1,x2,d,flag)
f = matlabFunction(funct);
sx1 = x1;
sx2 = x2;
if(f(x1)*f(x2) >= 0)
disp("x1 and x2 are not correct")
return
end
while(flag > 3 || flag < 1)
flag = input("Flag used incorrectly! please enter a value 1 - 3: ");
end
x3 = (f(x2)*x1-f(x1)*x2)/(f(x2)-f(x1));
i = 0;
E = d;
while(E >= d)
x3 = (f(x2)*x1-f(x1)*x2)/(f(x2)-f(x1));
i = i + 1;
if(f(x1)*f(x3) < 0)
x2 = x3;
x = x1;
else
x1 = x3;
x = x2;
end
if(i > 1)
x = x3;
x3 = (f(x2)*x1-f(x1)*x2)/(f(x2)-f(x1));
end
if(flag == 1)
E = abs(x - x3); % abs approx error
elseif(flag == 2)
e = abs(x - x3);
E = e/abs(x3); % abs relative error
else
E = abs(f(x3)); % true error
end
end
counter = i;
root = x3;
if(flag == 1)
method = "Absolute approximate error";
elseif(flag == 2)
method = "Absolute relative approximate error";
else
method = "True absolute error";
end
disp("Method used: " + method);
disp("Brackets: " + sx1 + " and " + sx2);
disp("The root is " + root);
disp("Iterations: " + counter);
disp(" ");
if(i > 1)
x = x3;
x3 = (f(x2)*x1-f(x1)*x2)/(f(x2)-f(x1));
end
>> [v,c] = FalsePosition(f,-7,-5,10^-6,2)
Method used: Absolute relative approximate error
Brackets: -7 and -5
The root is -5.7591
Iterations: 6
v =
-5.7591
c =
6