第10章 数值计算

第10章 数值计算

10.1 线性方程组的解法

函数 功能
rank(A) 求A的秩,即A中线性无关的行数和列数
det(A) 求A的行列式
inv(A) 求A的逆矩阵。如果A是奇异矩阵或近似奇异矩阵,则会给出一个错误信息
pinv(A) 求A的伪逆。如果A是m*n矩阵,则伪逆的大小为n*m。对于非奇异矩阵A来说,有pinv(A)=inv(A)
trace(A) 求A的迹,即对角线元素之和
x=A\b % 求解系统Ax=b
X=A\B % 求解系统AX=B,其中B=(b1 b2 ... bp)

10.1.1 直接解法

>> A=[1 3 -3 -1; 3 -6 -3 4; 1 5 -9 -8];
>> B=[1 4 0]';
>> X=A\B % 一个特解近似值

X =

         0
   -0.0000
   -0.5333
    0.6000

10.1.2 逆矩阵法

x=A^-1*b
x=inv(A)*b
>> A=[1 2; 3 4]; b=[-1; -1];
>> x=inv(A)*b

x =

    1.0000
   -1.0000

>> x=A^-1*b

x =

    1.0000
   -1.0000
>> A=[1 2; 2 4]; b=[-1; -1];
>> x=A^-1*b % 警告:矩阵为奇异工作精度

x =

  -Inf
  -Inf

10.1.3 利用矩阵的LU分解求解

[L,U]=lu(A)
>> A=[4 2 -1; 3 -1 2; 11 3 1];
>> B=[2 10 8]';
>> D=det(A)

D =

  -10.0000

>> [L,U]=lu(A)

L =

    0.3636   -0.5000    1.0000
    0.2727    1.0000         0
    1.0000         0         0


U =

   11.0000    3.0000    1.0000
         0   -1.8182    1.7273
         0         0   -0.5000

>> X=U\(L\B)

X =

    4.0000
  -10.0000
   -6.0000

10.1.4 求线性方程组的其他解法

10.1.4.1 Jacobi迭代法

新建“函数 jacobi.m 文件”

