【计算方法】部分习题的matlab求解

前言

要考试了整理一下。(没错,由于疫情原因,我们计算方法考试线下进行,可以用matlab。)

第一章、拉格朗日插值

在这里插入图片描述

clc,clear;
syms x;
% 拉格朗日插值点  x和y
x0 = [3,5,6];
y0 = [1.0986,1.6094,1.7918];
xq = 4;  %所求点的横坐标
len = length(x0);
%lx为核函数列表
lx = [];
for i = 1:len
	tmp = x0(:);
	tmp(i) = [];
	lxi = prod(x-tmp)/prod(x0(i)-tmp);
	lx = [lx lxi];
end
% y(x)为插值函数
y(x) = sum(lx.*y0);
disp("y = ");
disp(vpa(expand(y),4));
% 保留小数,求出结果
res = vpa(y(xq),4);
disp("y(xq)结果为")
disp(res);

%求误差的情况通常有一个已知的f(x)
f(x) = log(x);
% fx的n+1阶导数绝对值
fe(x) = abs(diff(f,len));

%尝试x,求最大值
x1 = x0(1):0.01:x0(len);
%求出n+1阶导数绝对值的最大值
fe0 = max(fe(x1));
%求出R(x)
R(x) = abs(fe0/factorial(len)*prod(x-x0));
disp("R(x)=")
disp(vpa(max(R(x1)),4))
%画出R(x)图像
% plot(x1,R(x1));

第二章、牛顿插值

在这里插入图片描述

clc,clear;
syms x;
%牛顿插值已知点
x0 = [3,4,5,6];
y0 = [1.0986,1.3863,1.6094,1.7918];
%所求值
xq = 4.5;
%求出x0的长度
len = length(x0);
%构建差商表table
table = zeros(len,len);
table(:,1) = y0';
for i=2:len
	tmp1 = table(i-1:len-1,i-1);
	tmp2 = table(i:len,i-1);
	xtmp = (x0(1:len-i+1)-x0(i:len))';
	table(i:len,i) = (tmp1-tmp2)./xtmp;
end
% 打印差商表
disp("差商表为")
disp(table)
xishu = diag(table);
N(x) = x;
for i = 1:len
	if (i==1)
		N(x) = N(x) + xishu(i);
	else
		N(x) = N(x) + xishu(i)*prod(x-x0(1:i-1));
	end
end
N(x) = N(x) - x;
%化简输出结果
vpa(simplify(N(x)),4)
vpa(N(xq),4)

%误差求法同拉格朗日
f(x) = log(x);
% fx的n+1阶导数
fe(x) = abs(diff(f,len));

%尝试x,求最大值
x1 = x0(1):0.01:x0(len);
%求出n+1阶导数绝对值的最大值
fe0 = max(fe(x1));
%求出R(x)
R(x) = abs(fe0/factorial(len)*prod(x-x0));
disp("xq loss")
disp(vpa(R(xq),4))
disp("y loss")
disp(vpa(max(R(x1)),4))
%画出R(x)图像
% plot(x1,R(x1));

第三章、线性插值&三次样条插值

线性插值

在这里插入图片描述

clc,clear;
syms x;
%分段线性插值
f(x) = 1/(1+x^2);
a = 2;
b = 5;
wucha = 0.01;

%求处达到精度的划分
% m为区间个数
% h为区间长度
ddf(x) = abs(diff(f,2));
x1 = a:0.01:b;
m2 = max(ddf(x1));
h = (8*wucha/m2)^0.5;
m = ceil((b-a)/h);
h = (b-a)/m;

%求出各个区段表达式
x0 = a:h:b;
y0 = f(x0);
y = [];
for i=1:m
	y = [y vpa((x-x0(i+1))/(x0(i)-x0(i+1))*y0(i) + (x-x0(i))/(x0(i+1)-x0(i))*y0(i+1),4)];
end
vpa(y,4)

三次样条插值

在这里插入图片描述

