
(欠定方程)
%解析解:
A = [2 -9 3 -2 -1; 10 -1 10 5 0; 8 -2 -4 -6 3; -5 -6 -6 -8 -4];
B = [-1 -4 0; -3 -8 -4; 0 3 3; 9 -5 3];
[rank(A), rank([A B])]
x0 = null(sym(A)); % 求AX=0的基础解
x_analytical = sym(A)\B; syms a;
x = a*[x0 x0 x0]+x_analytical
A*x - B
输出:
x =
[ - (127*a)/170 - 18/17, 193/170 - (127*a)/170, 5/34 - (127*a)/170]
[ (307*a)/408 + 347/204, (307*a)/408 - 719/408, (307*a)/408 - 103/408]
[(3659*a)/2040 + 587/204, (3659*a)/2040 - 8911/2040, (3659*a)/2040 - 283/408]
[- (1321*a)/680 - 265/68, 3069/680 - (1321*a)/680, 33/136 - (1321*a)/680]
[ a, a, a]
ans =
[0, 0, 0]
[0, 0, 0]
[0, 0, 0]
[0, 0, 0]
%数值解:
x0=null(A); x_numerical=A\B; syms a;
x=a*[x0 x0 x0]+x_numerical; vpa(x,10)
A*x-B
ans =
[0.2474402553*a + 0.1396556436, 0.2474402553*a - 0.6840666849, 0.2474402553*a - 0.1418420333]
[0.4938507789 - 0.2492262414*a, 0.07023776988 - 0.2492262414*a, 0.03853511888 - 0.2492262414*a]
[ -0.5940839201*a, -0.5940839201*a, -0.5940839201*a]
[0.6434420813*a - 0.7805411315, 0.6434420813*a - 0.2178190763, 0.6434420813*a - 0.5086089095]
[- 0.3312192394*a - 1.60426346, 2.435364854 - 0.3312192394*a, 0.3867176824 - 0.3312192394*a]
ans =
[ a/36028797018963968, a/36028797018963968, a/36028797018963968]
[-(99*a)/36028797018963968, -(99*a)/36028797018963968, -(99*a)/36028797018963968]
[ (5*a)/18014398509481984, (5*a)/18014398509481984, (5*a)/18014398509481984]
[ a/562949953421312, a/562949953421312, a/562949953421312]

syms x1 x2
eqns = [x1^2 - x2 - 1 == 0, (x1-2)^2+(x2-0.5)^2 - 1== 0];
[x1,x2] = solve(eqns,[x1 x2]);
norm(double([x1.^2-x2-1 (x1-2).^2+(x2-0.5).^2-1]))
format long;
syms x1 x2
eqns = [x1^2 - x2 - 1 == 0, (x1-2)^2+(x2-0.5)^2 - 1== 0];
S = solve(eqns,[x1 x2]);
x1 = double(vpa(S.x1)) %将sym类型转换为double类型
x2 = double(vpa(S.x2)) %将sym类型转换为double类型
[res1,res2] = deal(zeros(length(x1),1),zeros(length(x2),1)); %建立残差矩阵
for i = 1:length(x(1))
res1(i) = x1(i)^2 - x2(i) - 1;
res2(i) = (x1(i)-2)^2+(x2(i)-0.5)^2 - 1;
end
res1,res2
输出
x1 =
1.067346085806690 + 0.000000000000000i
1.546342883319945 + 0.000000000000000i
-1.306844484563317 + 1.213690445160591i
-1.306844484563317 - 1.213690445160591i
x2 =
0.139227666886861 + 0.000000000000000i
1.391176312794241 + 0.000000000000000i
-0.765201989840551 - 3.172209328450632i
-0.765201989840551 + 3.172209328450632i
res1 =
1.0e-15 *
-0.222044604925031
0
0
0
res2 =
0
0
0
0

a = [10 -1 -2; -1 10 -2; -1 -1 5];
b = [72; 83; 42];
jacobi(a,b,[0;0;0])
seidel(a,b,[0;0;0])
function y=jacobi(a,b,x0)
D = diag(diag(a)); U=-triu(a,1); L=-tril(a,-1);
B=D\(L+U); f=D\b;
y = B*x0+f;
n = 1;
while norm(y-x0)>=1.0e-6
x0 = y;
y = B*x0+f;
n = n+1;
end
N
function y=seidel(a,b,x0)
D = diag(diag(a)); U = -triu(a,1); L = -tril(a,-1);
G = (D-L)\U; f = (D-L)\b;
y = G*x0+f;
n = 1;
while norm(y-x0)>=1.0e-6
x0 = y;
y = G*x0+f;
n = n+1;
end
n
(jacobi)输出:
n =
17
ans =
11.0000
12.0000
13.0000
n =
10
(seidel)输出:
ans =
11.0000
12.0000
13.0000

