matlab 学习笔记

原文地址:matlab 学习笔记 作者:w104814
画图部分

参考资料:何正风 Matlab在数学方面的应用 北京 清华大学出版社 2012
clear;clc%在绘制的等高线上绘制向量图
n=-2.0:.2:2.0;
[X,Y,Z]=peaks(n);
contour(X,Y,Z,10);
[U,V]=gradient(Z,.2);
hold on
quiver(X,Y,U,V)
hold off

clear;clc%绘制函数的三维空间曲线
[X,Y]=meshgrid([-2:0.1:2]);
Z=X.*exp(-X.^2-Y.^2);
plot3(X,Y,Z)
grid on
set(gcf,'color','r');

clear;clc % 用三维曲线图、三维网格图及三维曲面图表现函数
x=-2*pi:0.1:2*pi;
[x,y]=meshgrid(x);
z=sin(2*y)+sin(2*x).*cos(2*y);
figure;plot3(x,y,z);%三维曲线图
xlabel('x轴');ylabel('y轴');zlabel('z轴');
title('三维曲线图');
set(gcf,'color','w');
figure;mesh(x,y,z);%三维网格图
xlabel('x轴');ylabel('y轴');zlabel('z轴');
title('三维网格图');
set(gcf,'color','w');
figure;surf(x,y,z); %三维曲面图
xlabel('x轴');ylabel('y轴');zlabel('z轴');
title('三维曲面图');
set(gcf,'color','w');

clear;clc % 标准三维曲面图的绘制
t=0:pi/10:2*pi;
[X,Y,Z]=cylinder(2+cos(t));
subplot(2,2,1);
surf(X,Y,Z);
title('圆柱图');
axis square
[x,y,z]=ellipsoid(0,0,0,5.9,3.25,3.25,30);
subplot(2,2,2);
surfl(x,y,z);
title('椭圆图');
colormap hsv
axis equal 
[x,y,z]=sphere;
subplot(2,2,3);
surf(x,y,z);
axis equal 
title('球体');
[x,y,z]=peaks;
subplot(2,2,4);
meshz(x,y,z);
title('多峰图');

图像处理


clear;clc %利用image函数显示图像
ax(1)=subplot(1,2,1);
rgb=imread('ngc6543a.jpg');
image(rgb);xlabel('(a)显示RGB图像');
ax(2)=subplot(122);
im=mean(rgb,3);
image(im);xlabel('(b)显示强度热图');
colormap(hot(256));
linkaxes(ax,'xy');
axis(ax,'image');


clear;clc %利用imagesc函数显示图像
load optdeblur P
[m,n]=size(P);
mn=m*n;
imagesc(P);
colormap(gray);
axis off image;
title([int2str(m) ' x ' int2str(n) '( ' int2str(mn) ')pixels'])

clear;clc %利用imshow函数显示图像
I=imread('rice.png');
J=filter2(fspecial('sobel'),I);%sobel算子
K=mat2gray(J);
subplot(1,2,1);imshow(I);
xlabel('(a)原始图像');
subplot(1,2,2);imshow(K);
xlabel('(b)sobel 算子图像');

clear;clc %查询ngc6543a.jpg图像的信息
info=imfinfo('ngc6543a.jpg')


动画制作



clear;clc %擦除式制作动画 建立一个随时间变化而变化的曲线
t=0:pi/20:2*pi;
y=exp(sin(t));
h=plot(t,y,'YDataSource','y');
for k=1:.1:10
      y=exp(sin(t.*k));
      refreshdata(h,'caller')
      drawnow;
      pause(.1)
end

clear;clc %擦除式制作动画 模拟布朗运动
n=45;
s=0.1;
x=rand(n,1)-0.4;
y=rand(n,1)-0.4;
h=plot(x,y,'.');
axis([-1 1 -1 1]);
axis square;grid on;
set(h,'EraseMode','xor','MarkerSize',24);
for i=linspace(1,5,10000)
      drawnow
      x=x+s*randn(n,1);
      y=y+s*randn(n,1);
      set(h,'XData',x,'YData',y);
end
set(gcf,'color','w');

clear;clc %使用comet函数建立一个质点绘制随机运行轨迹
t=0:0.01:2*pi;
x=cos(2*t).*(cos(t).^2);
y=sin(2*t).*(sin(t).^2);
comet(x,y);

clear;clc %使用comet3函数建立一个质点绘制随机运行轨迹
t=-10*pi:pi/250:10*pi;
comet3((cos(2*t).^2).*sin(t),(sin(2*t).^2).*cos(t),t);

clear;clc %电影式制作动画 建立一个绕Z旋转的peaks 动画效果
figure('position',[100 100 850 600])
Z=peaks;surf(Z);
axis tight;
set(gca,'nextplot','replacechildren');
%记录影片
for j=1:20
      surf(sin(2*pi*j/20)*Z,Z)
      F(j)=getframe;
end
[h,w,p]=size(F(1).cdata);
hf=figure;
set(hf,'position',[150 150 w h]);
axis off
movie(hf,F,4,30,[0 0 0 0]);


科学计算 




clc;clear;%求向量和矩阵的和玉积
X=[9 1 -3 7 12 4 -13 -1 6];
S1=sum(X),P1=prod(X)%求向量的和于积
B=magic(4)
S2=sum(B),P2=prod(B)%以行向量操作
S3=sum(B,2),P3=prod(B,2)%以列向量操作

clc;clear;%求向量和矩阵的平均值与中值
X=[9 1 -3 7 12 4 -13 -1 6];
S1=mean(X),P1=median(X)%求向量的
B=magic(4)
S2=mean(B),P2=median(B)%以行向量操作
S3=mean(B,2),P3=median(B,2)%以列向量操作