clc,clear;
%三次样条插值
%求达到误差精度的最大区间数量

syms x;
f(x) = log(x);
a = 3;
b = 6;
wucha = 0.0001;

df(x) = abs(diff(f,4));
m = max(df(a:0.01:b));

h = (wucha*384/5/m)^(0.25);
n = ceil((b-a)/h);
h = (b-a)/n;

n
h

第四章、最佳一致逼近

在这里插入图片描述

clc,clear;
%最佳一致逼近
syms x;
a = -1;
b = 1;
f(x) = exp(x);
cishu = 3; %逼近次数
k = 1:cishu+1;
x0 = (b-a)/2*cos((2.*k-1).*pi./(2.*length(k)))+(a+b)/2;
y0 = f(x0);

len = length(x0);
%lx为核函数列表
lx = [];
for i = 1:len
	tmp = x0(:);
	tmp(i) = [];
	lxi = prod(x-tmp)/prod(x0(i)-tmp);
	lx = [lx lxi];
end
% y(x)为插值函数
y(x) = sum(lx.*y0);
% 保留小数,求出结果
res = vpa(expand(y),4);
disp(res);

%计算误差
df(x) = abs(diff(f,cishu+1));
mdf = max(df(a:0.01:b));
wucha = 1/2^(cishu)/factorial(cishu+1)*mdf;
vpa(wucha,4)

第五章、最佳平方逼近和曲线拟合的最小二乘法

最佳平方逼近

在这里插入图片描述

clc,clear;
%最佳平方逼近
syms x;
%roux
rou(x) = x/x;
fai = [1 x x^2];
a = 0;
b = 1;
f(x) = exp(x);

[faix,faiy] = meshgrid(fai,fai);
%求内积
left = int(rou*faix.*faiy,a,b)
right = int(f.*fai,a,b)'
%矩阵求逆求出系数
xishu = inv(left)*right;