x=[-2,-1.7,-1.4,-1.1,-0.8,-0.5,-0.2,0.1,0.4,0.7,1,1.3,...
1.6,1.9,2.2,2.5,2.8,3.1,3.4,3.7,4,4.3,4.6,4.9];
y=[0.10289,0.11741,0.13158,0.14483,0.15656,0.16622,0.17332,...
0.1775,0.17853,0.17635,0.17109,0.16302,0.15255,0.1402,...
0.12655,0.11219,0.09768,0.08353,0.07019,0.05786,0.04687,...
0.03729,0.02914,0.02236];
x1 = [-2:0.1:4.9];
subplot(1,2,1)
y1 = lagrange(x,y,x1);
y2 = interp1(x,y,x1,'linear');
y3 = interp1(x,y,x1,'cubic');
plot(x1,[y1',y2',y3'],':',x,y,'*');
title('拉格朗日、线性插值与立方插值'),legend('lagrange插值曲线','线性插值曲线','立方插值曲线','原始数据点')
subplot(1,2,2)
y4 = interp1(x,y,x1,'nearest');
y5 = interp1(x,y,x1,'spline');
y6 = interp1(x,y,x1,'pchip');
plot(x1,[y4',y5',y6'],':',x,y,'*');
title('nearest、spline、pchip插值'),legend('nearest插值曲线','spline插值曲线','pchip插值曲线','原始数据点')

优劣:拉格朗日插值曲线没有线性插值、立方插值曲线那么平滑,但计算复杂度低;nearest插值曲线没有spline插值、pchip插值曲线那么平滑,但计算简单,其中spline插值曲线效果最佳。

[x,y]=meshgrid(0.1:0.1:1.1);
z=[0.83041,0.82727,0.82406,0.82098,0.81824,0.8161,0.81481,0.81463,0.81579,0.81853,0.82304;
0.83172,0.83249,0.83584,0.84201,0.85125,0.86376,0.87975,0.89935,0.92263,0.94959,0.9801;
0.83587,0.84345,0.85631,0.87466,0.89867,0.9284,0.96377,1.0045,1.0502,1.1,1.1529;
0.84286,0.86013,0.88537,0.91865,0.95985,1.0086,1.0642,1.1253,1.1904,1.257,1.3222;
0.85268,0.88251,0.92286,0.97346,1.0336,1.1019,1.1764,1.254,1.3308,1.4017,1.4605;
0.86532,0.91049,0.96847,1.0383,1.118,1.2046,1.2937,1.3793,1.4539,1.5086,1.5335;
0.88078,0.94396,1.0217,1.1118,1.2102,1.311,1.4063,1.4859,1.5377,1.5484,1.5052;
0.89904,0.98276,1.082,1.1922,1.3061,1.4138,1.5021,1.5555,1.5573,1.4915,1.346;
0.92006,1.0266,1.1482,1.2768,1.4005,1.5034,1.5661,1.5678,1.4889,1.3156,1.0454;
0.94381,1.0752,1.2191,1.3624,1.4866,1.5684,1.5821,1.5032,1.315,1.0155,0.62477;
0.97023,1.1279,1.2929,1.4448,1.5564,1.5964,1.5341,1.3473,1.0321,0.61268,0.14763];
[x1,y1]=meshgrid(0.1:0.02:1.1);
z1 = interp2(x,y,z,x1,y1); % z1=interp2(x,y,z,x1,y1,'spline');
figure,surf(x1,y1,z1),axis([0.1,1.1,0.1,1.1,0,1.8])
% axis([0.1,1.1,0.1,1.1,min(z1(:)),max(z1(:))])

前面给出的数据分别为一元数据和二元数据,试用分段三次样条函数和B样条函数对其进行拟合。
x=[-2,-1.7,-1.4,-1.1,-0.8,-0.5,-0.2,0.1,0.4,0.7,1,1.3,...
1.6,1.9,2.2,2.5,2.8,3.1,3.4,3.7,4,4.3,4.6,4.9];
y=[0.10289,0.11741,0.13158,0.14483,0.15656,0.16622,0.17332,...
0.1775,0.17853,0.17635,0.17109,0.16302,0.15255,0.1402,...
0.12655,0.11219,0.09768,0.08353,0.07019,0.05786,0.04687,...
0.03729,0.02914,0.02236];
figure, plot(x,y,'k*'), hold on;
sp1 = csapi(x,y); fnplt(sp1,'--'), hold on;
sp2 = spapi(5,x,y); fnplt(sp2,':')
title('一元数据拟合'),legend('原始数据','三次样条函数','5次B样条函数')

x1 = 0.1:0.1:1.1; y1 = 0.1:0.1:1.1;
subplot(121), sp1 = csapi({x1,y1},z); fnplt(sp1);axis([0.1,1.1,0.1,1.1,0,1.8])
subplot(122), sp2 = spapi({5,5},{x1,y1},z); fnplt(sp2);axis([0.1,1.1,0.1,1.1,0,1.8])

上面给出的数据,试考虑用多项式插值的方法对其数据进行逼近,并选择一个能较好拟合原数据的多项式阶次。
x=[-2,-1.7,-1.4,-1.1,-0.8,-0.5,-0.2,0.1,0.4,0.7,1,1.3,...
1.6,1.9,2.2,2.5,2.8,3.1,3.4,3.7,4,4.3,4.6,4.9];
y=[0.10289,0.11741,0.13158,0.14483,0.15656,0.16622,0.17332,...
0.1775,0.17853,0.17635,0.17109,0.16302,0.15255,0.1402,...
0.12655,0.11219,0.09768,0.08353,0.07019,0.05786,0.04687,...
0.03729,0.02914,0.02236];
x0=-2:0.02:4.9;
p3=polyfit(x,y,3); y3=polyval(p3,x0);
p5=polyfit(x,y,5); y5=polyval(p5,x0);
p7=polyfit(x,y,7); y7=polyval(p7,x0);
p9=polyfit(x,y,9); y9=polyval(p9,x0);
p11=polyfit(x,y,11); y11=polyval(p11,x0);
plot(x0,[y3; y5; y7; y9; y11])
从拟合的结果可以发现,选择5 次多项式就能较好地拟合原始数据。
x=[-2,-1.7,-1.4,-1.1,-0.8,-0.5,-0.2,0.1,0.4,0.7,1,1.3,...
1.6,1.9,2.2,2.5,2.8,3.1,3.4,3.7,4,4.3,4.6,4.9];
y=[0.10289,0.11741,0.13158,0.14483,0.15656,0.16622,0.17332,...
0.1775,0.17853,0.17635,0.17109,0.16302,0.15255,0.1402,...
0.12655,0.11219,0.09768,0.08353,0.07019,0.05786,0.04687,...
0.03729,0.02914,0.02236];
figure, plot(x,y,'k*'),hold on;
p2 = polyfit(x,y,2); y2 = polyval(p2,x);
p3 = polyfit(x,y,3); y3 = polyval(p3,x);
p4 = polyfit(x,y,4); y4 = polyval(p4,x);
p5 = polyfit(x,y,5); y5 = polyval(p5,x);
p6 = polyfit(x,y,6); y6 = polyval(p6,x);
plot(x,[y2',y3',y4',y5',y6']), title('多项式拟合'), legend('原始数据','2次拟合','3次拟合','4次拟合','5次拟合','6次拟合');
if(sum((y2-y).^2)>sum((y3-y).^2)>sum((y4-y).^2)>sum((y5-y).^2)>sum((y6-y).^2))
vpa(poly2sym(p6),4)
end
输出
ans =
- 6.457e-6*x^6 - 2.477e-5*x^5 + 0.0007888*x^4 - 0.0007826*x^3 - 0.01729*x^2 + 0.01175*x + 0.1765


x=[-2,-1.7,-1.4,-1.1,-0.8,-0.5,-0.2,0.1,0.4,0.7,1,1.3,...
1.6,1.9,2.2,2.5,2.8,3.1,3.4,3.7,4,4.3,4.6,4.9];
y=[0.10289,0.11741,0.13158,0.14483,0.15656,0.16622,0.17332,...
0.1775,0.17853,0.17635,0.17109,0.16302,0.15255,0.1402,...
0.12655,0.11219,0.09768,0.08353,0.07019,0.05786,0.04687,...
0.03729,0.02914,0.02236];
f = inline('exp(-(x-u(1)).^2/2/u(2).^2)/sqrt(2*pi)./u(2)','u','x')
[uu,res] = lsqcurvefit(f,[1,1],x,y)
figure, plot(x,y,'k*'); hold on;
y1 = f(uu,x); plot(x,y1), title('数据最小二乘法拟合'),legend('原始数据','最小二乘法拟合');
输出:
uu =
0.3461 2.2340
res =
1.8117e-09


[x,y]=meshgrid(0.1:0.1:1.1);
z=[0.83041,0.82727,0.82406,0.82098,0.81824,0.8161,0.81481,0.81463,0.81579,0.81853,0.82304;
0.83172,0.83249,0.83584,0.84201,0.85125,0.86376,0.87975,0.89935,0.92263,0.94959,0.9801;
0.83587,0.84345,0.85631,0.87466,0.89867,0.9284,0.96377,1.0045,1.0502,1.1,1.1529;
0.84286,0.86013,0.88537,0.91865,0.95985,1.0086,1.0642,1.1253,1.1904,1.257,1.3222;
0.85268,0.88251,0.92286,0.97346,1.0336,1.1019,1.1764,1.254,1.3308,1.4017,1.4605;
0.86532,0.91049,0.96847,1.0383,1.118,1.2046,1.2937,1.3793,1.4539,1.5086,1.5335;
0.88078,0.94396,1.0217,1.1118,1.2102,1.311,1.4063,1.4859,1.5377,1.5484,1.5052;
0.89904,0.98276,1.082,1.1922,1.3061,1.4138,1.5021,1.5555,1.5573,1.4915,1.346;
0.92006,1.0266,1.1482,1.2768,1.4005,1.5034,1.5661,1.5678,1.4889,1.3156,1.0454;
0.94381,1.0752,1.2191,1.3624,1.4866,1.5684,1.5821,1.5032,1.315,1.0155,0.62477;
0.97023,1.1279,1.2929,1.4448,1.5564,1.5964,1.5341,1.3473,1.0321,0.61268,0.14763];
figure, plot3(x,y,z,'k*'); hold on;
[x1,y1,z1] = deal(x(:),y(:),z(:));
A = [sin(x1.^2.*y1), cos(y1.^2.*x1), x1.^2, x1.*y1, ones(size(x1))];
uu = A\z1
[x,y] = meshgrid(0.1:0.02:1.1);
zz = uu(1)*sin(x.^2.*y) + uu(2)*cos(y.^2.*x) + uu(3)*x.^2 + uu(4)*x.*y + uu(5);
surf(x,y,zz), title('数据最小二乘法拟合');
或者
figure, plot3(x,y,z,'k*'); hold on;
[x,y] = meshgrid(0.1:0.02:1.1);
zz = A*uu;
zz = reshape(zz,size(x));
surf(x,y,zz), title('数据最小二乘法拟合');
输出:
uu =
-0.892046932516342
3.093786470903605
-0.122032779311857
2.708280894352104
-2.425070282206750

假设已知一组实测数据在文件c8pdat.dat中给出,试通过插值的方法绘制出三维曲面。
c8pdata = load('c8pdat.dat');
[x, y, z] = deal(c8pdata(:,1), c8pdata(:,2), c8pdata(:,3));
[max(x), min(x) max(y), min(y) max(z),min(z)] % 找出插值区域
[x1,y1] = meshgrid(0:0.02:1,0:0.02:1);
z1 = griddata(x,y,z,x1,y1,'v4');
figure, plot3(x,y,z,'k*'); hold on;
surf(x1,y1,z1), axis([0,1,0,1,0,2])
title('插值三维曲面');legend('原始数据','插值曲面')

本文探讨了数值计算中的多项式插值问题,包括拉格朗日插值、线性插值、立方插值以及最近邻插值、样条插值等方法。通过实例展示了不同插值方法在数据拟合上的表现,分析了它们的平滑度和计算复杂度。此外,还涉及到了最小二乘法在数据拟合中的应用,以及分段三次样条函数和B样条函数的使用。这些方法在解决实际问题中具有广泛的应用价值。

34

被折叠的 条评论
为什么被折叠?