clc;clear;%相关系数
x=randn(30,4);
x(:,4)=sum(x,2);
[r,p]=corrcoef(x)%计算相关系数及p-值
[i,j]=find(p<0.05)

clc;clear;%对向量和矩阵的排序
X=[9 1 -3 7 12 4 -13 -1 6];
S1=sort(X)%对向量进行s升序排序
S4=-sort(-X)%降序排序
B=magic(4)
S2=sort(B)%以行向量操作
S3=sort(B,2)%以列向量操作


%求函数的极限,速度好慢啊!
clear;clc
syms x h a b;
f1=limit ((sin(x+h)-sin(x))/h,h,0)

%求函数的导数
clear;clc
syms a b c x
f1=2*x*sin(x)-cos(x);
f2=c/(a+exp(b*x));
f3=(x-sin(x))^2;
f4=(2*x+3)*exp(2-3*x);
F=[f1,f2,f3,f4];
df=diff(F,x)%求每个函数的导数
df0=subs(df,'x',0)

clear;clc%复合函数的4阶导数
syms x
f=exp(-2*x)*cos(3*x^0.5)
g=diff(f,4)
pretty(g)%

clear;clc%求函数的积分运算
syms alpha t x;
f1=exp(alpha*t);
F1=int(f1)
f2=5*x*exp(alpha*t)
F2=int(f2,t)
F3=int(4*x/t,t,2,sin(x))

数值微积分及积数

clear;clc%求函数的二阶及三阶差分,并绘制相应的差分效果图
syms x;
f1=1/(5+4*cos(x));
f2=diff(f1,2)
ezplot(f2)%绘制2阶差分效果图
axis([-2*pi 2*pi -5 2])
title('2阶差分效果图');
f3=diff(f2)
pretty(f3)%以常用方式显示
f3=simple(f3)%化解差分
zeros=solve(f3)%在函数上计算零点
format;
zerosd=double(zeros)%以数值形式显示零点
ezplot(f3)
hold on;
plot(zerosd,0*zerosd,'ro');
plot([-2*pi,2*pi],[0,0],'g-.');
title('带零点的3阶差分图')


数值积分

1辛普生法
基于变步长辛普生法,matlab提供了quad函数来求定积分.

clear;clc%
[Q,fnt]=quad('exp(-x)',0,3)

2牛顿-科特斯法
matlab提供了quadl函数利用牛顿-科特斯法求解定积分,其求定积分的效率可能比quad函数更好.

clear;clc%
[Q,fnt]=quad('exp(-x)',0,3,1e-9)
[Q,fnt]=quadl('exp(-x)',0,3,1e-9)


3梯形法
matlab提供了trapz函数利用梯形法求解函数的定积分。
clear;clc%
X=0:pi/100:pi;
Y=sin(X);
Z=trapz(X,Y)

二重定积分
在matlab中提供了dblquad函数可直接用于求二重积分的数值解
clear;clc%
xmin=pi;
xmax=2*pi;
ymin=0;
ymax=pi;
result=dblquad('y*sin(x)+x*cos(y)',xmin,xmax,ymin,ymax,[],@quadl)

在数控平面内二元函数积分(上下可出现函数)
matlab提供了quad2d函数用于实现在数控平面内的二元函数积分运算。
clear;clc%
fun=@(x,y)abs(x.^2+y.^2-0.25);
c=@(x)-sqrt(1-x.^2);
d=@(x)sqrt(1-x.^2);
quad2d(fun,-1,1,c,d,'AbsTol',1e-8,'FailurePlot',true,'Singular',false)


级数
matlab 提供了symsum函数实现级数的求和
clear;clc%
syms x n;
f1=symsum(1/n^2,1,inf)

matlab提供了taylor函数实现泰勒级数
clear;clc%
syms x 
f1=sqrt(1-2*x+x^4)-(1-3*x+x^2)^(1/4);
t1=taylor(f1,x,6)%6阶泰勒展开式

求解非线性方程(组)


1用数值法求解非线性方程

通过自定义编写secondfen.m函数实现利用二分法求解非线性方程的解。

function y=secondfen(fun,a,b,eps)%其中fun为目标函数,a,b为区间;eps误差
if(nargin<4)
      eps=le-4;
end
if feval_r(fun,a)*feval_r(fun,b)<0
      n=1;
      c=(a+b)/2;
      while c>eps
            if feval_r(fun,a)*feval_r(fun,c)<0
                  b=c;
                  c=(a+b)/2;
            elseif feval_r(fun,c)*feval_r(fun,b)<0
                        a=c;
                        c=(a+b)/2;
                  else
                        y=c;eps=100000;
                  end
                  n=n+1;
      end
            y=c;
  elseif feval_r(fun,a)==0
                  y=a;
      elseif feval_r(fun,b)==0
                        y=b;
else
      disp('方程木有根!');
end
n


例子:
首先建立
wang.m

function y=wang(x)
y=x^2-x-1;

实现代码
clear;clc
a=0;b=10;eps=0.05;
x=secondfen(@wang,a,b,eps)


迭代法

若方程f(x)=0写成x=y(x)

1.可选取一个初始近似值x0,构造Picard迭代序列,进行不动点迭代法

构建一个Picardfun.m实现利用不动点迭代法求解非线性方程的解

function [x,n]=Picardfun(f,x0,eps)
if(nargin==2)
      eps=1.0e-4;
end
tol=1;
x=x0;
n=0;
while(tol>eps)
      n=n+1;
      r1=x;
      x=subs(sym(f),findsym(sym(f)),r1)+r1;
      tol=abs(x-r1);
end
      

测试代码如下:

clear;clc
[r,n]=Picardfun('1/8*(35*x^4-30*x^2+3)',0.5)%迭代初始值为0.5

2.Steffensen迭代法(斯特芬森)解方程

编写自定义函数Steffensefun.m。实现利用Steffensen迭代法求解非线性方程的解.

function [x,n]=Steffensefun(f,x0,eps)
if(nargin==2)
      eps=1.0e-4;
end
tol=1;
x=x0;
n=0;
while(tol>eps)
      n=n+1;
      r1=x;
      y=subs(sym(f),findsym(sym(f)),r1)+r1;
      z=subs(sym(f),findsym(sym(f)),y)+y;
      x=r1-(y-r1)^2/(z-2*y+r1);
      tol=abs(x-r1);
end

测试代码如下:
clear;clc
[x,n]=Steffensefun('x^2-5*cos(2*x)-4',1,1e-6)

3.Newton迭代法
牛顿迭代法是超线性收敛的,编写自定义函数Newtonfun.m
function [x,n]=Newtonfun(f,x0,eps)
if(nargin==2)
      eps=1.0e-5;
end
df=diff(sym(f));
x1=x0;
n=0;
err=0.1;
while(err>eps)
      n=n+1;
      fx=subs(f,x1);
      df=subs(df,x1);
      x=x1-fx/df;
      err=abs(x-x1);
      x1=x;
end
end

测试代码:
  clear;clc
  [x,n]=Newtonfun('x^3+2*x^2+10*x-20',1.4,1e-5)


4.弦截法
如果f(x)=0在区间[a,b]内有根,用两点连线与x轴交点逼近曲线f(x)与x轴的交点。

自定义编写xianjiefun.m
function x=xianjiefun(f,a,b,eps)
if(nargin==3)
      eps=1.0e-4;
end
f1=subs(sym(f),findsym(sym(f)),a);
f2=subs(sym(f),findsym(sym(f)),b);
if(f1==0)
      x=a;
end
if(f2==0)
      x=b;
end
if(f1*f2>0)
disp('两端点函数值乘积大于0!');
return;
else
      tol=1;
      fa=subs(sym(f),findsym(sym(f)),a);
      fb=subs(sym(f),findsym(sym(f)),b);
      x=a-(b-a)*fa/(fb-fa);
      while(tol>eps)
            r1=x;
            fx=subs(sym(f),findsym(sym(f)),r1);
            s=fx*fa;
            if(s==0)
                  x=r1;
            else
                  if(s>0)
                        x=b-(r1-b)*fb/(fx-fb);
                  else
                        x=a-(r1-a)*fa/(fx-fa);
                  end
            end
            tol=abs(x-r1);
      end
end

测试代码如下:
clear;clc
x=xianjiefun('x^3-3*x-1',1.8,2,1e-5)

用数值法求解非线性方程组

1不动点迭代法
编写自定义函数mulPicardfun.m
function [x,n]=mulPicardfun(F,x0,eps)
if nargin==2
      eps=1.0e-6
end
x0=transpose(x0);
n=1;
tol=1;
while tol>eps
      x=subs(F,findsym(F),x0);
      tol=norm(x-x0);
      n=n+1;
      x0=x;
      if(n>100000)
            disp('迭代次数太多,可能不收敛');
            return;
      end
end
测试代码如下:
syms x y;
z=[0.5*sin(x)+0.1*cos(x*y)-x;0.5*cos(x)-0.1*cos(y)-y];
[r,n]=mulPicardfun(z,[0 1],1e-5)

2Newton迭代法
编写自定义函数 mulNewton.m
function [x1,n]=mulNewton(x0)
x1=x0-fc(x0)/df(x0);
n=1;
while(norm(x1-x0)>=1e-6)&(n<=1e+11)
      x0=x1;
      x1=x0-fc(x0)/df(x0);
      n=n+1;
end
测试代码如下:

function y=fc(x)%目标函数
y(1)=x(1)-0.7*sin(x(1))-0.2*cos(x(2));
y(2)=x(2)-0.7*cos(x(1))+0.2*sin(x(2));
y=[y(1) y(2)];

function y=df(x)%导数
y=[1-0.7*cos(x(1)) 0.2*sin(x(2));0.7*sin(x(1)) 1+0.2*cos(x(2))];

运行:
clear;clc
x0=[0.5 0.5];
[y,n]=mulNewton(x0)

3.拟牛顿迭代法
编写自定义函数 mulBroynewton.m
function [x,m]=mulBroynewton(F,x0,A,eps)
if nargin==2
      A=eye(length(x0));
      eps=1.0e-4;
else
      if nargin==3
            eps=1.0e-4;
      end
end
x0=transpose(x0);
Fx=subs(F,findsym(F),x0);
x=x0-AFx;
m=1;
tol=1;
while tol>eps
      x0=x;
      Fx=subs(F,findsym(F),x0);
      x=x0-AFx;
      y=x-x0;
      Fr=subs(F,findsym(F),x0);
      x=x0-AFx;
      y=x-x0;
      Fr=subs(F,findsym(F),x);
      z=Fr-Fx;
      A1=A+(z-A*y)*transpose(y)/norm(y);
      A=A1;
      m=m+1;
      if(m>100000)
            disp('迭代次数太多,可能不收敛');
            return;
      end
      tol=norm(x-x0);
end

测试代码如下:
clear;clc
syms x y;
z=[0.5*sin(x)+0.1*cos(x*y)-x;0.5*cos(x)-0.1*sin(y)-y];
[x,m]=mulBroynewton(z,[0.5 0.5])

用符号法求解非线性方程(组)

1.solve函数

clear;clc
syms a b c x;
x=solve('a*x^2+b*x+c')%求解x