function jacobi(A,B,P,delta,max1) % A-系数矩阵;B-常数项;P-初始值;delta-允许误差;maxl-最大迭代次数
N=length(B);
for k=1:max1
    for j=1:N
        X(j)=(B(j)-A(j,[1:j-1,j+1:N])*P([1:j-1,j+1:N]))/A(j,j);
    end
    err=abs(norm(X'-P));
    relerr=err/(norm(X)+eps);
    P=X';
    k; P';
    if (err<delta)||(relerr<delta)
        break
    end
end
X=X'
>> A=[3 1 -1; 4 8 1; 3 1 6];
>> B=[6 -20 15]';
>> x0=[1 2 1]'; % 设定初始值
>> jacobi(A,B,x0,1e-5,50);

X =

    3.9786
   -4.6500
    1.2857

10.1.4.2 Gauss-Seidel迭代法

新建“函数 gseid.m 文件”

function jacobi(A,B,P,delta,max1) % A-系数矩阵;B-常数项;P-初始值;delta-允许误差;maxl-最大迭代次数
N=length(B); % X=zeros(N,1)
for k=1:max1
    for j=1:N
        if j==1
            X(1)=(B(1)-A(1,2:N)*P(2:N))/A(1,1);
        elseif j==N
            X(N)=(B(N)-A(N,1:N-1)*(X(1:N-1))')/A(N,N);
        else
            X(j)=(B(j)-A(j,1:j-1)*X(1:j-1)-A(j,j+1:N)*P(j+1:N))/A(j,j);
        end
    end
    err=abs(norm(X'-P));
    relerr=err/(norm(X)+eps);
    P=X';
    k; P';
    if (err<delta)||(relerr<delta)
        break
    end
end
X=X'
>> A=[3 1 -1; 4 8 1; 3 1 6];
>> B=[6 -20 15]';
>> x0=[1 2 1]'; % 设定初始值
>> gseid(A,B,x0,1e-5,60);

X =

    3.9786
   -4.6500
    1.2857

10.2 插值

10.2.1 一维数据插值

vq=interp1(x,v,xq) % 使用线性插值返回一维函数在特定查询点的插入值
vq=interp1(x,v,xq,method) % 指定备选插值方法
vq=interp1(x,v,xq,method,extrapolation) % 指定外插策略计算落在x域范围外的点

vq=interp1(v,xq) % 返回插入的值,并假定一个样本点坐标默认集
vq=interp1(v,xq,method) % 指定备选插值方法中的任意一种,并使用默认样本点
vq=interp1(v,xq,method,extrapolation) % 指定外插策略,并使用默认样本点
pp=interp1(x,v,method,'pp') % 使用method算法返回分段多项式形式的v(x)
>> x=linspace(0,2*pi,40);
>> y=cos(x.^2);
>> val=interp1(x,y,[0 pi/2 3]) % 用interp1计算中间点的函数值

val =

    1.0000   -0.7677   -0.8200

>> cor=cos([0 pi/2 3].^2) % 与用cos计算得到的正确结果进行比较

cor =

    1.0000   -0.7812   -0.9111

10.2.2 二维数据插值

Vq=interp2(X,Y,V,Xq,Yq) % 使用线性插值返回双变量函数在特定查询点的插入值

Vq=interp2(V,Xq,Yq) % 假定一个默认的样本点网格

Vg=interp2(V) % 将每个维度上样本值之间的间隔分割一次形成优化网格,并返回插入值
Vq=interp2(V,k) % 将每个维度上样本值之间的间隔反复分割k次形成优化网格,并在这些网格上返回插入值,即在样本值之间生成2^k-1个插值点
Vq=interp2(___,method) % 指定备选插值方法
Vq=interp2(___,method,extrapval) % 指定标量值extrapval
>> [X,Y]=meshgrid(-3:3);
>> V=peaks(7);
>> subplot(1,2,1); surf(X,Y,V)
>> title('初始数据');
>> [Xq,Yq]=meshgrid(-3:0.25:3); % 创建间距为0.25的查询网格
>> Vq=interp2(X,Y,V,Xq,Yq,'cubic'); % 对查询点插值,并指定三次插值
>> subplot(1,2,2); surf(Xq,Yq,Vq) % 绘制结果
>> title('cubic插值');

10.2.2 二维插值效果示例

10.2.3 三维及多维数据插值

Vq=interp3(X,Y,Z,V,Xq,Yq,Zq)
Vq=interp3(V,Xq,Yq,Zq)
Vg=interp3(V)
Vq=interp3(V,k)
Vq=interp3(___,method)
Vq=interp3(___,method,extrapval)

10.2.4 三次样条数据插值

s=spline(x,y,xq) % 返回与xg中的查询点对应的三次样条插值s的向量
pp=spline(x,y) % 返回一个分段多项式结构体,以用于ppval和样条工具unmkpp
>> x=-3:3;
>> y=[-1 -1 -1 0 1 1 1];
>> xq1=-3:.01:3;
>> p=pchip(x,y,xq1);
>> s=spline(x,y,xq1);
>> m=makima(x,y,xq1);
>> plot(x,y,'o',xq1,p,'-',xq1,s,'-.',xq1,m,'--')
>> legend('Points','pchip','spline','makima','Location','SouthEast')

10.2.4 插值结果比较

10.2.5 快速傅里叶变换插值

y=interpft(X,n) % 在X中内插函数值的傅里叶变换以生成n个等间距的点
y=interpft(X,n,dim) % 沿维度dim运算

10.2.6 对二维或三维散点数据插值

vq=griddata(x,y,v,xq,yq) % 拟合v=f(x,y)形式的曲面与向量(x,y,v)中的散点数据,即在(xq,yq)指定的点对曲面进行插值并返回插入的值vq
vg=griddata(x,y,z,v,xq,yq,zq) % 拟合v=f(x,y,z)形式的超曲面
vq=griddata(___,method) % 指定计算vq所用的插值方法
[Xq,Yq,vq]=griddata(x,y,v,xq,yq)
[Xq,Yq,vq]=griddata(x,y,v,xq,yq,method) % 额外返回Xq、Yq,包含查询点的网格坐标
>> x=rand(20,1); % 生成有20个元素的向量,元素值随机分布在0~1内
>> y=rand(20,1); % 生成有20个元素的向量,元素值随机分布在0~1内
>> z=rand(20,1); % 生成有20个元素的向量,元素值随机分布在0~1内
>> stps=0:0.02:1; % 向量A的值在[0,1]区间
>> [X,Y]=meshgrid(stps); % 生成一个[0,1]*[0,1]坐标网络
>> Z1=griddata(x,y,z,X,Y); % 线性插值
>> Z2=griddata(x,y,z,X,Y,'cubic'); % 三次插值
>> Z3=griddata(x,y,z,X,Y,'nearest'); % 最邻近插值
>> Z4=griddata(x,y,z,X,Y,'v4'); % MATLAB中的插值方法
>> subplot(2,2,1); mesh(X,Y,Z1); % 第一个子图中画曲面网格
>> hold on % 保持当前图形
>> plot3(x,y,z,'o'); % 画出数据点
>> hold off % 释放图形
>> subplot(2,2,2); mesh(X,Y,Z2); % 第二个子图中画曲面网格
>> hold on % 保持当前图形
>> plot3(x,y,z,'o'); % 画出数据点
>> hold off % 释放图形
>> subplot(2,2,3); mesh(X,Y,Z3); % 第三个子图中画曲面网格
>> hold on % 保持当前图形
>> plot3(x,y,z,'o'); % 画出数据点
>> hold off % 释放图形
>> subplot(2,2,4); mesh(X,Y,Z4); % 第四个子图中画曲面网格
>> hold on % 保持当前图形
>> plot3(x,y,z,'o'); % 画出数据点
>> hold off % 释放图形

10.2.6 用griddata命令对20个随机点进行插值

10.3 曲线拟合

p=polyfit(x,y,n) % 返回多项式的系数,是一个长度为n+1的向量p,用最小二乘法对输入的数据x、y用n阶多项式进行逼近
[p,s]=polyfit(x,y,n) % 额外返回误差分析报告,并保存在结构体变量s中
>> x=[1 2 3 4 5];
>> y=[1.2 1.8 2.4 3.9 4.5];
>> [p,s]=polyfit(x,y,1)

p =

    0.8700    0.1500


s = 

  包含以下字段的 struct:

           R: [2×2 double]
          df: 3
       normr: 0.4930
    rsquared: 0.9689

>> y1=polyval(p,x);
>> plot(x,y1); hold on;
>> plot(x,y,'b*');

10.3 线性拟合

>> clear,clf
>> x=-2:0.2:2;
>> y=1./(1+2*x.^2);
>> p4=polyfit(x,y,4);
>> p10=polyfit(x,y,10); % 用向量x和y中元素拟合不同次数的多项式
>> xcurve=-2:0.02:2;
>> p4curve=polyval(p4,xcurve); % 计算在这些x点处的多项值
>> p10curve=polyval(p10,xcurve);
>> plot(xcurve,p4curve,'r--',xcurve,p10curve,'b-.',x,y,'ko');
>> legend('L4(x)','L10(x)','精确值');

10.3 多项式拟合

>> clear,clf
>> x=0:0.2:2;
>> y=sin(x);
>> p=polyfit(x,y,8); % 用x和y在[0,2]区间上拟合
>> x1=0:0.2:6;
>> y1=polyval(p,x1);
>> y2=sin(x1);
>> plot(x1,y1,'kx',x1,y2,'k-') % 在[0,6]区间上画图
>> legend('polyfit','sin(x)');

10.3 多项式拟合的区间问题

10.4 数值积分

10.4.1 梯形法数值积分

T=trapz(Y) % 用等距梯形法近似计算Y的积分
T=trapz(X,Y) % 用梯形法计算Y在X点上的积分
T=trapz(___,dim) % 沿着dim指定的方向对Y进行积分,若参量中包含X,则应有length(X)=size(Y,dim)
>> X=-1:.1:1;
>> Y=1./(1+2*X.^2);
>> T=trapz(X,Y)

T =

    1.3503
>> x=-3:.1:3;
>> y=-5:.1:5;
>> [X,Y]=meshgrid(x,y); % 创建由域值构成的网络
>> F=X.^2+Y.^2; % 建立网络上的函数
>> T=trapz(y,trapz(x,F,2)) % 对数值数据的数组执行二重积分运算

T =

  680.2000

10.4.2 自适应辛普森积分法

q=quad(fun,a,b) % 近似地从a到b计算函数fun的数值积分,默认误差为1.0e-6
q=quad(fun,a,b,tol) % 用指定的绝对误差tol代替默认误差
q=quad(fun,a,b,tol,trace) % 打开诊断信息的显示
>> fun=inline('x.^2./(x.^3-x.^2+3)');
>> Q1=quad(fun,0,2)

Q1 =

    0.6275

>> Q2=quad(fun,0,2)

Q2 =

    0.6275
% 梯形法
>> m=pi/20;
>> x=0:m:pi/2;
>> y=cos(x);
>> z=trapz(y)*m

z =

    0.9979

% 自适应辛普森积分法
>> z=quad('cos',0,pi/2)

z =

    1.0000

10.4.3 全局自适应积分法

q=integral(fun,xmin,xmax) % 在xmin~xmax间以数值形式对函数fun求积分
g=integral(fun,xmin,xmax,Name,Value) % 指定一个或多个Name,Value参数对
g=integral2(fun,xmin,xmax,ymin,ymax)
q=integral2(fun,xmin,xmax,ymin,ymax,Name,Value)
q=integral3(fun,xmin,xmax,ymin,ymax,zmin,zmax)
q=integral3(fun,xmin,xmax,ymin,ymax,zmin,zmax,Name,Value)
>> fun=@(x) exp(-x.^2).*log(x).^2; % 创建匿名函数
>> q=integral(fun,0,Inf) % 求积分

q =

    1.9475
>> fun=@(x,y,z) x.*cos(y)+x.^2.*cos(z); % 创建匿名函数
>> xmin=-1; xmax=1;
>> ymin=@(x) -sqrt(1-x.^2); ymax=@(x) sqrt(1-x.^2);
>> zmin=@(x,y) -sqrt(1-x.^2-y.^2); zmax=@(x,y) sqrt(1-x.^2-y.^2);
>> q=integral3(fun,xmin,xmax,ymin,ymax,zmin,zmax)

q =

    0.7796

10.5 常微分方程(组)的数值求解

函数 求解问题类型 方法
ode23 求解非刚性微分方程—低阶方法 显式Runge-Kutta(2,3)法
ode45 求解非刚性微分方程—中阶方法 基于显式Runge-Kutta(4,5)的Dormand-Prince法
ode113 求解非刚性微分方程—变阶方法 Adams-Bashforth-Moulton PECE求解
ode78 求解非刚性微分方程—高阶方法 7阶连续外推Runge-Kutta 8(7)法
ode89 求解非刚性微分方程—高阶方法 8阶连续外推Runge-Kutta 9(8)法
ode15s 求解刚性微分方程和DAE—变阶方法 基于1到5阶数值微分公式(NDF)的VSVO求解器
ode23s 求解刚性微分方程—低阶方法 改进的二阶Rosenbrock法
ode23t 求解中等刚性的ODE和DAE—梯形法 使用“自由”插值的梯形法
ode23tb 求解刚性微分方程—梯形法+后向差分公式 TR-BDF2,采用隐式Runge-Kutta公式
ode15i 求解全隐式微分方程—变阶方法 基于1到5阶后向差分公式(BDF)的VSVO求解器
[X,Y]=odeN('odex',[t0,tf],y0,tol,trace)

新建“函数 odex1.m 文件”

function dy=odex1(x,y)
    dy=[y(2);y(3);y(2)*(1+y(3)^2)-y(1)];
end
>> [X,Y]=ode45('odex1',[0 30],[1;-1;0]); % 调用ode45命令求解
警告: 在 t=9.144275e-01 处失败。在时间 t 处,步长必须降至所允许的最小值(1.776357e-15)以下,才能达到积分容差要求。 
> 位置:ode45 (第 346 行)

>> plot(X,Y(:,1),'r-',X,Y(:,2),'k:',X,Y(:,3),'b--') % 绘图并观察变化趋势
>> xlabel('timeX');
>> ylabel('solutionY');
>> legend('Y1','Y2','Y3');

>> [X,Y]=ode45('odex1',[0 0.9],[1;-1;0]);
>> plot(X,Y(:,1),'r-',X,Y(:,2),'k:',X,Y(:,3),'b--')
>> xlabel('timeX');
>> ylabel('solutionY');
>> legend('Y1','Y2','Y3');

10.5 求解区间0-30

10.5 求解区间0-0.9

新建“函数 rigid.m 文件”

function dy=rigid(t,y)
    dy=zeros(3,1); % 列向量
    dy(1)=-y(2)*y(3);
    dy(2)=y(1)*y(3);
    dy(3)=2*y(1)*y(2);
end
>> options=odeset('RelTol',1e-4,'AbsTol',[1e-4 1e-4 1e-5]);
>> [t,Y]=ode45(@rigid,[0 12],[1 0 1],options); % 调用ode45命令求解
>> plot(t,Y(:,1),'-',t,Y(:,2),'-.',t,Y(:,3),'.') % 绘图并观察变化趋势

10.5 微分方程组初值问题2

新建“函数 vdp.m 文件”

function dy=vdp(t,y)
    dy=zeros(2,1); % 列向量
    dy(1)=y(2);
    dy(2)=900*(1-y(1)^2)*y(2)-y(1);
end
>> [T,Y]=ode15s(@vdp,[0 4000],[2 0]); % 调用ode15s命令求解
>> plot(T,Y(:,1),'-o') % 绘图并观察变化趋势

10.5 微分方程组初值问题3

10.6 数据分析

函数名 功能描述 基本调用格式
max 求最大值 C=max(A) 如果A是向量,则返回向量中的最大值;如果A是矩阵,则返回一个包含各列最大值的行向量
C=max(A,B) 返回矩阵A和B中较大的元素,矩阵A、B必须具有相同的大小
C=max(A,[],dim) 返回dim维上的最大值[C,1]=max(...),多返回最大值的下标
min 求最小值 与求最大值函数max的调用格式一致
mean 求平均值 M=mean(A) 如果A是向量,则返回向量A的平均值;如果A是矩阵,则返回含有各列平均值的行向量
M=mean(A,dim) 返回dim维上的平均值
median 求中间值 与求平均值函数mean的调用格式一致
std 求标准方差 s=std(A) 如果A是向量,则返回向量的标准方差;如果A是矩阵,则返回含有各列标准方差的行向量
s=std(A,flag) 用flag选择标准方差的定义式
s=std(A,flag,dim) 返回dim维上的标准方差
var 方差(标准方差的平方) var(A) 如果A是向量,则返回向量的方差;如果A是矩阵,则返回含有各列方差的行向量
var(A,1) 返回第二种定义的方差
var(A,w) 利用w作为权重计算方差
var(A,w,dim) 返回dim维上的方差
sort 数据排序 B=sort(A) 如果A是向量,则升序排列向量;如果A是矩阵,则升序排列各列
B=sort(A,dim) 升序排列矩阵A的dim维
B=sort(...,mode) 用mode选择排序方式:ascend为升序,descend为降序
[B,IX]=sort(...) 多返回数据B在原来矩阵中的下标IX
sortrows 对矩阵的行排序 B=sortrows(A) 升序排序矩阵A的行
B=sortrows(A,column) 以column列数据作为标准,升序排序矩阵A的行
[B,index]=sortrows(A) 多返回数据B在原来矩阵A中的下标index
sum 求元素之和 B=sum(A) 如果A是向量,则返回向量A的各元素之和;如果A是矩阵,则返回含有各列元素之和的行向量
B=sum(A,dim) 求dim维上的矩阵元素之和
B=sum(A,'double') 返回数据类型指定为双精度浮点数
B=sum(A,'native') 返回数据类型指定为与矩阵A的数据类型相同
prod 求元素的连乘积 B=prod(A) 如果A是向量,则返回向量A的各元素的连乘积;如果A是矩阵,则返回含有各列元素连乘积的行向量
B=prod(A,'all') 返回A的所有元素的乘积
B=prod(A,dim) 返回dim维上的矩阵元素连乘积
hist 画直方图 n=hist(Y) 在10个等间距的区间内统计矩阵Y属于该区间的元素个数
n=hist(Y,x) 在x指定的区间内统计矩阵Y属于该区间的元素个数
n=hist(Y,nbins) 用nbins个等间距的区间统计矩阵Y属于该区间的元素个数
hist(...) 直接画出直方图
histc 直方图统计 n=histc(x,edges) 计算在edges区间内向量x属于该区间的元素个数
n=histc(x,edges,dim) 在dim维上统计x出现的次数
trapz 梯形数值积分(等间距) Z=trapz(Y) 返回Y的梯形数值积分
Z=trapz(X,Y) 计算以X为自变量时Y的梯形数值积分
Z=trapz(...,dim) 在dim维上计算梯形数值积分
cumsum 矩阵的累加 B=cumsum(A) 如果A是向量,则计算向量A的累加和;如果A是矩阵,则计算矩阵A在列方向上的累加和
B=cumsum(A,dim) 在dim维上计算矩阵A的累加和
cumprod 矩阵的累积 与函数cumsum的调用格式相同
cumtrapz 梯形积分累积 与函数trapz的调用格式相同

10.6.1 最大值、最小值、平均值、中间值、元素求和

>> x=1:20;
>> y=randn(1,20); % 创建20个随机数y
>> plot(x,y); hold on;
>> [y_max,I_max]=max(y);
>> plot(x(I_max),y_max,'*');
>> [y_min,I_min]=min(y);
>> plot(x(I_min),y_min,'o');
>> y_mean=mean(y);
>> plot(x,y_mean*ones(1,length(x)),'--');
>> legend('数据','最大值','最小值','平均值');

10.5 最大值、最小值、平均值

10.6.2 标准差和方差

>> x1=rand(1,200);
>> x2=8*x1;
>> std_x1=std(x1);
>> var_x1=var(x1);
>> std_x2=std(x2);
>> var_x2=var(x2);
>> disp(['x2的标准方差与x1的标准方差之比=',num2str(std_x2/std_x1)]);
x2的标准方差与x1的标准方差之比=8
>> disp(['x2的方差与x1的方差之比=',num2str(var_x2/var_x1)]);
x2的方差与x1的方差之比=64

10.6.3 元素排序

>> a=[0 -13i 1 i -i -3i 3 -3];
>> b=sort(a)

b =

   0.0000 + 0.0000i   0.0000 - 1.0000i   1.0000 + 0.0000i   0.0000 + 1.0000i   0.0000 - 3.0000i   3.0000 + 0.0000i  -3.0000 + 0.0000i   0.0000 -13.0000i

10.7 多项式函数

10.7.1 多项式表示法

>> poly2sym([1 -2 0 8 0 6 -8])
 
ans =
 
x^6 - 2*x^5 + 8*x^3 + 6*x - 8

10.7.2 多项式求值

y=polyval(p,x)

Y=polyvalm(p,X) % 把矩阵X代入多项式p中进行计算,矩阵X必须是方阵
>> p1=[1 3 6]; % 多项式x^2+3x+6的系数
>> A=[10 -1];
>> A1=[1 0; 0 1];
>> p1_A=polyval(p1,A) % 求多项式的值

p1_A =

   136     4

>> p1_Am=polyvalm(p1,A1) % 求矩阵多项式的值

p1_Am =

    10     0
     0    10
函数名 功能描述 函数名 功能描述 函数名 功能描述
poly 求多项式的系数 roots 求多项式的根 deconv 去卷积或多项式除法
polyeig 求多项式特征值问题 polyval 求多项式的值 polyint 求多项式的积分
polyfit 多项式曲线拟合 polyvalm 求矩阵多项式的值 polyder 求多项式的一阶导数(微分)
residue 部分分式展开(分解) conv 卷积或多项式乘法 ... ...
posted @ 2026-01-12 10:43  Zhuye_inking  阅读(37)  评论(0)    收藏  举报