計算方法實驗:方程求根二分法、不動點迭代法、牛頓法

計算方法實驗一,方程求根

分別用Matlab和C寫了一下,初學Matlab,如有不足還請指正。

實驗內容:
1)在區間[0,1]內用二分法求方程ex+10x2e^x+10*x-2的近似根,要求誤差不超過0.5×1030.5\times10^{-3}
2)取初值x0=0x_0=0,用迭代公式xk+1=2exk10,(k=0,1,2,...)x_{k+1}=\frac{2-e^{x_k}}{10},(k=0,1,2,...)求方程ex+10x2e^x+10*x-2的近似根,要求誤差不超過0.5×1030.5\times10^{-3}
3)取初值x0=0x_0=0,用牛頓迭代法求方程ex+10x2e^x+10*x-2的近似根,要求誤差不超過0.5×1030.5\times10^{-3}
牛頓迭代公式:xk+1=xkf(xk)f(xk)x_{k+1}=x_k-\frac{f(x_k)}{f'(x_k)}

1. C

#include <stdio.h>
#include <Windows.h>
#include <math.h>

#define WUCHA (0.5*pow(10, -4))

double f_x(double x);
double erfenfa();
double diedai();
double newtown();

int cnt = 0;

int main()
{
	// 二分法
	printf("二分法:%lf\n", erfenfa());
	printf("計算次數%d\n", cnt);

	// 迭代法
	printf("迭代法:%lf\n", diedai());
	printf("計算次數%d\n", cnt);

	// 牛頓法
	printf("牛頓法:%lf\n", newtown());
	printf("計算次數%d\n", cnt);

	system("pause");
	return 0;
}


// f(x)
double f_x(double x)
{
	return (exp(x) + 10 * x - 2);
}

// f'(x)
double fd_x(double x)
{
	return (exp(x) + 10);
}

// 牛頓法
double newtown()
{
	cnt = 0;

	double x0 = 0.0;
	double ret = f_x(x0);
	double xk = x0 - f_x(x0) / fd_x(x0);

	for (int k = 0; ; k++)
	{
		cnt++;
		if (fabs(ret - 0) <= WUCHA)
		{
			break;
		}

		xk = xk - f_x(xk) / fd_x(xk);
		ret = f_x(xk);
	}

	return xk;
}

// 迭代法
double diedai()
{
	cnt = 0;
	double x0 = 0.0;
	double ret = f_x(x0);
	double xk = x0;

	//int k = 0;
	for (int k = 0; ; k++)
	{
		cnt++;
		if (fabs(ret - 0) <= WUCHA)
		{
			break;
		}

		xk = ((2 - exp(xk)) / 10);
		ret = f_x(xk);
	}

	return xk;
}

// 二分法
double erfenfa()
{
	cnt = 0;
	double left = 0.0;
	double right = 0.1;
	double x = (left + right) / 2;
	double ret = f_x(x);

	while (fabs(ret - 0) >= WUCHA)
	{
		cnt++;
		if (ret > 0)
		{
			right = x;
		}
		if (ret < 0)
		{
			left = x;
		}
		x = (left + right) / 2;
		ret = f_x(x);
	}
	return x;
}

分界線


2. Matlab

2.1 二分法

function x = erfen(f,a,b,e)
% f是函數名 a,b是區間端點,e爲精度
fa = feval(f,a); % feval是求函數值
fb = feval(f,b);
if fa*fb>0
    error('此函數在[%d,%d]區間無解',a,b);
end

k = 0;
x = (a+b)/2;
while(b-a)>(2*e)
    fx=feval(f,x);
    if fa*fx<0
        b=x;
        fb=fx;
    else
        a=x;
        fb=fx;
    end
    k=k+1;
    x=(a+b)/2;
    
    fprintf("%d:x=%f\n", k, x);
    
end

2.2 不動點迭代法

function x = diedai(f,diedaif,x0,e)

N = 10; %最大迭代次數

ret = feval(diedaif,x0);
xk = x0;
k = 0;

while abs(x0-ret)>e & k<N
    
    xk = feval(diedaif,xk);
    ret = feval(diedaif,xk);
    
    k = k+1;
    fprintf("xk=%f\n", xk);
    %if
    %    break;
    %end
    
end

if k==N
    fprintf('超過最大迭代次數限制\n');

end

2.3 牛頓法

function x = newton(f,fd,x0,e)
% f->f(x)
% fd->f'(x)
% x0=0
% e=0.0005

N = 100; %最大迭代次數100
x = x0;
x0 = x+2*e;
k = 0;
while abs(x0-x)>e & k<N
    k = k+1;
    x0=x;
    x=x0-feval(f,x0)/feval(fd,x0);
    fprintf("x=%f\n", x);
end

if k==N
    warning('超過最大迭代次數限制');

end

分界線


3.實驗結果

3.1 C

C運行結果

3.2 Matlab

二分法
迭代法
牛頓法


EOF,不足之處,還請指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章