%%牛顿法和牛顿下山法
% h=@(x) x.^3+x.^2-1;
% x = newton_eq(h,1,1000);
function result=newton_eq(h,x,n)
%x为初始值
%n为迭代次数
f = matlabFunction(h);%转化为句柄形式
f1=matlabFunction(diff(h));%weishixian
X(1)=x;
i=2;
while 1
X(i)=X(i-1)-lamda*f(X(i-1))/f1(X(i-1));
if abs(f(X(i)))<1e-6
result=X(i);
return;
end
if abs(f(X(i)))
else
lamda=lamda/2;
end
if i> n
result=X(i);
return;
end
i=i+1;
end
%%弦截法
h=@(x) x.^3+x.^2-1;
[x,tol] = xianjie(h,[1,2],1000);
function [result,to]=xianjie(f,x,n)
if nargout==1
flag=1;
elseif nargout==2
flag=2;
end
x1=x(1);
x2=x(2);
i=1;
while i < n
x3=x2-f(x2)*(x2-x1)/(f(x2)-f(x1));
if abs(f(x3))<1e-6
if flag==1
result=x3;
return;
elseif flag==2
result=x3;
to=abs(f(x3));
return;
end
end
x1=x2;
x2=x3;
i=i+1;
end
%%抛物线法
h=@(x) x.^3+x.^2-1;
[x,tol] = paowuxian(h,[-5,0,5]);
function [result,tol]=paowuxian(h,x)
if nargout==1||nargout==0
flag=1;
elseif nargout==2
flag=2;
end
f=h;
x1=x(1);
x2=x(2);
x3=x(3);
while 1
y1=f(x1);
y2=f(x2);
y3=f(x3);
f1=lagrange([x1,x2,x3],[y1,y2,y3]);
a=f1(1);b=f1(2);c=f1(3);
if b^2-4*a*c<=0
disp('初值不合适');
result=[];
tol=[];
return;
end
x4_1=(-b+sqrt(b^2-4*a*c))/(2*a);
x4_2=(-b-sqrt(b^2-4*a*c))/(2*a);
if abs(x1-x4_1)
else
x4=x4_2;
end
if abs(f(x4))<1e-6
if flag==1||flag==0
result=x4;
return;
elseif flag==2
result=x4;
tol=abs(f(x4));
return;
end
end
x1=x2;
x2=x3;
x3=x4;
end
%% fzero
% 用法1
x1=fzero('x.^2-2',1);%根趋近于1
x2=fzero('x.^2-2',[0,3]);%根在【0,3】区间里
%用法二
x3=fzero(@myfun,2)
%新建一个脚本文件
% function y=myfun(x)
% y=x.^2-2+x.^3;
fun=@(x) x.^2-2+x.^3;
x4=fzero(fun,2);
options=optimset('Display','Final')%notify
fun=@(x) x.^2-2+x.^3;
x5=fzero(fun,2,options);
[x6,fval]=fzero(fun,2);
[x6,fval,exitflag]=fzero(fun,2);
%% solve
%第一种
%re=sovle('2*x==a','x') 将会移除
syms a x
rel=solve(2*x^2==a,x)
%第二种
syms a b c x
y=a*x^2+b*x+c %y==0
re2=solve(y,x)
%第三种
syms a b c x
y=a*x^2+b*x+c==2 %y==0
re2=solve(y,x)
%第四种
syms x
y=sin(x)*cos(x)
re3=solve(y,x)%求解一个解
[re3,pa,cond]=solve(y,x,'ReturnConditions',true)%pa返回的是参数,cond返回的是参数条件
assume(cond)
interval=[re3>0,re3<2*pi]
s=solve(interval,pa)
v=subs(re3,pa,s)
%多变量
syms a b c x1 x2
y1=a*x1^2+b*x2+c;
y2=a*x1^2-2*b*x2-c^2;
[x1,x2]=solve([y1,y2],[x1,x2])
syms x
y=x^3+1==0;
x1=solve(y,x,'Real',ture)
%多项式
syms x
y=x^3+x^2+1==0
x1=solve(y,x)
x1=vpa(x1,10)%显示计算后的精度
x2=solve(y,x,'MaxDegree',3)%显示三阶的结果
%
syms x y
f1=x+2*y==1
f2=x^2-y==0
[x,y]=solve([f1,f2],[x,y])
%% fsolve
% global x3
% x3=2;
[x,fval]=fsolve('demo_fsolve1',[1 1])
%
[x,fval]=fsolve('demo_fsolve1',[1 1],[],2)
% 函数形式:function f=demo_fsolve(x0,x3)
my.options=optimoptions('fsolve','Display','none');
my.objective=@demo_fsolve1;
my.x0=[1 1];
my.solver='fsolve';
x=fsolve(my)
function f=demo_fsolve1(x0)
% global x3
x1=x0(1);
x2=x0(2);
f(1)=x1.^3+x2.^2-5;
% f(1)=x1.^3+x2.^2-5+x3;
f(2)=(x1+1)*x2-(3*x1+1);
x10=[0 0;0 0];
option=optimoptions('fsolve','Display','iter');%final最后输出
%MaxIterations 迭代次数若求不出结果可设的大一点
%Algorithm 若求不出结果,算法同样可改变 trust-region-doglag trust-region L-M levenberg-marquardt
x=fsolve('demo_fsolve2',x10);
function f=demo_fsolve2(x)
x1=x;
f=x1*x1+x1-[2 3;4 5];
x=[0,0];
[x,fval]=fsolve('mymain',x,option,2,3)
function f=mymain(x,y1,y2)
r=myfun1(x);
f(1)=r(1)^2++r(3)-y1^2-y2;
f(2)=r(2)^2*y2+y1-r(1);
function r=myfun1(x)
x1=x(1);
x2=x(2);
r(1)=x1*x2+6*x1+x2^2;
r(2)=x1*x2-x2+x1*x2^2;
r(3)=x2-x2^3+x1*x2^2;
%% 线性方程组--高斯消元法
A=[1 2 3 5;5 2 3 1;8 4 1 3;8 5 2 1;];
b=[5;8;2;4;];
x=GS(A,b)
function X=GS(A,b)
%高斯消元法,本例仅计算有唯一解的非线性齐次方程
if det(A)==0,error('行列式为0,求解终止');end
m=size(A,1);
A=[A,b];
%% 消元
for i=1:m-1
a=A(i,i);
if a==0
fprintf('第%d个主元为0,求解结束',i);
return;
end
for j =i+1:m
k=A(j,i)/a;
A(j,:)=A(j,:)-k*A(i,:);
end
end
%% 回代
for i=m:-1:2 %共有m-1列需要回代
a=A(i,i);
for j=i-1:-1:1
k=A(j,i)/A(i,i);
A(j,:)=A(j,:)-k*A(i,:);
end
end
%% 对角线单位化,求X的值
for i=1:m
A(i,:)=A(i,:)/A(i,i);
X(i)=A(i,end);
end
%% 线性方程组--列主元法
A=[0.001 2 3;-1 3.712 4.623;-2 1.072 5.643];
b=[1 2 3]';
x1=A\b;
x=GS_col(A,b);
function X=GS_col(A,b)
%高斯消元法,列主元消去法
if det(A)==0,error('行列式为0,求解终止');end
m=size(A,1);
A=[A,b];
%% 消元
for i=1:m-1
%寻找第一列最大主元
c=A(i:end,i);%取出第i列的第i个到最后一个元素
id=find(abs(c)==max(abs(c)));%计算绝对值最大的位置
row=id(1)+i-1;%因为可能有相同的最大元素,取第一个
%交换行
temp=A(i,:);
A(i,:)=A(row,:);
A(row,:)=temp;
a=A(i,i);
if a==0
fprintf('第%d个主元为0,求解结束',i);
return;
end
for j =i+1:m
k=A(j,i)/a;
A(j,:)=A(j,:)-k*A(i,:);
end
end
%% 回代
for i=m:-1:2 %共有m-1列需要回代
for j=i-1:-1:1
k=A(j,i)/A(i,i);
A(j,:)=A(j,:)-k*A(i,:);
end
end
%% 对角线单位化,求X的值
X=zeros(m,1);
for i=1:m
A(i,:)=A(i,:)/A(i,i);
X(i)=A(i,end);
end
%% 线性方程组--三角分解法
A=[2 2 -1;1 2 -3;1 -2 1];
b=[2;6;10];
x=A\b;
x1=inv(A)*b;
%% lu
[l,u]=lu(A);
x2=u\(l\b);
%% qr
[q,r]=qr(A);
x3=r\(q\b);
%% LDU
[l,d,u]=LDU(A);%自己写的函数LDU
x4=u\(d\(l\b));
%% 线性方程组--迭代法
B0=[0 3/8 -2/8;-4/11 0 1/11;-6/12 -3/12 0];
f=[20/8 33/11 36/12]';
x0=[0 0 0]';
for i=1:10
x1=B0*x0+f;
x0=x1;
end
%% 线性方程组--雅克比迭代法
A=[8 -3 2;4 11 -1;6 3 12];
b=[20 33 36]';
x0=[0 0 0]';
[x,k]=jacobi(A,b,x0,200)%k迭代哪一次得出的结果
function [result,k]=jacobi(A,b,x0,n)
%线性方程组迭代求解,雅克比迭代
%A为系数矩阵
%b为常数向量
%x0为初始值
D=diag(diag(A));
L=-tril(A,-1);%下三角矩阵,-1表示从对角线下一行开始取
U=-triu(A,1);%上三角矩阵,1表示从对角线上一行开始取
B=D^(-1)*(L+U);
r=vrho(B);%谱半径,特征值绝对值最大的那一个,小于1收敛
if r>1
disp('无法收敛');
return;
end
f=D^(-1)*b;
i=1
while i
if norm(x1-x0)<1e-6
result=x1;
k=i;
return;
end
x0=x1;
i=i+1;
end
%% 线性方程组--高斯-赛德尔迭代法
A=[8 -3 2;4 11 -1;6 3 12];
b=[20 33 36]';
x0=[0 0 0]';
x=gauss_seidel(A,b,x0)%k迭代哪一次得出的结果
function result=gauss_seidel(A,b,x0)
%线性方程组迭代求解,高斯-赛德尔,可以利用当前解得前面的分量求解后面的分量
%A为系数矩阵
%b为常数向量
%x0为初始值
D=diag(diag(A));
L=-tril(A,-1);%下三角矩阵,-1表示从对角线下一行开始取
U=-triu(A,1);%上三角矩阵,1表示从对角线上一行开始取
B=(D-L)^(-1)*U;
r=vrho(B);%谱半径,特征值绝对值最大的那一个,小于1收敛
if r>1
disp('无法收敛');
return;
end
f=(D-L)^(-1)*b;
i=1;
while 1
x1=B*x0+f;
if norm(x1-x0)<1e-8
result=x1;
return;
end
if i>1000
return;
end
x0=x1;
i=i+1;
end
%% 线性方程组--Sor迭代法
A=[8 -3 2;4 11 -1;6 3 12];
b=[20 33 36]';
x0=[0 0 0]';
[x,k]=Sor(A,b,x0,1);
function [result,k]=Sor(A,b,x0,w)
%线性方程组迭代求解,逐次超松弛,successive over relaxation method M=1/w*(D-wL)
%w=1,为gauss_seidel迭代,w>1为超松弛迭代,w<1为低松弛迭代,松弛迭代因子只有在0-2范围内才可能收敛
%A为系数矩阵
%b为常数向量
%x0为初始值
D=diag(diag(A));
L=-tril(A,-1);%下三角矩阵,-1表示从对角线下一行开始取
U=-triu(A,1);%上三角矩阵,1表示从对角线上一行开始取
B=(D-w*L)^(-1)*((1-w)*D+w*U);
r=vrho(B);%谱半径,特征值绝对值最大的那一个,小于1收敛
if r>1
disp('无法收敛');
return;
end
f=w*(D-w*L)^(-1)*b;
i=1;
while 1
x1=B*x0+f;
if norm(x1-x0)<1e-8
result=x1;
k=i;
return;
end
if i>1000
return;
end
x0=x1;
i=i+1;
end
A=[5 2 6 0 0 1 0;
4 5 1 0 0 0 0;
0 0 0 2 3 1 0;
1 0 2 3 1 0 0;
5 2 0 1 2 3 0;
0 0 0 1 2 0 3;
2 0 3 0 1 0 0;];
b=[1 2 5 6 3 4 0]';
%% bicg
x1=A\b;
x=bicg(A,b);
maxit=15;
x=bicg(A,b,1e-14,maxit);%1e-14是自己指定的相对残差,不一定能达到,maxit是自定义迭代次数,范围在min(阶数,20)
M1=rand(7);%预处理器
M2=rand(7);%inv(M)*Ax=inv(M)*b
x=bicg(A,b,1e-14,maxit,M1,M2);
[x,flag,relres,iter,resvec]=bicg(A,b,1e-14,maxit,M1,M2);%flag为验证指标,若为0,则是比较成功收敛的
%relres是相对残差 norm(b-Ax)/norm(b),iter为迭代次数,resvec为每次迭代的相对残差
%% cgs 与上一个函数用法类似
x=cgs(A,b);
maxit=15;
x=cgs(A,b,1e-14,maxit);%1e-14是自己指定的相对残差,不一定能达到,maxit是自定义迭代次数,范围在min(阶数,20)
M1=rand(7);%预处理器
M2=rand(7);%inv(M)*Ax=inv(M)*b
x=bicg(A,b,1e-14,maxit,M1,M2);
[x,flag,relres,iter,resvec]=cgs(A,b,1e-14,maxit,M1,M2);%flag为验证指标,若为0,则是比较成功收敛的
%relres是相对残差 norm(b-Ax)/norm(b),iter为迭代次数,resvec为每次迭代的相对残差
A=[5 2 6 0 0 1 0;
4 5 1 0 0 0 0;
0 0 0 2 3 1 0;
1 0 2 3 1 0 0;
5 2 0 1 2 3 0;
0 0 0 1 2 0 3;
2 0 3 0 1 0 0;];
b=[1 2 5 6 3 4 0]';
%% lsqr
x=lsqr(A,b);
maxit=15;
x=lsqr(A,b,1e-14,maxit);%1e-14是自己指定的相对残差,不一定能达到,maxit是自定义迭代次数,范围在min(阶数,20)
M1=rand(7);%预处理器
M2=rand(7);%inv(M)*Ax=inv(M)*b
x=lsqr(A,b,1e-15,maxit,M1,M2);
x0=[0.1 0.2 0.2 0.3 0.2 0.1 0.3]';
x=lsqr(A,b,1e-15,maxit,M1,M2,x0);%给定一个初值,比较靠近真实值,默认的都是给定0
[x,flag,relres,iter,resvec]=lsqr(A,b,1e-14,maxit,M1,M2);%flag为验证指标,若为0,则是比较成功收敛的
%relres是相对残差 norm(b-Ax)/norm(b),iter为迭代次数,resvec为每次迭代的相对残差
%% minres
A=[5 2 6 0 0 1 0;
2 5 1 0 0 0 0;
6 1 0 2 3 1 0;
0 0 2 3 1 0 0;
0 0 3 1 2 2 1;
1 0 1 0 2 0 0;
0 0 0 0 1 0 0;];%需对称,若不对称相对残差则比较大
b=[1 2 5 6 3 4 0]';
x=minres(A,b)%默认1e-6
x1=minres(A,b,1e-15);%指定相对残差
x2=minres(A,b,1e-15,13);%指定迭代次数
M1=rand(7);%预处理器
M2=rand(7);
M1=tril(M1,-1)+triu(M1',0);%使其对称
M2=tril(M2,-1)+triu(M2',0);
M1=M1'*M1;%使其为正定矩阵,特征值不能小于0
M2=M2'*M2;
x3=minres(A,b,1e-15,maxit,M1);%使用一个,M1*M2可能就不是对称正定矩阵了
x0=[0.1 0.2 0.2 0.3 0.2 0.1 0.3]';
x=minres(A,b,1e-15,maxit,M1,[],x0);%给定一个初值,比较靠近真实值,默认的都是给定0
[x,flag,relres,iter,resvec]=minres(A,b,1e-14,maxit,M1);
%% gmr 用法类似
%% gmres 用法类似
%% 非线性方程组-不动点迭代
[X,tol]=budongdian_system(@mybudongdian,[1 0.1],800)
x=fsolve(@mybudongdian,[1,0.1]);%与上式等价,这里利用fsolve函数求解
function x=mybudongdian(x0)
x1=x0(1);
x2=x0(2);
x(1)=0.5*sin(x1)+0.1*cos(x1*x2)-x1;
x(2)=0.5*cos(x1)-0.1*cos(x2)-x2;
function [X,Tol]=budongdian_system(f,x0,n)
e=1e-6;
x0=x0(:);
i=1;
while 1
x1=f(x0)'+x0;
if norm(x0-x1)
Tol=f(X);
return;
end
x0=x1;
i=i+1;
if i>n
X=x0;
Tol=f(X);
return;
end
end
syms x1 x2
F=[x1^2-2*x1-x2+0.5;x1^2+4*x2^2-4];
[X,tol]=newton_sys(F,[1,1],20)
% t=matlabFuntion(F)
% x=fsolve(@my_newton,[1,1])%不完整需写成文件的形式
function [X,tol]=newton_sys(f,x0,n)
e=1e-6;
F=matlabFunction(f);%函数句柄,仍未实现
F1=jacobi(f,symvar(f))^(-1);
B=symval(F1);
F1=matlabFunction(F1);%雅克比矩阵的句柄
i=1;
h=length(x0);
m=length(B);
FF='F(';
FF1='F1(';
for k=1:h
FF=[FF,'x0(',num2str(k),')'];
for j=1:m
A=char(B(j))
if A==['x',num2str(k)]
FF1=[FF1,'x0(',num2str,'),']
end
end
end
FF(end)=')';
FF1(end)=')';
while 1
x1=x0(:)-eval(FF1)*eval(FF);
if norm(x0-x)
tol=eval(FF);
return;
end
if i>n
X=x0;
tol=eval(FF);
return;
end
i=i+1;
x0=x1;
end