利用二分法、迭代法、斯蒂芬森加速迭代法和牛顿迭代法求解非线性方程(matlab实现)

二分法
matlab代码:

close, clc, clear;
tol = 1e-6;
g = bisectfun('x^3 - 3*x + 1', -1, 1, tol)

function g = bisectfun(f, a, b, tol) 
% f:待求解的非线性方程   a:下限  b:上限  tol:精度
if nargin == 3
    tol = 1e-3;
end
g = compute_bisect(f, a, b, tol);
end

function r = compute_bisect(f, a, b, tol)
fa = subs(f, a);
fb = subs(f, b);
fab = subs(f, (a + b)/2);
if fa*fab>0    % 零点不在区间 [a, (a + b)/2]
    t = (a + b)/2;
    r = compute_bisect(f, t, b, tol);
else
    if fa*fab == 0
        r = (a + b)/2;
    else
        if (abs(b - a)<=tol)
            r = (b + 3*a)/4;
        else
            s = (a + b)/2;
            r = compute_bisect(f, a, s, tol);
        end
    end
end
end

% 结果:

g =

    0.3473

迭代法
迭代法的基本思想是一种逐次逼近的方法。首先取一个粗糙的近似值,然后用同一个递推公式反复校正这个近似值,直到满足预先给出的精度要求为止。
matlab代码:

x0 = 0.5; tol = 1e-6; n = 10000;
f = inline('sin(x)/x', 'x');

[x, k, error, P] = Iteration(f,x0,tol, n)

function [x, k, error, P] = Iteration(f, x0, tol, n)
P(1) = x0;
for k = 2:n
    P(k) = feval(f, P(k-1));
    disp(k);
    error = abs(P(k) - P(k - 1));
    x = P(k);
    if error <= tol
        break
    end
    
    if k == n
        disp('超过迭代次数,程序终止!');
        break;
    end
end
end

% 结果:

x =

    0.8767


k =

    12


error =

   8.2977e-07


P =

  1 至 9 列

    0.5000    0.9589    0.8537    0.8829    0.8751    0.8772    0.8766    0.8768    0.8767

  10 至 12 列

    0.8767    0.8767    0.8767

斯蒂芬森加速迭代法
在通常情况下,迭代法是线性收敛的,而线性收敛的速度比较慢,因此需要改进迭代公式,提高迭代速度,由此产生了斯蒂芬森加速迭代法。
matlab代码:

f = inline('1/sqrt(x) + x - 2', 'x');
x0 = 0.45;
[R, n] = Stevenfun(f, x0)


function [r0, n] = Stevenfun(f, x0, eps)
if nargin == 2
    eps = 1e-4;
end

tol = 1;  % 初始精度
r0 = x0;
n = 0;
while tol >= eps
    n = n + 1;
    r = r0;
    % y = subs(sym(f), findsym(sym(f)), r) + r;   % y = f(r) + r
    % z = subs(sym(f), findsym(sym(f)), y) + y;   % z = f(y) + y
    y = feval(f, r) + r;
    z = feval(f, y) + y;
    r0 = r - (y - r)^2/(z - 2*y + r);
    tol = abs(r0 - r);
end
end

% 结果:

R =

    0.3820


n =

     3

牛顿迭代法
利用非线性函数 f(x) 的线性展开解决问题,算法步骤如下:
(1)、选取初始点x0,最大迭代次数n和精度eps。
(2)、如果df(x(k)) = 0,则停止计算;如果df(x) ~= 0,则执行下一步。
(3)、x(k+1) = x(k) - f(x(k))/df(x(k))
(4)、如果 |x(k+1) - x(k)|<eps,则停止计算。
(5)、如果k=N,则停止计算;否则,k = k + 1,回到第二步。

f = inline('x^3 - 3*x + 2', 'x');
df = inline('3*x^2 - 3', 'x');
x0 = 1.4;
eps = 1e-6;
n = 20;
[x, error, k, y] = newton(f, df, x0, eps, n)
function [x, error, k, y] = newton(f, df, x0, eps, n)
y(1) = x0;
for k = 1: n
    x = x0 - feval(f, x0)/feval(df, x0);
    error = abs(x - x0);
    x0 = x;
    if error < eps | y == 0
        break
    end
end
end

% 结果:

x =

    1.0000


error =

   8.6078e-07


k =

    19


y =

    1.4000
  • 8
    点赞
  • 90
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值