注:为了便于校验结果,本文为实验报告的补充
非线性方程组的数值求解方法很多,基本的思想是线性化•不同的方法效果如何,要靠计算的实践来分析、比较.
分别编写它们的Matlab 程序.
用上述各种方法,分别计算下面的两个例子.在达到精度相同的前提下,比较其迭代次数.
(1) { 12 x 1 − x 2 2 − 4 x 3 − 7 = 0 x 1 2 + 10 x 2 − x 3 − 11 = 0 x 2 3 + 10 x 3 − 8 = 0 \left\{\begin{array}{l}12 x_1-x_2^2-4 x_3-7=0 \\ x_1^2+10 x_2-x_3-11=0 \\ x_2^3+10 x_3-8=0\end{array} \quad\right. ⎩ ⎨ ⎧12x1−x22−4x3−7=0x12+10x2−x3−11=0x23+10x3−8=0 取 x ( 0 ) = ( 1 , 1 , 1 ) T x^{(0)}=(1,1,1)^{ T } x(0)=(1,1,1)T
(2) { 3 x 1 − cos ( x 2 x 3 ) − 1 2 = 0 x 1 2 − 81 ( x 2 + 0.1 ) 2 + sin x 3 + 1.06 = 0 e − x 1 x 2 + 20 x 3 + 1 3 ( 10 π − 3 ) = 0 \left\{\begin{array}{l}3 x_1-\cos \left(x_2 x_3\right)-\frac{1}{2}=0 \\ x_1^2-81\left(x_2+0.1\right)^2+\sin x_3 \\ +1.06=0 \\ e ^{-x_1 x_2}+20 x_3+\frac{1}{3}(10 \pi-3)=0\end{array} \quad\right. ⎩ ⎨ ⎧3x1−cos(x2x3)−21=0x12−81(x2+0.1)2+sinx3+1.06=0e−x1x2+20x3+31(10π−3)=0 取 x ( 0 ) = ( 0 , 0 , 0 ) T x ^{(0)}=(0,0,0)^{ T } x(0)=(0,0,0)T
取其他初值 x ( 0 ) x^{(0)} x(0),结果又如何?反复选取不同的初值,比较其结果.
总结归纳你的实验结果,试说明各种方法适用的问题.
%----- code Newton法 for 实验4.1 -----
%----- code Newton法 for 实验4.1 -----
%----- code Newton法 for 实验4.1 -----
% clc %清除命令窗口的内容
clear all; %清除工作空间的所有变量,函数,和MEX文件
format long ; %设置输出显示格式为16位有效数字
%--------------------- 数值分析 实验4.1 算法设计与比较 ---------------------
x_0_0 = input('请输入初值x0的每一分量: ');%为了便于比较取初值3个分量相同
% x_k1 为x^(k+1) ,x_k为x^()
x_0 = [x_0_0,x_0_0,x_0_0]';
times = 0;
x_k = x_0;
delta_x = [1,1,1]';
tol = 1e-8;
% disp('方程组1——Frechet导数F(x)为:');
A = df1(x_k); % A为F'(x)
tic;
while norm(delta_x)>tol
delta_x = -df1(x_k)\f1(x_k);
x_k1 = delta_x + x_k;
x_k = x_k1;
times = times + 1;
end
run_time = toc;
err = norm(x_k-x_0,inf);%计算误差
disp('---------------- Newton法_output ----------------');
fprintf('初值x0 = [ %d, %d, %d ] \n',x_0_0,x_0_0,x_0_0);
fprintf('方程组1_计算结果_牛顿法的解 x_k = [ %16.15f, %16.15f, %16.15f ] \n',x_k(1,1),x_k(2,1),x_k(3,1));
fprintf('迭代次数为: %2d, 计算误差为: %16.15e , 最后两步迭代差为: %16.15e , CPU计算时间:%16.15f s \n',times,err,norm(delta_x),run_time);
% 定义方程组1 :输入x
function y = f1(x)
y(1,1) = 12*x(1,1) - x(2,1)^2 - 4*x(3,1) -7;
y(2,1) = x(1,1)^2 + 10*x(2,1) - x(3,1) - 11;
y(3,1) = x(2,1)^3 + 10*x(3,1) - 8;
end
% 定义方程组1——Frechet导数
function y = df1(x)
y(1,:) = [12 -2*x(2,1) -4];
y(2,:) = [2*x(1,1) 10 -1];
y(3,:) = [0 3*x(2,1)^2 10];
end
%----- code Newton法 for 实验4.1 -----
%----- code Newton法 for 实验4.1 -----
%----- code Newton法 for 实验4.1 -----
% clc %清除命令窗口的内容
clear all; %清除工作空间的所有变量,函数,和MEX文件
format long ; %设置输出显示格式为16位有效数字
%--------------------- 数值分析 实验4.1 算法设计与比较 ---------------------
x_0 = input('请输入初值x0,格式[x1;x2;x3]: ');
% x_k1 为x^(k+1) ,x_k为x^()
times = 0;
x_k = x_0;
delta_x = [1,1,1]';
tol = 1e-8;
% disp('方程组1——Frechet导数F(x)为:');
A = df2(x_k); % A为F'(x)
tic;
while norm(delta_x)>tol
delta_x = -df2(x_k)\f2(x_k);
x_k1 = delta_x + x_k;
x_k = x_k1;
times = times + 1;
end
% toc;
run_time = toc;
err = norm(x_k-x_0,inf);%计算误差
disp('-------------------------------- Newton法_output --------------------------------');
disp('方程组2_计算结果_牛顿法:');
x_k
fprintf('迭代次数为: %3d, 计算误差为: %16.15e , 最后两步迭代差为: %16.15e , CPU计算时间:%16.15f s \n',times,err,norm(delta_x),run_time);
% 定义方程组2 :输入x
function y = f2(x)
y(1,1) = 3*x(1,1) - cos(x(2,1)*x(3,1)) - 1/2;
y(2,1) = x(1,1)^2 - 81*(x(2,1) + 0.1)^2 +sin(x(3,1)) + 1.06;
y(3,1) = exp(-x(1,1)*x(2,1)) + 20*x(3,1) + (10*pi - 3)/3;
end
% 定义方程组2——Frechet导数
function y = df2(x)
y(1,:) = [3 x(3,1)*sin(x(2,1)*x(3,1)) x(2,1)*sin(x(2,1)*x(3,1))];
y(2,:) = [2*x(1,1) -162*(x(2,1) + 0.1) cos(x(3,1))];
y(3,:) = [-x(2,1)*exp(-x(1,1)*x(2,1)) -x(1,1)*exp(x(1,1)*x(2,1)) 20];
end
%----- code 拟Newton法 for 实验4.1 -----
%----- code 拟Newton法 for 实验4.1 -----
%----- code 拟Newton法 for 实验4.1 -----
% clc %清除命令窗口的内容
clear all; %清除工作空间的所有变量,函数,和MEX文件
format long ; %设置输出显示格式为16位有效数字
%--------------------- 数值分析 实验4.1 算法设计与比较 ---------------------
x_0 = input('请输入初值x0,格式[x1;x2;x3]: ');
% x_k1 为x^(k+1) ,x_k为x^()
times = 0;
x_k = x_0;
delta_x = [1,1,1]';
tol = 1e-8;
% disp('方程组1——Frechet导数F(x)为:');
A = df1(x_k); % A为F'(x)
tic;
while norm(delta_x) > tol
x_k1 = x_k - pinv(A)*f1(x_k);
delta_x = x_k1 - x_k;
delta_y = f1(x_k1) - f1(x_k);
A = A + (delta_y - A*delta_x)*delta_x'/(delta_x'*delta_x);
x_k = x_k1;
times = times + 1;
end
run_time = toc;
err = norm(x_k-x_0,inf);%计算误差
disp('---------------- 拟Newton法_output ----------------');
disp('方程组1_计算结果_拟牛顿法:');
x_k
fprintf('迭代次数为: %2d, 计算误差为: %16.15e , 最后两步迭代差为: %16.15e , CPU计算时间:%16.15f s \n',times,err,norm(delta_x),run_time);
% 定义方程组1 :输入x
function y = f1(x)
y(1,1) = 12*x(1,1) - x(2,1)^2 - 4*x(3,1) -7;
y(2,1) = x(1,1)^2 + 10*x(2,1) - x(3,1) - 11;
y(3,1) = x(2,1)^3 + 10*x(3,1) - 8;
end
% 定义方程组1——Frechet导数
function y = df1(x)
y(1,:) = [12 -2*x(2,1) -4];
y(2,:) = [2*x(1,1) 10 -1];
y(3,:) = [0 3*x(2,1)^2 10];
end
%----- code 拟Newton法 for 实验4.1 -----
%----- code 拟Newton法 for 实验4.1 -----
%----- code 拟Newton法 for 实验4.1 -----
% clc %清除命令窗口的内容
clear all; %清除工作空间的所有变量,函数,和MEX文件
format long ; %设置输出显示格式为16位有效数字
%--------------------- 数值分析 实验4.1 算法设计与比较 ---------------------
x_0 = input('请输入初值x0,格式[x1;x2;x3]: ');
% x_k1 为x^(k+1) ,x_k为x^(k)
times = 0;
x_k = x_0;
delta_x = [1,1,1]';
tol = 1e-8;
% disp('方程组1——Frechet导数F(x)为:');
A = df2(x_k); % A为F'(x)
tic;
while norm(delta_x) > tol
x_k1 = x_k - A\f2(x_k);
delta_x = x_k1 - x_k;
delta_y = f2(x_k1) - f2(x_k);
A = A + (delta_y - A*delta_x)*delta_x'/(delta_x'*delta_x);
x_k = x_k1;
times = times + 1;
end
run_time = toc;
err = norm(x_k-x_0,inf);%计算误差
disp('---------------- 拟Newton法_output ----------------');
disp('方程组2_计算结果_拟牛顿法:');
x_k
fprintf('迭代次数为: %2d, 计算误差为: %16.15e , 最后两步迭代差为: %16.15e , CPU计算时间:%16.15f s \n',times,err,norm(delta_x),run_time);
% 定义方程组2 :输入x
function y = f2(x)
y(1,1) = 3*x(1,1) - cos(x(2,1)*x(3,1)) - 1/2;
y(2,1) = x(1,1)^2 - 81*(x(2,1) + 0.1)^2 +sin(x(3,1)) + 1.06;
y(3,1) = exp(-x(1,1)*x(2,1)) + 20*x(3,1) + (10*pi - 3)/3;
end
% 定义方程组2——Frechet导数
function y = df2(x)
y(1,:) = [3 x(3,1)*sin(x(2,1)*x(3,1)) x(2,1)*sin(x(2,1)*x(3,1))];
y(2,:) = [2*x(1,1) -162*(x(2,1) + 0.1) cos(x(3,1))];
y(3,:) = [-x(2,1)*exp(-x(1,1)*x(2,1)) -x(1,1)*exp(x(1,1)*x(2,1)) 20];
end
%----- code Newton法 for 实验4.1(2) -----
%----- code Newton法 for 实验4.1(2) -----
%----- code Newton法 for 实验4.1(2) -----
% clc %清除命令窗口的内容
clear all; %清除工作空间的所有变量,函数,和MEX文件
format long ; %设置输出显示格式为16位有效数字
%--------------------- 数值分析 实验4.1 算法设计与比较 ---------------------
% x_0_0 = input('请输入初值x0的每一分量: ');%为了便于比较取初值3个分量相同
% 定义数组存放计算误差、迭代步数
cal_err = [];
cal_steps = [];
i = 1;
for n = 0.1:0.1:100
% x_k1 为x^(k+1) ,x_k为x^(k)
x_0 = [n,n,n]'; % 初值
times = 0;
x_k = x_0;
delta_x = [1,1,1]';
tol = 1e-8;
A = df1(x_k); % A为F'(x)
tic;
while norm(delta_x)>tol
delta_x = -df1(x_k)\f1(x_k);
x_k1 = delta_x + x_k;
x_k = x_k1;
times = times + 1;
end
run_time = toc;
err = norm(x_k-x_0,inf);%计算误差
disp('---------------- Newton法_output ----------------');
fprintf('初值x0 = [ %4.1f, %4.1f, %4.1f ] \n',n,n,n);
fprintf('方程组1_计算结果_牛顿法的解 x_k = [ %16.15f, %16.15f, %16.15f ] \n',x_k(1,1),x_k(2,1),x_k(3,1));
fprintf('迭代次数为: %2d, 计算误差为: %16.15e , 最后两步迭代差为: %16.15e , CPU计算时间:%16.15f s \n',times,err,norm(delta_x),run_time);
cal_err(i) = err;
cal_steps(i) = times;
i = i + 1;
end
nn = 0.1:0.1:100;
figure
plot(nn,cal_err,nn,cal_steps);
% 按照顺序标识标识图形
legend('计算误差', '迭代次数');
% 添加标题
title('方程1牛顿法计算结果');
% 添加 x 轴标签
% \pi 在图像中显示的小写希腊字母
xlabel('初值的每一分量');
% 添加 y 轴标签
% ylabel('y = sin(x)');
% plot(nn,cal_err);
% figure
% plot(nn,cal_steps);
% 定义方程组1 :输入x√ç
function y = f1(x)
y(1,1) = 12*x(1,1) - x(2,1)^2 - 4*x(3,1) -7;
y(2,1) = x(1,1)^2 + 10*x(2,1) - x(3,1) - 11;
y(3,1) = x(2,1)^3 + 10*x(3,1) - 8;
end
% 定义方程组1——Frechet导数
function y = df1(x)
y(1,:) = [12 -2*x(2,1) -4];
y(2,:) = [2*x(1,1) 10 -1];
y(3,:) = [0 3*x(2,1)^2 10];
end
%----- code Newton法 for 实验4.1(2) -----
%----- code Newton法 for 实验4.1(2) -----
%----- code Newton法 for 实验4.1(2) -----
% clc %清除命令窗口的内容
clear all; %清除工作空间的所有变量,函数,和MEX文件
format long ; %设置输出显示格式为16位有效数字
%--------------------- 数值分析 实验4.1 算法设计与比较 ---------------------
% x_0_0 = input('请输入初值x0的每一分量: ');%为了便于比较取初值3个分量相同
% 定义数组存放计算误差、迭代步数
cal_err = [];
cal_steps = [];
i = 1;
for n = -0.5:0.01:5
% x_k1 为x^(k+1) ,x_k为x^(k)
x_0 = [n,n,n]'; % 初值
times = 0;
x_k = x_0;
delta_x = [1,1,1]';
tol = 1e-8;
A = df1(x_k); % A为F'(x)
tic;
while norm(delta_x)>tol
delta_x = -pinv(df2(x_k))*f2(x_k);
%在使用matlab对矩阵求逆时出现了“警告:
% 矩阵接近奇异值,或者缩放错误。结果可能不准确
%此时可以用pinv代替inv,即可解决这个问题。
x_k1 = delta_x + x_k;
x_k = x_k1;
times = times + 1;
if times > 10000
disp('迭代超10000仍未达到精度要求,可能不收敛')
break
end
end
run_time = toc;
err = norm(x_k-x_0,inf);%计算误差
disp('---------------- Newton法_output ----------------');
fprintf('初值x0 = [ %4.1f, %4.1f, %4.1f ] \n',n,n,n);
fprintf('方程组1_计算结果_牛顿法的解 x_k = [ %16.15f, %16.15f, %16.15f ] \n',x_k(1,1),x_k(2,1),x_k(3,1));
fprintf('迭代次数为: %2d, 计算误差为: %16.15e , 最后两步迭代差为: %16.15e , CPU计算时间:%16.15f s \n',times,err,norm(delta_x),run_time);
cal_err(i) = err;
cal_steps(i) = times;
i = i + 1;
end
nn = -0.5:0.01:5;
figure
plot(nn,cal_err,nn,cal_steps);
% 按照顺序标识标识图形
legend('计算误差', '迭代次数');
% 添加标题
title('方程2牛顿法计算结果');
% 添加 x 轴标签
% \pi 在图像中显示的小写希腊字母
xlabel('初值的每一分量');
% 添加 y 轴标签
% ylabel('y = sin(x)');
% plot(nn,cal_err);
% figure
% plot(nn,cal_steps);
% 定义方程组2 :输入x
function y = f2(x)
y(1,1) = 3*x(1,1) - cos(x(2,1)*x(3,1)) - 1/2;
y(2,1) = x(1,1)^2 - 81*(x(2,1) + 0.1)^2 +sin(x(3,1)) + 1.06;
y(3,1) = exp(-x(1,1)*x(2,1)) + 20*x(3,1) + (10*pi - 3)/3;
end
% 定义方程组2——Frechet导数
function y = df2(x)
y(1,:) = [3 x(3,1)*sin(x(2,1)*x(3,1)) x(2,1)*sin(x(2,1)*x(3,1))];
y(2,:) = [2*x(1,1) -162*(x(2,1) + 0.1) cos(x(3,1))];
y(3,:) = [-x(2,1)*exp(-x(1,1)*x(2,1)) -x(1,1)*exp(x(1,1)*x(2,1)) 20];
end
%----- code Newton法 for 实验4.1(2) -----
%----- code Newton法 for 实验4.1(2) -----
%----- code Newton法 for 实验4.1(2) -----
% clc %清除命令窗口的内容
clear all; %清除工作空间的所有变量,函数,和MEX文件
format long ; %设置输出显示格式为16位有效数字
%--------------------- 数值分析 实验4.1 算法设计与比较 ---------------------
% x_0_0 = input('请输入初值x0的每一分量: ');%为了便于比较取初值3个分量相同
% 定义数组存放计算误差、迭代步数
cal_err = [];
cal_steps = [];
i = 1;
for n = 0.1:0.5:20
% x_k1 为x^(k+1) ,x_k为x^(k)
x_0 = [n,n,n]'; % 初值
times = 0;
x_k = x_0;
delta_x = [1,1,1]';
tol = 1e-8;
A = df1(x_k); % A为F'(x)
tic;
while norm(delta_x) > tol
x_k1 = x_k - pinv(A)*f1(x_k);
delta_x = x_k1 - x_k;
delta_y = f1(x_k1) - f1(x_k);
A = A + (delta_y - A*delta_x)*delta_x'/(delta_x'*delta_x);
x_k = x_k1;
times = times + 1;
if times > 10000
disp('迭代超10000仍未达到精度要求,可能不收敛')
break
end
end
run_time = toc;
err = norm(x_k-x_0,inf);%计算误差
disp('---------------- 拟Newton法_output ----------------');
fprintf('初值x0 = [ %4.1f, %4.1f, %4.1f ] \n',n,n,n);
fprintf('方程组1_计算结果_拟牛顿法的解 x_k = [ %16.15f, %16.15f, %16.15f ] \n',x_k(1,1),x_k(2,1),x_k(3,1));
fprintf('迭代次数为: %2d, 计算误差为: %16.15e , 最后两步迭代差为: %16.15e , CPU计算时间:%16.15f s \n',times,err,norm(delta_x),run_time);
cal_err(i) = err;
cal_steps(i) = times;
i = i + 1;
end
nn = 0.1:0.5:20;
figure
plot(nn,cal_err,nn,cal_steps);
% 按照顺序标识标识图形
legend('计算误差', '迭代次数');
% 添加标题
title('方程1拟牛顿法计算结果');
% 添加 x 轴标签
% \pi 在图像中显示的小写希腊字母
xlabel('初值的每一分量');
% 添加 y 轴标签
% ylabel('y = sin(x)');
% plot(nn,cal_err);
% figure
% plot(nn,cal_steps);
% 定义方程组1 :输入x√ç
function y = f1(x)
y(1,1) = 12*x(1,1) - x(2,1)^2 - 4*x(3,1) -7;
y(2,1) = x(1,1)^2 + 10*x(2,1) - x(3,1) - 11;
y(3,1) = x(2,1)^3 + 10*x(3,1) - 8;
end
% 定义方程组1——Frechet导数
function y = df1(x)
y(1,:) = [12 -2*x(2,1) -4];
y(2,:) = [2*x(1,1) 10 -1];
y(3,:) = [0 3*x(2,1)^2 10];
end
%----- code Newton法 for 实验4.1(2) -----
%----- code Newton法 for 实验4.1(2) -----
%----- code Newton法 for 实验4.1(2) -----
% clc %清除命令窗口的内容
clear all; %清除工作空间的所有变量,函数,和MEX文件
format long ; %设置输出显示格式为16位有效数字
%--------------------- 数值分析 实验4.1 算法设计与比较 ---------------------
% x_0_0 = input('请输入初值x0的每一分量: ');%为了便于比较取初值3个分量相同
% 定义数组存放计算误差、迭代步数
cal_err = [];
cal_steps = [];
i = 1;
for n = 0.0:0.01:2
% x_k1 为x^(k+1) ,x_k为x^(k)
x_0 = [n,n,n]'; % 初值
times = 0;
x_k = x_0;
delta_x = [1,1,1]';
tol = 1e-8;
A = df1(x_k); % A为F'(x)
tic;
while norm(delta_x) > tol
x_k1 = x_k - pinv(A)*f2(x_k);
delta_x = x_k1 - x_k;
delta_y = f2(x_k1) - f2(x_k);
A = A + (delta_y - A*delta_x)*delta_x'/(delta_x'*delta_x);
x_k = x_k1;
times = times + 1;
if times > 10000
disp('迭代超10000仍未达到精度要求,可能不收敛')
break
end
end
run_time = toc;
err = norm(x_k-x_0,inf);%计算误差
disp('---------------- Newton法_output ----------------');
fprintf('初值x0 = [ %4.1f, %4.1f, %4.1f ] \n',n,n,n);
fprintf('方程组1_计算结果_牛顿法的解 x_k = [ %16.15f, %16.15f, %16.15f ] \n',x_k(1,1),x_k(2,1),x_k(3,1));
fprintf('迭代次数为: %2d, 计算误差为: %16.15e , 最后两步迭代差为: %16.15e , CPU计算时间:%16.15f s \n',times,err,norm(delta_x),run_time);
cal_err(i) = err;
cal_steps(i) = times;
i = i + 1;
end
nn = 0.0:0.01:2;
figure
plot(nn,cal_err,nn,cal_steps);
% 按照顺序标识标识图形
legend('计算误差', '迭代次数');
% 添加标题
title('方程2拟牛顿法计算结果');
% 添加 x 轴标签
% \pi 在图像中显示的小写希腊字母
xlabel('初值的每一分量');
% 添加 y 轴标签
% ylabel('y = sin(x)');
% plot(nn,cal_err);
% figure
% plot(nn,cal_steps);
% 定义方程组2 :输入x
function y = f2(x)
y(1,1) = 3*x(1,1) - cos(x(2,1)*x(3,1)) - 1/2;
y(2,1) = x(1,1)^2 - 81*(x(2,1) + 0.1)^2 +sin(x(3,1)) + 1.06;
y(3,1) = exp(-x(1,1)*x(2,1)) + 20*x(3,1) + (10*pi - 3)/3;
end
% 定义方程组2——Frechet导数
function y = df2(x)
y(1,:) = [3 x(3,1)*sin(x(2,1)*x(3,1)) x(2,1)*sin(x(2,1)*x(3,1))];
y(2,:) = [2*x(1,1) -162*(x(2,1) + 0.1) cos(x(3,1))];
y(3,:) = [-x(2,1)*exp(-x(1,1)*x(2,1)) -x(1,1)*exp(x(1,1)*x(2,1)) 20];
end