% vpa(xishu,4)
S(x) = sum(fai'.*xishu);
disp("polynomial is")
vpa(S(x),4)
%误差处理
%平方误差
pingfang = abs(int(f^2*rou,a,b)-int(S*f*rou,a,b));
disp("sqrt error")
vpa(pingfang,4)
%最大值误差
disp("max error")
zuidazhi(x) = abs(f-S);
vpa(max(zuidazhi(a:0.01:b)),4)

曲线拟合的最小二乘法

在这里插入图片描述

clc,clear;
%曲线拟合
syms x;
x0 = [-2 -1 0 1 2];
y0 = [-8.2 -1.2 0 1.25 8.05];
cishu = 2;

len = length(x0);
left = zeros(cishu+1,cishu+1);
xs = [];
for i = 1:cishu+1
	xs = [xs;x^(i-1)];
end

for i=1:cishu+1
	for j=1:cishu+1
		f(x) = x^(i+j-2);
		left(i,j) = sum(f(x0));
	end
end

right = zeros(cishu+1,1);
for i = 1:cishu+1
	right(i) = sum(y0.*x0.^(i-1));
end
%求出系数
a = inv(left)*right;
%表达式
f(x) = sum(a.*xs);
disp("polynomial is")
vpa(f(x),4)
%求出误差
e = sum((f(x0)-y0).^2)^0.5;
disp("error is")
vpa(e,4)

机械求积方法

在这里插入图片描述

clc,clear;
syms x;
% 构造积分精度
jingdu = 3;
% 原先的被积函数
f(x) = exp(x);
% 积分区间
a = -1;
b = 2;

func = [];
x0 = linspace(a,b,jingdu+1);
for i=1:jingdu+1
	func = [func x^(i-1)];
end

left = zeros(jingdu+1);
for i=1:jingdu+1
	f_i(x) = func(i);
	left(i,:) = f_i(x0);
end

right = int(func',a,b);

A = inv(left)*right;
disp("A=")
vpa(A,4)

%求得的积分结果
intres = sum(A'.*f(x0));
disp("求得结果为")
vpa(intres,4)
%求误差
%真实误差
acc = int(f,a,b);
acce = abs(acc - intres);
disp("真实误差为");
vpa(acce,4)
%误差估计
df(x) = diff(f,jingdu+1);
maxf = max(abs(df(a:0.01:b)));
e = maxf/factorial(jingdu+1)*int(abs(prod(x-x0)),a,b);
disp("误差估计为");
vpa(e,4)

复合求积公式

在这里插入图片描述

clc,clear;
%课堂作业1
%复化求积公式
syms x;
a = 0;
b = 4;
n= 4;
h=(b-a)/n;
f(x)=exp(x);
%求精确解
disp("精确解为")
acc=vpa(int(f,a,b));
disp(acc)
%复化梯形公式
i=a+h:h:b-h;
%复化梯形公式算公式如下
Tn=h/2*(f(a)+2*sum(f(i))+f(b));
disp("复化梯形公式的计算结果为")
disp(vpa(Tn,4))
%复化辛普森公式
i=a+h:h:b-h;
j=a+h/2:h:b-h/2;
%复化辛普森公式计算公式如下
Sn=h/6*(f(a)+4*sum(f(j))+2*sum(f(i))+f(b));
disp("复化辛普生公式的结算结果为")
disp(vpa(Sn,4))
%复化梯形公式的误差
% disp("复化梯形公式的实际误差为")
% acce1=abs(acc-vpa(Tn));
% disp(acce1)
disp("复化梯形公式的误差")
df(x) = diff(f,2);
Rt = abs((b-a)/12*h^2)*max(abs(df(a:0.01:b)));
disp(vpa(Rt,4))
%复化辛普生公式的误差
% disp("复化辛普生公式的实际误差为")
% acce2=abs(acc-vpa(Sn));
% disp(acce2)
disp("复化辛普生公式的误差为")
df(x) = diff(f,4);
Rs = abs((b-a)/2880*h^4)*max(abs(df(a:0.01:b)));
disp(vpa(Rs,4))

线性方程组的直接解法

在这里插入图片描述

clc,clear;
syms x;
%第一问不写了自个拿着计算器解去吧!
%判读是否收敛:cond(A)
A = [8 -2 1
	 3 1 1.001
	 1 1 1];
% Ainv = inv(A);
%直接求出结果
cond(A,inf)
%经过一定过程
Ainv = inv(A);
A = abs(A);
Ainv =abs(Ainv);
max(sum(A,2))*max(sum(Ainv,2))
%当输出结果远远大于1时为病态的。

解线性方程组的迭代法

雅克比迭代法

在这里插入图片描述

clc,clear;
% 雅克比迭代
% 求解方法AX = B
syms x;
A = [4 1 2
	 1 4 1
	 2 -1 4];
B = [7;6;5];
len = length(B);
% 初值为0
X = zeros(len,1);
% 迭代次数
n = 3;
diagA = diag(A);
left = A;
left(logical(eye(size(left)))) = 0;
left = -left./diagA;
left0 = B./diagA;
for i = 1:n
	fprintf("第%d次迭代",i);
	%若不加分号显示迭代过程
	X = left * X + left0
end
% X
%B其实就是left
left

高斯-塞德尔迭代

在这里插入图片描述

clc,clear;
% 高斯赛德尔迭代
% 求解方法AX = B
syms x;
A = [4 1 2
	 1 4 1
	 2 -1 4];
B = [7;6;5];
len = length(B);
% 初值为0
X = zeros(len,1);
% 迭代次数
n = 3;

D = diag(diag(A));
L = -tril(A,-1);
U = -triu(A,1);
G = inv(D-L)*U;
d = inv(D-L)*B;
for i = 1:n
	fprintf("第%d次迭代",i);
	X = G * X + d
end
G

解线性方程组的迭代法的收敛性

雅克比迭代法

在这里插入图片描述

clc,clear;
%解线性方程组的收敛性
% 雅克比迭代(和老师答案有点不太一致)
% 求解方法AX = B
syms x;
A = [3 0 1
	 1 3 2
	 0 1 3];
B = [4;3;3];
jingdu = 0.001;

len = length(B);
diagA = diag(A);
left = A;
left(logical(eye(size(left)))) = 0;
left = -left./diagA;
left0 = B./diagA;
if(max(abs(eig(left)))>=1)
	disp("发散无法求出迭代次数");
end
X0 = zeros(len,1);
X1 = left * X0 + left0;

%left的范数
%我们主要看两个范数
%1.无穷范数
%2.F范数
condB = max(sum(abs(left),2)); %X0X1的无穷范数
condX = max(abs(X1 - X0)); %无穷范数
disp("无穷范数求得迭代次数为")
k = ceil(log(jingdu/condX*(1-condB))/log(condB))
condB = sum(sum(left.^2))^0.5; %X0X1的F范数
condX = sum((X1-X0).^2)^0.5; %F范数
disp("F范数求得迭代次数为")
k =  ceil(log(jingdu/condX*(1-condB))/log(condB))

高斯-塞德尔迭代

在这里插入图片描述

clc,clear;
% 解线性方程组的收敛性
% 高斯赛德尔迭代
% 求解方法AX = B
% 和老师的结果差1
syms x;
A = [3 0 1
	 1 3 2
	 0 1 3];
B = [4;3;3];
jingdu = 0.001;
len = length(B);
D = diag(diag(A));
L = -tril(A,-1);
U = -triu(A,1);
G = inv(D-L)*U;
d = inv(D-L)*B;

if(max(abs(eig(G)))>=1)
	disp("发散无法求出迭代次数");
end
X0 = zeros(len,1);
X1 = G * X0 + d;
%G的范数
%我们主要看两个范数
%1.无穷范数
%2.F范数
condB = max(sum(abs(G),2)); %X0X1的无穷范数
condX = max(abs(X1 - X0)); %无穷范数
disp("无穷范数求得迭代次数为")
k = ceil(log(jingdu/condX*(1-condB))/log(condB))
condB = sum(sum(G.^2))^0.5; %X0X1的F范数
condX = sum((X1-X0).^2)^0.5; %F范数
disp("F范数求得迭代次数为")
k =  ceil(log(jingdu/condX*(1-condB))/log(condB))

非线性方程的数值解法

二分法

在这里插入图片描述

clc,clear;
%非线性方程的数值解法
%二分法
%有可能还需要求在这个区间上有几个解,验证解的唯一性
syms x;
% 方程为f(x) = 0
f(x) = x^3 - x^2 + x - 1;
%迭代区间
a = 0;
b = 2;
%n为迭代次数
n = 5;
x1 = a;
x2 = b;
for i=1:n
	if (f((x1+x2)/2)*f(x1)>0)
		x1 = (x1+x2)/2;
	elseif(f((x1+x2)/2)*f(x2)>0)
		x2 = (x1+x2)/2;
	else
		x1 = (x1+x2)/2;
		x2 = (x1+x2)/2;
	end
end
disp("解在下列两个数之间")
x1,x2

不动点迭代法

在这里插入图片描述

clc,clear;
%非线性方程的数值解法
%不动点迭代法
syms x;
% 方程为f(x)为构造的不动点迭代方程
f(x) = (x^2 - x + 1)^(1/3);
%迭代区间
a = 0.5;
b = 1.5;
%n为迭代次数
n = 5;
%x0 为开始迭代的点
x0 = 0.5;

df(x) = diff(f,1);
% vpa(sum(abs(df(a:0.01:b))>1),5)
if(sum(logical(abs(df(a:0.01:b))>1))==0)
	disp("ok")
end
X = x0;
for i=1:n
	X = f(X);
end
vpa(X,4)

牛顿迭代法

在这里插入图片描述

clc,clear;
%非线性方程的数值解法
%牛顿迭代法
syms x;
% 方程为f(x) = 0
f(x) = x^3 - x^2 + x - 1;
%n为迭代次数
n = 5;
%x0 为开始迭代的点
x0 = 0.5;

df(x) = diff(f,1);
X = x0;
for i=1:n
	X = X - f(X)/df(X);
end
vpa(X,4)

常微分方程初值问题数值解法

欧拉法

clc,clear;
%欧拉法
h=0.05; %步长  
xf=2; %区间最右边x坐标
x = 0:h:2;%初始化x向量
y = zeros(1,length(x));%初始化y  
y(1) = 1; %y(0)=1  
F_xy = @(x, y)(y.^2-2*x)./y%y导数
for i=1:(length(x)-1) %循环迭代  
    y(i+1)=y(i) + h*(y(i)-2*x(i)/y(i))  
end  
% 	x  
% 	y  
%调用Matlab方法ode45()进行常微分方程初值问题的精确解求解  
%求得的解在函数调用的左端[x_ode45, y_ode45]  
x0 = x(1);  
y0 = y(1);  
yspan = [x0 xf];  
[x_ode45, y_ode45] = ode45(F_xy,yspan,y0);  
%画出精确解  
plot(x_ode45,y_ode45,'--');   
xlabel('x');ylabel('y');  
hold on;
%画出近似解  
plot(x,y,'-');
disp("欧拉法解为")
for i=1:length(y)
    fprintf("%.8f\n",y(i))
end
disp("精确解为")
for i=1:length(y_ode45)
    fprintf("%.8f\n",y_ode45(i));
end
xlabel('x');ylabel('y');  
legend('Exact','Euler');  

改进欧拉法

clc,clear;
%改进欧拉法
h=0.05; %步长  
xf=2; %区间最右侧点  
x = 0:h:2;%初始化x向量  
y = zeros(1,length(x));%初始化y  
y(1) = 1; %y(0)=1  
F_xy = @(x, y)(y.^2-2*x)./y%y导数 
for i=1:(length(x)-1) %循环迭代  
    yp=y(i)+h*(y(i)-2*x(i)/y(i))  
    yc=y(i)+h*(yp-2*x(i+1)/yp)  
    y(i+1)=(yp+yc)/2  
end  
% 	x  
% 	y  
%调用Matlab方法ode45()进行常微分方程初值问题的精确解求解  
%求得的解在函数调用的左端[x_ode45, y_ode45]  
x0 = x(1);  
y0 = y(1);  
yspan = [x0 xf];  
[x_ode45, y_ode45] = ode45(F_xy,yspan,y0);  
%画出精确解  
plot(x_ode45,y_ode45,'--');   
xlabel('x');ylabel('y');
hold on;
%画出近似解  
plot(x,y,'-');  
y=vpa(y,8);
y_ode45=vpa(y_ode45,8);
    disp("改进欧拉法解为")
for i=1:length(y)
    fprintf("%.8f\n",y(i))
end
disp("精确解为")
for i=1:length(y_ode45)
    fprintf("%.8f\n",y_ode45(i));
end
xlabel('x');ylabel('y');  
legend('Exact','improve_Euler');  

PS:csdn是不是没法插入matlab代码?我用的php的格式。
还有那个我求函数最大值是通过取很多点来实现的(为了省事),需要注意一下求出来的不一定是最大值。
以后可能会更新。
链接:https://pan.baidu.com/s/1W7YiEsf0KamzTyLxjTC-zg
提取码:blj5
可能有错误,各位大佬发现别忘记在评论区评论。
要是觉得有用,别忘记分享点赞哦!

南京大学大气科学学院2021~2022秋季学期计算方法课程作业 m 一共七个 学号:191830227 ##一、分析报告###1. 问题分析本次的实习平台上的20个点,要求: a) 用三次样条插值构造出插值曲线; 用最小二乘法构造出b线曲线,b_xy为$_0+b_xy+b_4y^2^2=2$ 。 20个点的坐标如下: X 0.99 0.95 0.87 0.77 0.67 0.56 0.44 0.30 0.16 0.01 是 0.39 0.32 0.27 0.22 0.18 0.15 0.13 0.12 0.13 0.15 X 0.93 0.85 0.73 0.59 0.42 0.29 0.16 0.05 -0.11 -0.20 是 0.40 0.41 0.42 0.43 0.42 0.41 0.40 0.36 0.32 0.22 首先绘制出(x, y)的散点图,观察散点在平面上的分布情况。 散点图 从下面可以实现散点的一个整体的区域,从而在进行三次样条插值时使用可能的条件。 ###2.细节####(1) 仿样条插值的实现 使用三弯矩法计算各个周期上样条函数的系数。 给定$函数=f(x)$在区间$[a,b]$ 上的一组节点$(x_k,y_k)\(k=0,1,2,\cdots,n)$ ,将$[a,b]$划分为n个子区间$[x_{i-1},x_i]\(i=1,2,\cdots,n)$ 。 设样条函数为$S(x)$ ,每个区间上的样条函数为$S_i(x)=a_ix^3+b_ix^2+c_ix+d_i\(i = 1,2,\cdots, n)$。 记$M_i=S^{\prime\prime}(x_i),h_i=x_i-x_{i-1}\ (i=1,2,\cdots,n)$ 。 计算得 $$ \begin{aligned} &S(x)=\frac{M_{i-1}}{6h_i}{(x_i-x)}^3+\frac{M_{i}}{6h_i}{( x-x_{i-1})}^3+(\frac{y_i}{h_i}-\frac{h_iM_i}{6})(x-x_{i-1})+(\frac{y_{i -1}}{h_i}-\frac{h_iM_{i-1}}{6})(x_i-x)\ &x_{i-1}\leq x\leq x_i,i=1,2,\cdots, n-1 \end{对齐} $$ 不考虑最佳条件时,有如下一组组\beta_2\ \qquad\qquad\qquad\vdots\ \alpha_{n-1}M_{n-2}+2M_1+(1-\alpha_{n-1})M_n=\beta_{n-1}\ \end {cases} \end{equation} $$ $$ \alpha_i=\frac{h_i}{h_i+h_{i+1}},\beta_i=\frac{6}{h_i+h_{i+1}}(\frac{y_{i+1}- y_i}{h_{i+1}}-\frac{y_{i}-y_{i-1}}{h_{i}}) $$ 加上上关键条件条件$y_0=y_n,y^\prime_0=y^\prime_n,y^{\prime\prime}_0=y^{\prime\prime}_n$。 由$M_0=M_n$和$y^\prime_0=y^\prime_n$ ,得 $$ \begin{equation} \begin{cases} M_0=M_n\ \frac{h_1}{h_1+h_n}M_1-\frac{h_n}{h_1+h_n}M_{n-1}+2M_n=\frac{ 6}{h_1+h_n}(\frac{y_1-y_0}{h_1}-\frac{y_n-y_{n-1}}{h_n}) \end{cases} \end{equation} $$ 有几个组联立可出$M_i$ ,x想要得$S()$ 的解系数。 考虑到提供的散点围了部分区域,无法使用一个样条函数$S(x)$进行插值,所以考虑使用参数的形式进行插值。 设插值曲线的参数为 $$ \begin{equation} \begin{cases} x=phi(u)\ \end{cases} \end{equation} \quad( leq u\leq 21) $$ 然后分别对$(u_i,\phi_i)$和$(u_i,\psi_i)$进行插值发酵。 因为共有2个点(周期目标条件又加了一点),所以你取值在1到21之间,插值节点可以简单地设置$u_i=i$,方便计算。 记样条函数为$x=\Phi(u),y=\Psi(u)$ ,将它们联立即得到原问题的插值函数。 ####(2)最小二乘法的实现 将$(x_i,y_i,x_i,x_y_i,y_i^2)$i原因变量,$x_^2$由于目标变量,通过最小二乘
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值