用伪位置法计算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