clear;clc%利用matlab求解非线性方程组
syms x y z;
s1=x+y-1;s2=x+3*z^2-4;s3=y-z+11*x-5;
[u,v,w]=solve(s1,s2,s3)


2.fzero函数
clear;clc%利用fzero函数求一维变量的零点.
[x,fval,exitflag,output]=fzero('x^5+2*x^3-5*x+3',1,-1)

3。fsolve函数

首先定义一个wo.m
function F=wo(x)
F=[2*x(1)-x(2)-exp(-x(1));
      -x(1)+2*x(2)-exp(-x(2))];

运行:
clear;clc
x0=[-5;5];
options=optimset('Display','iter');
[x,fval,exitflag,output,Jacobian]=fsolve(@wo,x0,options)


求解线性方程(组)

1.LU分解线性方程组
   如果方阵A可以分解成一个下三角矩阵L与一个上三角矩阵U的乘积,这样的分解称为A的三角分解或者LU分解。
如果L为下三角矩阵时,称其为Doolittle分解,U为上三角矩阵时,称其为Crout分解。

%利用LU分解对线性方程组进行求解
clear;clc
A=[1 2 3;4 5 6;7 8 0];
[L1,U]=lu(A)
b=[7 -5 1]';
x=L1*Ub

分析结果发现得到的L1矩阵并非下三角矩阵,这是由于分解过程中采用了主元素交换的方法。
[L2,U,P]=lu(A)
此处的P矩阵不是一个单位矩阵,而是单位矩阵的置换矩阵。
inv(P)*L2*U%检验结果是否正确

在matlab中提供了luinc函数实现矩阵的不完全LU分解。

clear;clc%利用luinc函数对matlab自带的稀疏矩阵westo479进行不完全LU分解。
load west0479;
S=west0479;
[L,U]=lu(S);%对稀疏矩阵进行完全分解
subplot(1,2,1);%显示分解后的效果图。
spy(L);
subplot(1,2,2);
spy(U);


[L,U,P]=luinc(S,'0');
D=(L*U).*spones(P*S)-P*S;
subplot(2,2,1);%显示不完全分解的效果图
spy(L);
subplot(2,2,2);spy(U);
subplot(2,2,3);spy(P);
subplot(2,2,4);spy(D);

QR分解法求解线性方程组
QR分解法即将矩阵A分解称一个正交矩阵与一个上三角矩阵的乘积。

