用matlab实现割线法、牛顿法求解非线性方程组

利用割线法求解非线性方程组代码

%% 利用割线法求F(x)=0的根
% F(x)=|x1+x2-3    |=0
%      |x1^2+x2^2-9|
% 初始点(1,5)',精确解(0,3)',(3,0)'

%% 主程序
function main
format long 
clear all,clc,
szfun1=zeros(1,50);
X=cell(1,100);
J=zeros(1,100);
szfun2=zeros(1,50);%预存数组
% 牛顿法
tic,[szfun1,k1]=newton;s1=toc
hold on;
rx1=1:1:k1-1;
szfun1=szfun1(1:length(rx1));
plot(rx1,szfun1,':^b');
% 割线法
tic,[szfun2,k2]=Secant_Mth;s2=toc
rx2=1:1:k2-1;
szfun2=szfun2(1:length(rx2));
plot(rx2,szfun2,':or');
title('两种数值方法比较');
xlabel('迭代次数k');ylabel('|f(x)|函数值');
legend(['牛顿法','time:',num2str(s1)],['割线法','time:',num2str(s2)]);
end
%% 牛顿法迭代格式
function [szfun1,k1]=newton
x0=[1,5]';xk=x0;k1=1;fk=norm(fun(xk),1);
while fk>1/2*10^-6
    szfun1(k1)=fk;X(k1)={xk};
    df=dfun(xk);
    J(k1)=det(df);%函数的导数值
    %避免导数过小
    if norm(df,2)<10^-10
        df=df+1/2*rand(1);
    end
    xk_1=xk-df\fun(xk)';%牛顿迭代公式
    xk=xk_1;%更新点
    fk=norm(fun(xk),1);
    k1=k1+1;
end
disp('迭代点:'),X{1:k1-1},
disp('雅可比矩阵:'),J(1:k1-1),
end
%% 割线法迭代格式
function [szfun2,k2]=Secant_Mth
% h 初始迭代的步长
x0=[1;5];xk=x0;k2=1;sk=[0;0];
funk=fun(xk);
fk=norm(funk,2);
% 初始A0
A0=dfun(x0);Ak=A0;
while fk>1/2*10^-6
    szfun2(k2)=fk; X(k2)={xk}; 
    J(k2)=det(Ak);%记录迭代点信息
    sk=XXFC(Ak,-funk'); %求解Ak*sk=-funk
    %sk=Ak\-funk';
    xkk=xk+sk; %更新迭代点
    funkk=fun(xkk);
    yk=funkk'-funk'; %两个迭代点函数值差
    Ak=Ak+((yk+funk')*sk')/(sk'*sk); %更新Ak
    fk=norm(funkk,2);
    xk=xkk;funk=funkk;
    k2=k2+1;
end
disp('迭代点:'),X{1:k2-1},
disp('近似雅可比矩阵Ak:'),J(1:k2-1)
end
%% 列主元高斯解线性方程组
function x=XXFC(A,y)
k=0;%分类标记
if A(1,1)>A(2,1)
    A=A;
else
    %列主元交换
    b= A(1,:);
    A(1,:)= A(2,:);
    A(2,:)=b;
    a=y(1);
    y(1)=y(2);
    y(2)=a;
    k=1;
end
A(2,2)=A(2,2)-(A(2,1)/A(1,1))*A(1,2);
y(2)=y(2)-(A(2,1)/A(1,1))*y(1);
x(2)=y(2)/A(2,2);
x(1)=(y(1)-A(1,2)*x(2))/A(1,1);
x=x';
end

%% 辅助函数
function y=fun(x)
y(1)=x(1)+x(2)-3;
y(2)=x(1)^2+x(2)^2-9;
end
% 函数导数
function dy=dfun(x)
dy(1,:)=[1,1];
dy(2,:)=[2*x(1),2*x(2)];
end

用matlab实现割线法、牛顿法求解非线性方程组_第1张图片

你可能感兴趣的:(数学,matlab)