凯鲁嘎吉
用书写铭记日常,最迷人的不在远方
posts - 292,comments - 409,views - 138万
回到顶部(go to top)

MATLAB用二分法、不动点迭代法及Newton迭代(切线)法求非线性方程的根

作者:凯鲁嘎吉 - 博客园
http://www.cnblogs.com/kailugaji/

一、实验原理

二、实验步骤

三、实验过程

1.(程序)

(1)二分法:求   在区间(12)之间的根,取

abipart.m:

1
2
3
4
5
6
7
8
9
10
11
12
function [x,m]=bipart(fun,a0,b0,tol)
a=a0;b=b0;
m=1+round(round(log((b-a)/tol))/log(2));
for k=1:m
    p=(a+b)/2;    
    if fun(p)*fun(b)<0
            a=p;
    else
            b=p;
    end
    x=p;
end 

(b)fun1.m:

1
2
function f=fun1(x)
f=x^3+10*x-20;

 2)不动点迭代法:求方程附近的根,取

    2020/10/17   注:这里求解用的牛顿迭代法,不是不动点迭代法,不动点迭代法的MATLAB程序请参看:MATLAB实例:不动点迭代法求一元函数方程的根 - 凯鲁嘎吉 - 博客园 

(a)budong.m:

1
2
3
4
5
6
7
8
9
function [x,k]=budong(fun,x0,tol,m)
for k=1:m
    x=fun(x0);
    if abs(x-x0)<tol
        break;
    end
    x0=x;
end
x=vpa(x,8);

   (b)fun.m

1
2
3
4
5
6
7
function t=fun(x1)
syms x;
f=x^3-2*x-5;
s=subs(diff(f,x),x,x1);
x=x1;
f=x^3-2*x-5;
t=x-f/s;

3)牛顿迭代法:求方程附近的根,取

newton.m:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
function x1=newton(t1,esp,m)
 
syms x;
 
fun=x^3+2*x-5;
 
for k=1:m
 
    if abs(subs(diff(fun,'x'),x,t1))<esp
 
        x1=t1;
 
        break;
 
    else
 
        if subs(diff(fun,'x',2),x,t1)==0
 
            break;
 
            disp('解题失败!')
 
        else
 
            t0=t1;
 
            t1=t0-subs(fun,x,t0)/subs(diff(fun,'x'),x,t0);
 
            if abs(t1-t0)<esp
 
                x1=t1;
 
                break;
 
            end
 
        end
 
    end
 
end
 
x1=vpa(x1,8);

2.(运算结果)

(1)二分法:

1
2
3
4
5
>> [x,m]=bipart(@fun1,1,2,0.0001)
x =
    1.5945
m =
    14

(2)不动点迭代法:

1
2
3
4
5
>> [x,k]=budong(@fun,2,1e-5,100)
x =
2.0945515
k =
     4

(3)牛顿迭代法:

1
2
3
4
>> x1=newton(2,1e-4,20)
    x1 =
       1.3282689
 

3.(拓展(方法改进、体会等))

对于方程的根为重根的情形,newton法求重根只是线性收敛,迭代缓慢,如果对于求重根的情形,对newton法进行改进,取

             ,

。用迭代法

                  

m重根,则具有二阶收敛性,但要知道的重数m。

   计算方程的根是二重根,用newton法与改进方法求根。

源程序:

newton_biroot.m:

1
2
3
4
5
6
7
8
9
10
11
12
13
function t=newton_biroot(x1)
 
syms x;
 
f=x^4-4*(x^2)+4;
 
s=subs(diff(f,x),x,x1);
 
x=x1;
 
f=x^4-4*(x^2)+4;
 
t=x-f/s;

biroot1.m:

1
2
3
4
5
6
7
8
9
10
11
12
13
function t=biroot1(x1)
 
syms x;
 
f=x^4-4*(x^2)+4;
 
s=subs(diff(f,x),x,x1);
 
x=x1;
 
f=x^4-4*(x^2)+4;
 
t=x-2*f/s;

budong.m:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function [x,k]=budong(fun,x0,tol,m)
 
for k=1:m
 
    x=fun(x0);
 
    if abs(x-x0)<tol
 
        break;
 
    end
 
    x0=x;
 
    x=vpa(x,8)
 
end
 
x=vpa(x,8);

运行结果:取初值为2

k

          xk

newton

改进方法

1

          x1

1.75

1.5

2

          x2

1.5982143

 

1.4166667

 

3

          x3

1.5115099

 

1.4142157

 

4

          x4

1.4644275

 

1.4142157

 

 计算4步,改进方法就已经收敛,而newton法只是线性收敛,要达到同样精度需迭代17次。

附结果:

>> [x,k]=budong(@biroot1,2,1e-5,3)

x =

1.5

x =

1.4166667

x = 

1.4142157

x =

1.4142157 

k =

     3

>> [x,k]=budong(@biroot1,2,1e-5,10)

x =

1.5

x =

1.4166667

x =

1.4142157

x =

1.4142136 

k =

     4

>> [x,k]=budong(@newton_biroot,2,1e-5,50)

x =

1.75

x = 

1.5982143 

x = 

1.5115099 

x = 

1.4644275

x =

1.439751

x =

1.4270955

x =

1.4206836

x =

1.4174559

x =

1.4158366 

x =

1.4150256

x =

1.4146197

x =

1.4144166

x =

1.4143151

x = 

1.4142643 

x =

1.414239

x =

1.4142263 

x =

1.4142199

k =

    17

posted on   凯鲁嘎吉  阅读(36122)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 字符编码:从基础到乱码解决

点击右上角即可分享
微信分享提示