clear;clc%利用qr函数对创建的C系数矩阵进行分解。
C=gallery('uniformdata',[4,3],0);%这个在2012a以上版本运行。
[Q,R]=qr(C)
x=A(A'b)
[Q,R]=qr(C,0)%0表示经济型分解
[Q,R,P]=qr(C)

Cholesky分解法求解线性方程组

   如果A是对称正定矩阵,则必存在一个非奇异下三角矩阵G,使得A=GG',称为矩阵A的Cholesky分解,
而且当G的主对角元素为正时,这种分解是唯一的。

clear;clc%利用chol函数对线性方程组进行分解。
A=[1 1 1 1;1 2 3 4;1 3 6 10;1 4 10 20];
b=[3 15 21 12]';
R=chol(A)
x=R(R'b)

clear;clc%利用cholinc函数对创建的对称正定稀疏矩阵进行不完全Cholesky分解。
S=delsq(numgrid('C',15));
C=chol(S);
R0=cholinc(S,'0');
S2=S;S2(101,101)=0;
[R,p]=cholinc(S2,'0');
D1=(R0'*R0).*spones(S)-S;
D2=(R'*R).*spones(S2)-S2;
subplot(2,3,1);spy(C);
subplot(2,3,2);spy(R0);
subplot(2,3,3);spy(R);
subplot(2,3,4);spy(p);
subplot(2,3,5);spy(D1);
subplot(2,3,6);spy(D2);

双共轭梯度法求解线性方程组
   共轭梯度算法是一种迭代方法,它从一组初值向量出发,定义代价函数,进而转化为最优化问题。
它是寻找一个向量,这个向量使得计算的代价函数为极值,这里为最小值。

clear;clc%利用是双共轭梯度算法求解线性方程组
A=[23.6 -6.8 4.5 6.3 7.2 8.6
      4.2 7.62 0.8 -3.1 -4.5 5.3
      9.8 -6.8 45.2 3.07 -4.37 7.82;
      8.4 -9.05 24.4 2.65 6.53 -3.64;
      -9.5 4.54 15.8 4.89 4.8 -7.48;
      26.32 3.08 4.6 -3.5 -7.8 25.6];
b=[-9.50 8.12 42.30 -21.40 4.70 3.47]';
[x,flag,relres,iter,resverc]=bicg(A,b,1e-11)

广义最小残差法求解线性方程组

当迭代值x所引起的相对残差小于或等于给定的收敛值时,停止迭代。

clear;clc%利用gmres函数求解线性方程组
A=[25.4 -6.5 5.5 6.3 6.2 4.6
      4.5 7.62 0.7 -3.1 -4.5 5.1
      8.9 -6.8 5.2 3.07 -4.37 7.8
      8.4 -5.05 4.4 2.65 6.53 -4.4
      -9.5 4.54 6.3 4.89 4.8 -7.4
      6.3 4.08 1.6 -3.5 -7.8 5.6];
b=[-4.5 7.2 4.3 -2.4 24.7 5.7]';
[x,flag,relres,iter,resvec]=gmres(A,b)






微分方程的求解

微分方程的数值求解

刚性:对于一个常微分方程组,如果其Jocabian矩阵的特征值相关悬殊,那么这个方程组称为刚性方程组
1显式常微分方程组的求解

%求解非刚性方程y''-u(1-y^2)y'+y=0,其中u为参数1.
%这里先把原刚性方程化为1阶常微分方程组
function dydt=wang_1(t,y)
dydt=zeros(2,1);
dydt(1)=y(2);
dydt(2)=(1-y(1)^2)*y(2)-y(1);

运行:
clear;clc
[t,y]=ode45(@wang_1,[0,18],[2;0]);
plot(t,y(:,1),':',t,y(:,2),'-')


也可以设置成参数形式的
%求解非刚性方程y''-u(1-y^2)y'+y=0,其中u为参数.
%这里先把原刚性方程化为1阶常微分方程组
function dydt=wang_1(t,y,u)
dydt=zeros(2,1);
dydt(1)=y(2);
dydt(2)=u*(1-y(1)^2)*y(2)-y(1);

运行
clear;clc
[t,y]=ode45(@wang_1,[0,18],[2;0],[],6);%这里为参数u=6
plot(t,y(:,1),':',t,y(:,2),'-')

%求y''-1000(1-y^2)y'-y=0在初始条件y(0)=1.5,y'(0)=0.8下的数值解。
%先把原方程化为1阶常微分方程组
function dy=wang_2(t,y)
dy=zeros(2,1);
dy(1)=y(2);
dy(2)=1000*(1-y(1)^2)*y(2)-y(1);

运行:
clear;clc
[t,y]=ode15s(@wang_2,[0,2600],[2 0]);
plot(t,y(:,1),'-p')


%比较用ode23与ode45函数求解如下微分方程组的效果。
function yp=wang_3(t,y)
yp=diag([1-0.01*y(2),-1+0.02*y(1)])*y;

运行:
clear;clc
t0=0;
tfinal=15;
y0=[20 20]';
tfinal=tfinal*(1+eps);
[t,y]=ode23(@wang_3,[t0 tfinal],y0);
subplot(1,2,1);
plot(t,y);
xlabel('(a)时间曲线图')
subplot(1,2,2)
plot(y(:,1),y(:,2))
xlabel('(b)二维相位平面图')

比较ode23函数与ode45绘制常微分方程组的二维相位平面效果图
clear;clc
t0=0;
tfinal=15;
y0=[20 20]';
tfinal=tfinal*(1+eps);
[t,y]=ode23(@wang_3,[t0 tfinal],y0);
[T,Y]=ode45(@wang_3,[t0 tfinal],y0);
plot(y(:,1),y(:,2),'-',Y(:,1),Y(:,2),'-');
legend('ode23','ode45')
线性隐式常微分方程组的求解

clear;clc
tspan=[0,20]%定义变量求解区间
x0=[-1,1,1,0]';
M=eye(4);
M(4,4)=0;
options=odeset('Mass',M);%定义系数矩阵M(t,y)
[t,x]=ode15s(@wang_4,tspan,x0,options);%调用函数ode15s求解方程
subplot(121);
plot(t,x(:,1),'r-',t,x(:,2),'k:');
legend('x1','x2');
subplot(122);
plot(t,x(:,3),'r-',t,x(:,4),'k:');
legend('x3','x4');

完全隐式常微分方程组的求解

%求解完全隐式常微分方程Weissinger方程ty^2(y')^3-y^3(y')^2+t(t^2+1)y'-t^2y=0;
%当初始值等于sqrt(3/2)时,方程的解析式微y(t)=sqrt(t^2+0.5)
function dt=wang_5(t,y,dydt)
dt=t*y.^2*dydt.^3-y.^3*dydt.^2+t*(t^2+1)*dydt-t^2*y;

clear;clc
t0=1;
y0=sqrt(3/2);
yp0=0;
[y0,yp0]=decic(@wang_5,t0,y0,1,yp0,0);
[t,y]=ode15i(@wang_5,[1 10],y0,yp0);
ytrue=sqrt(t.^2+0.5);
plot(t,y,t,ytrue,'p');

常微分方程的符号求解

%利用dsolve函数求解式
clear;clc
h=dsolve('Dy=a*y*(1-y)-c*y','y(0)=b','t')
a=0.02;b=0.8;c=0.06;
h11=subs(h)
ezplot(h11,[0,130]);%绘制y(t)-t曲线
grid on

延迟微分方程组的数值解

延迟微分方程组的形式为:
y'(t)=f(t,y(t),y(t,a1),..,y(t,ak)),在matlab中提供了odde23函数来求解延迟微分方程。

%求下面延迟微分方程的解,y1'(t)=y1(t-1),y2'(t)=y1(t-1)+y2(t-0.3),y3'(t)=y2(t)
%首次建立延迟微分方程的M函数,
function dydt=wang_6(t,y,Z)
ylag1=Z(:,1);
ylag2=Z(:,2);
dydt=[ylag1(1)       
      ylag1(1)+ylag2(2)
      y(2)    ];

function S=init(t)%创建延迟微分方程组的初始的M函数
S=ones(3,1);

运行代码:
clear;clc
lags=[1.2,0.3];
sol=dde23(@wang_6,lags,@init,[0,5])
plot(sol.x,sol.y);
title('绘制延迟微分方程的效果图');
xlabel('time t');
ylabel('solution y');
legend('y_1','y_2','y_3',2)

常微分方程的边界问题

%求解如下微分方程的边界问题y''+|y|=0,边界条件为y(0)=0,y(4)=-2;
function dydx=twoode(x,y)
dydx=[y(2)
      -abs(y(1))];

function res=towbc(ya,yb)
res=[ya(1)
      yb(1)+2];

运行:

clear;clc
solinit=bvpinit(linspace(0,4,5),[1 0]);
sol=bvp4c(@twoode,@twobc,solinit);
x=linspace(0,4);
y=deval_r(sol,x);
plot(x,y(1,:));%微分方程边界条件下的解
figure;
xint=linspace(0,4,5);
sxint=deval_r(sol,xint);
plot(xint,sxint(1,:));%边界解得状态效果图

概率与数理统计分析

随机数的产生

clear;clc%生成连续均匀分布的随机数
a=0;b=30;
len=5;
y1=unifrnd(a,b,[1,len])


clear;clc%生成泊松分布的随机数
n=75;
lambda=1.75;
x=poissrnd(lambda,n,1)

clear;clc%生成超几何分布的随机数
M=800;K=45;n=25;
len=8;%产生len个随机数
y1=hygernd(M,K,n,[1 len])

clear;clc%生成正态随机分布的随机数
n=75;mu=1;
sigma=3;
x=normrnd(mu,sigma,n,1)

概率累加函数
clear;clc%绘制非中心T与T累积分布函数曲线
x=(-5:0.1:5)';
p1=nctcdf(x,10,1);
p=tcdf(x,10);
plot(x,p,'-',x,p1,'r:')
legend('非中心T累积分布','T累积分布');

概率密度函数

clear;clc%如果抛一次硬币,正面朝上为成功,那么在第一次成功前有4次失败的概率
P=geopdf(4,0.5)

clear;clc%如果有80张软盘,有15张为坏盘,抽出6张来,坏盘的张数是0-3张的概率分别是
p=hygepdf(0:3,80,15,6)

逆累积分布函数
   已知分布及分布中的一点值,求此点处的概率值要用到概率累积函数(CDF);当已知概率
值而需求对应该概率的分布点时,就要用到逆累积函数(INF)

clear;clc%如果10000张中有20张坏盘,则不合格,那么100张中最少有几张是坏盘说明这批产品不合格。
x=hygeinv(0.998,10000,20,100)

参数估计

clear;clc%求均匀分布置性度为95%的参数估计与置信区间。
r=unifrnd(10,12,100,2);
[ahat,bhat,aci,bci]=unifit(r)

clear;clc%求数据组服从正态分布,95%的置信区间及其参数估计值。
data=[1.2 3.1 2.9 2.78 3.9 4.2 1.7];
[mu,sigma,muci,sigmaci]=normfit(data)

区间估计

%求高斯-牛顿法德非线性最小二乘数据拟合
load reaction 
beta=nlinfit(reactants,rate,@hougen,beta)

load reaction %求非线性模型的参数估计的95%的置信区间
[beta,resid,J,Sigma]=nlinfit(reactants,rate,@hougen,beta);
ci=nlparci(beta,resid,'jacobian',J)

load reaction %求非线性模型的拟合并显示交互图形
nlintool(reactants,rate,@hougen,beta,0.01,xn,yn)


方差分析

单因素方差分析

clear;clc;
strength=[82 86 79 83 84 85 86 87 74 82 78 75 76 77 79 79 77 78 82 79];
alloy={'st','st','st','st','st','st','st',...
      'al1','al1','al1','al1','al1','al1','al1',...
      'al2','al2','al2','al2','al2','al2','al2'};
[p,table,stats]=anova1(strength,alloy)


双因素方差分析
clear;clc
X=[23 24 19 21 17 19 22 24 25 13 15 17 19 27 20
     29 21 24 14 18 19 21 24 20 16 17 21 18 25 23
     12 17 16 21 24 19 20 24 23 17 12 17 19 21 27];
[p,table,stats]=anova2(X',5)

多因素方差分析
clear;clc
y=[52.7 57.5 45.9 44.5 53.0 57.0 45.9 44.0]';
g1=[1 2 1 2 1 2 1 2];
g2={'hi';'hi';'lo';'lo';'hi';'hi';'lo';'lo'};
g3={'may';'may';'may';'may';'june';'june';'june';'june'};
[p,table,stats,terms]=anovan(y,{g1,g2,g3},'model','interaction')



插值



1拉格朗日插值
通过自定义Languagefun.m实现拉格朗日插值

function s=Languagefun(x,y,t)
syms p;
n=length(x);
s=0;
for(k=1:n)
      la=y(k);
      for(j=1:k-1)
            la=la*(p-x(j))/(x(k)-x(j));
      end;
      for(j=k+1:n)
            la=la*(p-x(j))/(x(k)-x(j));
      end
      s=s+la;
      simplify(s);
end
%如果三个参数,则给出插值点的插值结果,第三个参数可以为向量
if(nargin==2)
      s=subs(s,'p','x');
      s=collect(s);%展开多项式
      s=vpa(s,10);%把系数取到10位精度
else
      m=length(t);
      for i=1:m
            temp(i)=subs(s,'p',t(i));
      end
      s=temp;
end

测试代码:
clear;clc
x=0:0.5:3;
y=[0 0.4794 0.8415 0.9975 0.9093 0.5985 0.141];
f1=Languagefun(x,y) %求插值多项式
f2=Languagefun(x,y,1.5)%求插值结果

2.牛顿插值
牛顿构造了均差插值多项式
通过自定义函数Newtonjunfun.m实现牛顿均差插值


function s=Newtonjunfun(x,y,t)
syms p;
s=y(1);
dd=0;
dxs=1;
n=length(x);%读取x的长度
for i=1:n-1
      for j=i+1:n
            dd(j)=(y(j)-y(i))/(x(j)-x(i));
      end
      temp1(i)=dd(i+1);
      dxs=dxs*(p-x(i));
      s=s+temp1(i)*dxs;
      y=dd;
end
simplify(s);
if(nargin==2)
      s=subs(s,'p','x');
      s=collect(s);
      s=vpa(s,4);
else
      m=length(t);
      for i=1:m
            temp(i)=subs(s,'p',t(i));
      end
      s=temp;
end

测试代码如下:
clear;clc
x=1:6;
y=[0 0.6789 0.7963 1.0375 1.2936 1.3745 1.7954];
f1=Newtonjunfun(x,y)
f2=Newtonjunfun(x,y,1.7)

埃尔米特插值
有些实际问题,不仅要求插值多项式在插值点与函数值相同,而且还要求导数相同,这类问题就是埃尔米特插值问题
编写自定义函数Hermitefun.m

function f=Hermitefun(x,y,yd,x0)
syms t;
f=0.0;
if(length(x)==length(y))
      if(length(y)==length(yd))
            n=length(x);
      else 
            disp('y和y的导数的维数不相等');
            return;
      end
else
      disp('x和y的维数不相等');
      return;
end
for i=1:n
      h=1.0;
      a=0.0;
      for j=1:n
            if(j~=i)
                  h=h*(t-x(j))^2/((x(i)-x(j))^2);
                  a=a+1/(x(i)-x(j));
            end
      end
      f=f+h*((x(i)-t)*(2*a*y(i)-yd(i))+y(i));
      if(i==n)
            if(nargin==4)
                  f=subs(f,'t',x0);
            else
                  f=vpa(f,6);
            end
      end
end

运行:

clear;clc
x=[1 1.2 1.4 1.6 1.8 2.0 2.2];
y=[0 0.4794 0.8415 0.9975 0.9093 0.5985 0.1411];
yd=[0.5 0.4568 0.4236 0.3977 0.3784 0.1755 0.2378];
f1=Hermitefun(x,y,yd)
f2=Hermitefun(x,y,yd,1.56)

分段线性插值

   分段线性插值是最通俗的一种插值方法,直观上就是将各数据点用折线连接起来。
在matlab中提供了interp1函数进行分段线性插值。

clear;clc
x=0:0.2:pi;
y=sin(x);
pp=interp1(x,y,'cubic','pp');
xi=0:0.1:pi;
yi=ppval(pp,xi);
plot(x,y,'ko')
hold on;
plot(xi,yi,'r:')
hold off

样条插值

样条本来是绘图人员用于数据放样的工具,现在数学上所说的样条,实质上指分段多项式的光滑连接
clear;clc
x=[0.1 0.2 0.15 0 -0.2 0.3];
y=[0.95 0.84 0.86 1.06 1.50 0.72];
pp=spline(x,y)
pp.coefs

高维插值

clear;clc
x=0:4;
y=[2:4]';
z=[83 82 81 82 84;78 64 62 66 79;83 83 81 84 86];
subplot(1,2,1);mesh(x,y,z);
title('原始数据');
xi=0:0.1:4;
yi=[2:0.1:4]';
z=interp2(x,y,z,xi,yi,'spline');%二维样条插值
subplot(1,2,2);mesh(xi,yi,z);
title('二维样条插值');
set(gcf,'color','w');


拟合

   插值法师一种用简单函数近似代替较复杂函数的方法,它的近似标准时在插值点处的误差为0。
但有时,我们不要求具体某些点的误差为0,而是要求考虑整体的误差限制。这里需要引入拟合。

非线性最小二乘拟合
   在matlab中提供了lsqcurvefit函数及lsqnonlin函数实现非线性最小二乘拟合。

clear;clc
t=[0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 4.5 5 6 7 8 9 10 11 12 13 14 15 16];
h=[30 68 75 82 82 77 68 68 58 51 50 41 38 35 28 25 18 15 14 10 7 7 4];
h1=log(h);
f=inline('a(1)+a(2).*log(t)+a(3).*t','a','t');%输入内联函数
[x,r]=lsqcurvefit(f,[1,0.5,-0.5],t,h1)%求参数lna,b,c的拟合值
plot(t,h,'p');%绘制散点图
hold on;
ezplot('exp(4.834+0.4709*log(t)+(-0.2663)*t)',[0.2,16]);%

在matlab中提供了lsqlin函数实现线性最小二乘拟合。

clear;clc;
xk=0.8;
yk=[2 3.5 5.5 7.8 10.6 11.9 13.6 15.8 19.0];
plot(xk,yk,'p');%绘制离算数据点
h=lsline%最小二乘拟合
xd=get(h,'xData');%获取直线的数据
yd=get(h,'yData');
a=[yd(1)-yd(2)]/[xd(1)-xd(2)]%计算斜率
b=yd(1)-a*xd(1)%截距
grid on



数据分析

Kalman滤波
   在应用学科如卫星轨道、形态学等领域,一般把最小二乘方法与加权的最小二乘方法
或其他的一些改进、变形的估计方法统称为批处理方法。相对批处理方法的另外一种算法叫序惯处理方法。


%已知离散系统 xk+1Axk+ek,yk=xk(2)+vk
%第一式为系统方程,第二式为观测方程。假设x1的真值为x1=[   ],用Kalman滤波对仿真数据进行滤波处理
clear;clc
A=[0.490 0.298 0.412
      0.401 -0.391 0.391;
      -0.992 0.401 0.296];%状态转换矩阵
B=zeros(3,3);
G=eye(3,3);
C=[0 1 0];
D=[0 0 0];
H=zeros(1,3);
x(:,1)=[10.900 8.481 -4.300]';
g=[20.1 21.3 20.7]';%状态向量的初始估计值
for i=2:30
      w=randn(3,1);
      v=randn(1,1);
      x(:,i)=A*x(:,i-1)%真实数据
      x1(:,i)=x(:,i)+w;%系统误差
      Qn=eye(2,2);
      Rn=1;
      Nn=0;
      z0(:,i)=C*x1(:,i)+v;%观测误差
      %建立Kalman的系统参数
      sys=ss(A,[B,G],C,[D,H],-1);
      [kest,L,P,M,Z]=kalman(sys,Qn,Rn,Nn);
      g(:,i)=A*g(:,i-1)+L*(z0(:,i)-C*A*g(:,i-1));
end
subplot(2,2,1);plot(x(1,:));%作出真值线
hold on;
plot(g(1,:),'r:');
hold off
legend('真值曲线x1','误差曲线x1');
grid on;
subplot(2,2,2);plot(x(2,:));
hold on;
plot(g(2,:),'r:');
hold off
legend('真值曲线x2','误差曲线x3');
grid on;
subplot(2,1,2);plot(x(3,:));
hold on;
plot(g(3,:),'r:');
hold off
legend('真值曲线x3','误差曲线x3');
grid on;

启发渐进式特征投影
启发渐进式特征投影(Heuristic evolving latent projection,HELP)是为了解决渐进过程中的组分数、组分浓度变化等问题提出的


数据变换 


数据变换主要包括傅里叶变换、Laplace变换,Mellin变换及Z变换等。



傅里叶变换

%给定数学函数 x(t)= ...,取N=256,试对t从0-1s采样,用FFT作傅里叶变换,绘出相应的振幅-频率图
clear;clc
N=256;
T=1;
t=linspace(0,T,N);
x=10*sin(pi*8*t+pi/4)+4*cos(pi*30*t);
dt=t(2)-t(1);%采样周期
f=1/dt%采样频率
X=fft(x);
F=X(1:N/2+1);
f=f*(0:N/2)/N;
plot(f,abs(F),'-*');
xlabel('频率');ylabel('|F(x)|');
%求X的一维逆变换,并与原函数比较
ix=real(ifft(X));%求逆变换,结果只取实部
plot(t,x,t,ix,'*');%逆变换结果与原函数曲线
legend('逆变换效果图','原函数效果图');
norm(x-ix)

%利用fourier函数实现符号傅里叶变换
syms x;
f=exp(-x^2);
fourier(f)

小波变换

在解决分析与处理非平稳信号这类问题上傅里叶变换受到限制。为此发展出如窗口傅里叶、分数傅里叶变换以及小波变换等

matlab中提供wavemngr函数用来管理小波函数。

wavemngr('read',1)%列出所有小波


clear;clc
randn('seed',531316785)
s=2+kron(ones(1,8),[1 -1])+((1:16).^2)/32+0.2*randn(1,16);%离散信号
[ca1,cd1]=dwt(s,'haar');%利用haar小波进行一维小波变换
subplot(311);plot(s);
xlabel('(a)原始信号');
subplot(323);plot(ca1);
xlabel('(b)haar小波的低频系数');
subplot(324);plot(cd1);
xlabel('(c)haar小波的高频系数');
[Lo_D,Hi_D]=wfilters('haar','d');%生成低频、高频波向量
[ca1,cd1]=dwt(s,Lo_D,Hi_D);%小波变换
[ca2,cd2]=dwt(s,'db2');%利用db2小波进行变换
subplot(325);plot(ca2);
xlabel('(d)db2小波的低频系数');
subplot(326);plot(cd2);
xlabel('(e)db2小波的高频系数');


逆离散小波变换

在matlab中提供了idwt函数实现逆离散变换


clear;clc
randn('seed',531316785)
s=2+kron(ones(1,8),[1 -1])+((1:16).^2)/32+0.2*randn(1,16);%离散信号
[ca1,cd1]=dwt(s,'db2');
subplot(221);plot(ca1);
xlabel('(a)db2小波的低频系数');
subplot(222);plot(cd1);
xlabel('(b)db2小波的高频系数');
%利用基小波进行逆离散小波变换
ss=idwt(ca1,cd1,'db2');
err=norm(s-ss);%检查重建
subplot(212);plot([s;ss]');
title(['Error norm = ',num2str(err)])
xlabel('(c)原始信号与重建信号');




混沌现象

Henon映射的实现

clear;clc
b=0.5;%设置参数b的数值
N=400;%设置迭代次数
an=ones(1,N);
xn=zeros(1,N);
hold on;
box on;
x=0,y=0;%迭代初值
for a=0:0.001:1.4%对参数a离散取值
      for k=1:N
            xm=x;%xm为x的迭代之前的数值
            ym=y;%ym为y的迭代之前的数值
            x=ym+1-a*xm.*xm;%迭代计算
            y=b*xm;
      end
      xn(1)=x;%记录数值
      for n=2:N
            xm=x;
            ym=y;
            x=ym+1-a*xm.*xm;
            y=b*xm;
            xn(n)=x;
      end
      plot(an*a,xn,'k.','markersize',1);
end
xlim([0,a]);
title(['Henon映射,a=0~',num2str(a),',b=0.5']);
set(gcf,'color','w');



分形

在20世纪60年代,B.Mandelbrot对一个具有复杂几何性质但局部看起来仍然一样的几何对象提出了分形的概念


Koch曲线

美国生物学家Aristid Lindenmayer在研究植物形态的进行与构造是,于1968年提出了一种描述方法,现把这种方案称为L系统

%字符串绘图部分
function huitu(z,A,omega,delta)
hold on;
for k=1:length(omega)
      if strcmp(omega(k),'F');%如果遇到字符串F则画一线段
            plot([z,z+exp(i*A)],'k');
            z=z+exp(i*A);
      elseif strcmp(omega(k),'+');%更换角度
            A=A+delta;
      elseif strcmp(omega(k),'-')%更换角度
            A=A-delta;
      end
end
axis equal;
box on

你可能感兴趣的:(matlab)