实验一:误差传播及算法稳定性实验 1.2
1、试验程序:
function charpt1_2
% 误差传播及算法稳定性实验
clc;clear all;
promps={'请选择递推关系式,若选E1=1/e,En=1-nEn-1,请输入1,若选EN=0,
En-1=(1-En)/n,请输入2:'};
I=1;
while I
result=inputdlg(promps,'charpt1_2',1,{'1'});
Nb=str2num(char(result));
if ((Nb~=1)|(Nb~=2))
I=0;
end
end
%%%%%%%%%%%%%%%%%
I=1;
while I
result=inputdlg('请输入递推步数 n>=1:','charpt1_2',1,{'10'});
steps=str2num(char(result));
if (steps>0)&(steps==fix(steps))
%% 如果steps大于0且为整数
I=0;
end
end
%%%%%%%%%%%%%%%%%
result=inputdlg('请输入计算中所采用的有效数字位数
n:','charpt1_2',1,{'5'});
Sd=str2num(char(result));
format long
result=zeros(1,steps);
err=result;
func=result;
%%%%%%%%%%%%%%%%%
%% 用quadl计算积分近似值
for n=1:steps
%% 设置显示精度
%% 存储计算结果
%% 存储计算的绝对误差值
%% 存储用quadl计算的近似值
fun=@(x) x.^n.*exp(x-1);
func(n)= quadl(fun,0,1);
end
%%%%%%%%%%%%%%%%%
%% 用自定义算法计算
if(Nb==1)
digits(Sd);
result(1)=subs(vpa(1/exp(1)));
for n=2:steps
result(n)=subs(vpa(1-n*result(n-1)));
end
err=abs(result-func);
elseif(Nb==2)
digits(Sd);
result(steps)=0;
for n=(steps-1):-1:1
result(n)=subs(vpa((1-result(n+1))/(n+1)));
end
err=abs(result-func);
end
%%%%%%%%%%%%%%%%%
%% 输出结果数值及图像
clf;
disp('库函数计算值:');
disp(sprintf('%e ',func));
disp('递推值:');
disp(sprintf('%e ',result));
disp('误差值:');
disp(sprintf('%e ',err));
if(Nb==1)
plot([1:steps],result,'-rs',[1:steps],func,':k*',[1:steps],err,'-.bo')
;
elseif(Nb==2)
plot([steps:-1:1],result,'-rs',[steps:-1:1],func,':k*',[steps:-1:1],e
rr,'-.bo');
end
xlabel('第n步');
ylabel('计算值');
legend('自定义算法结果','库函数计算结果','误差值');
grid on
2、试验结果:
选择递推关系式 1,递推步数为 10,有效数字为 5 位,计算结果如下:
库函数计算值:
3.678794e-001 2.642411e-001 2.072766e-001 1.708934e-001 1.455329e-001
1.268024e-001 1.123836e-001 1.009323e-001 9.161229e-002 8.387707e-002
递推值:
3.678800e-001 2.642400e-001 2.072800e-001 1.708800e-001 1.456000e-001
1.264000e-001 1.152000e-001 7.840000e-002 2.944000e-001 -1.944000e+000
误差值:
5.588280e-007 1.117662e-006 3.352927e-006 1.341222e-005 6.705713e-005
4.023702e-004 2.816427e-003 2.253226e-002 2.027877e-001 2.027877e+000
自 定 义 算 法 结 果
库 函 数 计 算 结 果
误 差 值
2.5
2
1.5
1
0.5
0
-0.5
-1
-1.5
值
算
计
-2
1
2
3
4
6
5
第 n步
7
8
9
10
选择递推关系式 2,递推步数为 10,有效数字为 5 位,计算结果如下:
库函数计算值:
3.678794e-001 2.642411e-001 2.072766e-001 1.708934e-001 1.455329e-001
1.268024e-001 1.123836e-001 1.009323e-001 9.161229e-002 8.387707e-002
递推值:
3.678800e-001 2.642400e-001 2.072800e-001 1.708900e-001 1.455300e-001
1.267900e-001 1.125000e-001 1.000000e-001 1.000000e-001 0.000000e+000
误差值:
5.588280e-007 1.117662e-006 3.352927e-006 3.412224e-006 2.942873e-006
1.237016e-005 1.164270e-004 9.322618e-004 8.387707e-003 8.387707e-002
自 定 义 算 法 结 果
库 函 数 计 算 结 果
误 差 值
0.4
0.35
0.3
0.25
0.2
0.15
0.1
0.05
值
算
计
0
1
2
3
4
6
5
第 n步
7
8
9
10
选择递推关系式 1,递推步数为 10,有效数字为 6 位,计算结果如下:
库函数计算值:
3.678794e-001 2.642411e-001 2.072766e-001 1.708934e-001 1.455329e-001
1.268024e-001 1.123836e-001 1.009323e-001 9.161229e-002 8.387707e-002
递推值:
3.678790e-001 2.642420e-001 2.072740e-001 1.709040e-001 1.454800e-001
1.271200e-001 1.101600e-001 1.187200e-001 -6.848000e-002 1.684800e+000
误差值:
4.411720e-007 8.823378e-007 2.647073e-006 1.058778e-005 5.294287e-005
3.176298e-004 2.223573e-003 1.778774e-002 1.600923e-001 1.600923e+000
自 定 义 算 法 结 果
库 函 数 计 算 结 果
误 差 值
1.8
1.6
1.4
1.2
1
0.8
0.6
0.4
0.2
0
值
算
计
-0.2
1
2
3
4
6
5
第 n步
7
8
9
10
选择递推关系式 2,递推步数为 10,有效数字为 6 位,计算结果如下:
库函数计算值:
3.678794e-001 2.642411e-001 2.072766e-001 1.708934e-001 1.455329e-001
1.268024e-001 1.123836e-001 1.009323e-001 9.161229e-002 8.387707e-002
递推值:
3.678800e-001 2.642410e-001 2.072770e-001 1.708930e-001 1.455360e-001
1.267860e-001 1.125000e-001 1.000000e-001 1.000000e-001 0.000000e+000
误差值:
5.588280e-007 1.176622e-007 3.529274e-007 4.122239e-007 3.057127e-006
1.637016e-005 1.164270e-004 9.322618e-004 8.387707e-003 8.387707e-002
自 定 义 算 法 结 果
库 函 数 计 算 结 果
误 差 值
0.4
0.35
0.3
0.25
0.2
0.15
0.1
0.05
值
算
计
0
1
2
3
4
6
5
第 n步
7
8
9
10
3、结果分析:
很明显第二种递推式结果要比第一种好,式 1 在第七步后有明显误差,而式
2 在第三步后基本与近似解一致。
而从理论上也可以得到我们也可以得到类似结论。这是由于式 1 前一步的误
差乘以 n 后累积到后一步,从而使误差扩散,而式 2 恰恰相反。
有效数字位数影响不是很明显。
实验二:多项式差值的震荡现象实验 2.1
1、试验程序:
function charpt2_1
%数值试验二:多项式差值的震荡现象
promps={'请选择实验函数,若选 f(x),请输入 f,若选 h(x),请输入 h,若选 g(x),
请输入 g:'};
result=inputdlg(promps,'charpt2_1',1,{'f'});
Nb_f=char(result);
result=inputdlg({'请输入插值多项式的次数 N>=1:'},'charpt2_1',1,{'10'});
Nd=str2num(char(result));
switch Nb_f
case'f'
f=inline('1./(1+25*x.^2)');a=-1;b=1;
case'h'
case'g'
f=inline('x./(1+x.^4)');a=-5;b=5;
f=inline('atan(x)');a=-5;b=5;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
x0=linspace(a,b,Nd+1);y0=feval(f,x0);
x=a:0.1:b;
y=Lagrange(x0,y0,x);
clf;
fplot(f,[a,b],'co');
hold on;
plot(x,y,'b--');
xlabel('x');
ylabel('y=f(x) o and y=Ln(x)--');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function y=Lagrange(x0,y0,x)
n=length(x0);
m=length(x);
for i=1:m
p=p*(z-x0(j))/(x0(k)-x0(j));
z=x(i);
s=0.0;
for k=1:n
p=1.0;
for j=1:n
if(j~=k)
end
end
s=s+p*y0(k);
end
y(i)=s;
end
2、试验结果:
函数 f(x):
n=2
1
0.9
0.8
0.7
0.6
0.5
0.4
0.3
0.2
0.1
-
-
)
x
(
n
L
=
y
d
n
a
o
)
x
(
f
=
y
0
-1
-0.8
-0.6
-0.4
-0.2
0.2
0.4
0.6
0.8
1
0
x
n=3
1
0.9
0.8
0.7
0.6
0.5
0.4
0.3
0.2
0.1
-
-
)
x
(
n
L
=
y
d
n
a
o
)
x
(
f
=
y
0
-1
-0.8
-0.6
-0.4
-0.2
0.2
0.4
0.6
0.8
1
0
x
n=4
-
-
)
x
(
n
L
=
y
d
n
a
o
)
x
(
f
=
y
1
0.8
0.6
0.4
0.2
0
-0.2
-0.4
-1
n=5
-0.8
-0.6
-0.4
-0.2
0
x
0.2
0.4
0.6
0.8
1
1.2
1
0.8
0.6
0.4
0.2
0
-
-
)
x
(
n
L
=
y
d
n
a
o
)
x
(
f
=
y
-0.2
-1
-0.8
-0.6
-0.4
-0.2
n=6
1.2
1
0.8
0.6
0.4
0.2
0
-
-
)
x
(
n
L
=
y
d
n
a
o
)
x
(
f
=
y
-0.2
-1
-0.8
-0.6
-0.4
-0.2
0
x
0
x
0.2
0.4
0.6
0.8
1
0.2
0.4
0.6
0.8
1
n=10
-
-
)
x
(
n
L
=
y
d
n
a
o
)
x
(
f
=
y
1.6
1.4
1.2
1
0.8
0.6
0.4
0.2
0
-0.2
-0.4
-1
-0.8
-0.6
-0.4
-0.2
0
x
0.2
0.4
0.6
0.8
1
函数 g(x):
n=2