数据拟合实验
实验类型:●验证性实验 ○综合性实验 ○设计性实验
实验目的: 进一步熟练掌握最小二乘多项式拟合算法,提高编程能力和解决拟合问题的实践技能。
实验内容:
1 对下列数据,求解最小二乘抛物线f(x)=Ax2+Bx+C
x | -3 | -1 | 1 | 3 |
y | 15 | 5 | 1 | 5 |
2 数学模型与拟合算法应用:logistic 人口增长模型的参数确定。当人口P(t)受限于极限值L时,它符合logistic曲线,具有函数形式P(t)=L/(1+CeAt)。对下列数据集求解参数A和C,L是已知的。
(a)5个(t,P)点:(0,200), (1,400), (2,650), (3,850), (4,950); L=1000
(b)5个(t,P)点:(0,500), (1,1000), (2,1800)(3,2800), (4,3700); L=5000
先在A4纸上手工计算,再编写程序、上机调试和计算。
实验原理: 求多项式或确定模型参数,使得拟合函数值与离散点纵坐标偏差平方和最小----误差向量2范数的平方最小。
实验说明:数学模型与拟合算法应用问题,应对形式P(t)=L/(1+CeAt)的非线性函数进行变形,取对数,引入变换,从而将非线性函数模型转化为一次多项式模型(即完成模型的线性化处理),并用前述变换对数据处理使得处理后的数据适合一次多项式拟合。要求输入所有拟合点(ti,Pi),输出拟合函数的待定系数并在同一坐标系下画出原始离散点和拟合函数P(t)=L/(1+CeAt)的曲线(注意要求画的不是一次多项式的曲线而是原始离散点和拟合函数P(t)=L/(1+CeAt)的曲线)。
实验步骤
- 要求上机实验前先手工计算再编写出程序代码;
- 编辑录入程序;
- 调试程序并截图记录调试过程中出现的问题及修改程序的过程;
- 经反复调试后,运行程序并验证程序运行是否正确。。
- 截图记录运行时的输入和输出,并把截图及时粘贴在Word文档里,配上必要的文字说明,以便证实你的实验过程真实可靠、证实你的程序正确性和可靠性。
- 要求在A4纸上手工计算并和计算机程序计算的主要中间结果进行列表比较,手工解算过程中所有数据保留5位小数,依据列表进行验证手工解算和机器解算是否一致,若不一致,或纠正手工计算或修改计算机程序重新调试和运行,直到两者结果高度一致。严禁不加分析、不进行列表对比的妄下断语(即论断应有充分的依据,必要的分析、对比和推理过程)。将手工计算过程及其验证结论拍照成JPG图片插入在实验报告的word 电子版中随实验报告一起打印并提交。
实验报告:根据实验情况和结果撰写并递交实验报告。
实验报告打印和装订顺序要求
实验报告打印要求:在 A4 纸上将实验报告的 Word 文档双面打印;打印的字迹要清晰,报告内容文字或截图上的文字打印后,要确保字迹清晰可见,若字迹不清影响评阅,报告得分将酌情扣减。
实验报告装订顺序
1)实验任务(本文档版式不得做任何改动);
2)实验报告正文(Word文档);
3)可将A4 纸上详细手工计算过程拍照成JPG图片插入在实验报告的 word 电子版中随Word文档双面打印。
实验总结 (学会了......; 掌握了......; 训练了......; 发现了......; 今后学习中......有待提高。)
程序代码(MATLAB程序)
x | -3 | -1 | 1 | 3 |
y | 15 | 5 | 1 | 5 |
手工计算结果:
拟合抛物线的系数为:
a = 0.8750
b = -1.7000
c = 2.1250
程序代码:
function [a, b, c, xx, yy] = sy81(x, y)
% 输入:
% x - 自变量数据点, y - 因变量数据点
% a, b, c - 拟合抛物线的系数
% xx, yy - 拟合曲线的自变量和因变量数据点
% 构建矩阵 X
X = [x.^2; x; ones(1, length(x))]';
coeff = (X' * X) \ (X' * y');
a = coeff(1);
b = coeff(2);
c = coeff(3);
% 显示结果
fprintf('拟合抛物线的系数为:\n');
fprintf('a = %.5f\n', a);
fprintf('b = %.5f\n', b);
fprintf('c = %.5f\n', c);
xx = linspace(min(x), max(x), 100);
yy = a * xx.^2 + b * xx + c;
figure;
plot(x, y, 'ro', 'MarkerSize', 8, 'LineWidth', 2);
hold on;
plot(xx, yy, 'b-', 'LineWidth', 2);
title('最小二乘法拟合抛物线');
xlabel('x');
ylabel('y');
legend('数据点', '拟合抛物线');
grid on;
end程序运行界面及结果:
手工计算与matlab结果对比:
A | B | C | |
手工计算 | 0.87500 | -1.70000 | 2.12500 |
实验结果 | 0.87500 | -1.70000 | 2.12500 |
经过对比,手工计算结果与matlab结果完全相同。
2.(a)5个(t,P)点:(0,200), (1,400), (2,650), (3,850), (4,950); L=1000
手工计算结果:
程序代码:
function [A,C,t1,P1,P_1,L1] = sy82()
t1 = [0, 1, 2, 3, 4];
P1 = [200, 400, 650, 850, 950];
P_1 = [log(4), log(3/2), log(7/13), log(3/17), log(1/19)];
L1 = 1000;
Y1 = log((L1 - P1) ./ P1)';
X1 = [t1', ones(length(t1), 1)];
coeff1 = X1 \ Y1;
A1 = -coeff1(1);
D1=coeff1(2);
C1 = exp(coeff1(2));
fprintf('数据集 (a) 的参数为:\n');
fprintf('A = -%.4f\n', A1);
fprintf('D = %.4f\n', D1);
fprintf('C = %.4f\n', C1);
t_fit1 = linspace(min(t1), max(t1), 100);
P_fit1 = L1 ./ (1 + C1 * exp(-A1 * t_fit1));
figure;
plot(t1, P1, 'ro', 'MarkerSize', 8, 'LineWidth', 2);
hold on;
plot(t_fit1, P_fit1, 'b-', 'LineWidth', 2);
title('数据集 (a) 的 Logistic 拟合');
xlabel('时间 t');
ylabel('人口 P(t)');
legend('数据点', '拟合曲线');
grid on;
xx = linspace(min(t1), max(t1), 100);
yy = -A1 * xx + D1;
figure;
plot(t1, P_1, 'ro', 'MarkerSize', 8, 'LineWidth', 2);
hold on;
plot(xx, yy, 'b-', 'LineWidth', 2);
title('最小二乘法拟合曲线');
xlabel('t');
ylabel('y');
legend('数据点', '拟合曲线');
grid on;
end程序运行界面及结果:
手工计算与matlab结果对比:
A | D | C | |
手工计算 | -1.08015 | 1.45904 | 4.30184 |
实验结果 | -1.0802 | 1.4590 | 4.3018 |
经过对比,手工计算结果与matlab结果一样(matlab保留四位小数,手工计算保留五位小数)。
2. (b)5个(t,P)点:(0,500), (1,1000), (2,1800)(3,2800), (4,3700); L=5000
手工计算结果:
程序代码:
function [A,C,t2,P2,P_2,L2] = sy83()
t2 = [0, 1, 2, 3, 4];
P2 = [500, 1000, 1800, 2800, 3700];
P_2 = [log(9), log(4), log(16/9), log(11/14), log(13/37)];
L2 = 5000;
Y2 = log((L2 - P2) ./ P2)';
X2 = [t2', ones(length(t2), 1)];
coeff2 = X2 \ Y2;
A2 = -coeff2(1);
D2=coeff2(2);
C2 = exp(coeff2(2));
fprintf('数据集 (b) 的参数为:\n');
fprintf('A =- %.4f\n', A2);
fprintf('D = %.4f\n', D2);
fprintf('C = %.4f\n', C2);
t_fit2 = linspace(min(t2), max(t2), 100);
P_fit2 = L2 ./ (1 + C2 * exp(-A2 * t_fit2));
figure;
plot(t2, P2, 'ro', 'MarkerSize', 8, 'LineWidth', 2);
hold on;
plot(t_fit2, P_fit2, 'b-', 'LineWidth', 2);
title('数据集 (b) 的 Logistic 拟合');
xlabel('时间 t');
ylabel('人口 P(t)');
legend('数据点', '拟合曲线');
grid on;
grid on;
xx = linspace(min(t2), max(t2), 100);
yy = -A2 * xx + D2;
figure;
plot(t2, P_2, 'ro', 'MarkerSize', 8, 'LineWidth', 2);
hold on;
plot(xx, yy, 'b-', 'LineWidth', 2);
title('最小二乘法拟合曲线');
xlabel('t');
ylabel('y');
legend('数据点', '拟合曲线');
grid on;
end程序运行界面及结果:
手工计算与matlab结果对比:
A | B | C | |
手工计算 | -0.81138 | 2.19711 | 8.99897 |
实验结果 | -0.8114 | 2.1971 | 8.9991 |
经过对比,手工计算结果与matlab结果一样(matlab保留四位小数,手工计算保留五位小数)。
数学建模:
代码:
function [t,r,A,C] = sy84()
t = [0.10, 0.24, 0.38, 0.52, 0.66, 0.80, 0.94, 1.08, 1.22, 1.36, 1.50, 1.65, 1.79, 1.93, ...
3.26, 3.53, 3.80, 4.07, 4.34, 4.61, 15.0, 25.0, 34.0, 53.0, 62.0]; % 时间 t (毫秒)
r = [11.1, 19.9, 25.4, 28.8, 31.9, 34.2, 36.3, 38.9, 41.0, 42.8, 44.4, 46.0, 46.9, 48.7,...
59.0, 61.1, 62.9, 64.3, 65.6, 67.3, 106.5, 130.0, 145.0, 175.0, 185.0]; % 半径 r (米)
ln_r = log(r);
ln_et2_rho = 1/5 * log((t.^2));
X = [ones(length(ln_et2_rho), 1), ln_et2_rho'];
coefficients = X \ ln_r'; A = 1/5; C = exp(coefficients(1));
disp('拟合参数:'); (['A = ', num2str(A)]); disp(['C = ', num2str(C)]);
f = fit(t', r', 'smoothingspline');
figure;plot(f, t, r);
title('时间与半径拟合曲线');
xlabel('时间 t (毫秒)'); ylabel('半径 r (米)');
legend('拟合曲线', '原始数据');
grid on;
end
运行及结果界面:
实验总结:
在这次实验中,我学会了使用最小二乘法拟合抛物线和曲线,并在MATLAB中实现了相关计算结果输出和绘图。并且掌握了不同拟合方法的应用。通过分析给定的数据,我可以手工计算正确结果和编写程序,我还掌握了如何建立和求解正规方程。在实验过程中,我训练了数据处理和 MATLAB 编程的技能。发现了一些在处理矩阵运算和方程求解时的常见问题。
今后学习中,我需要进一步提高对算法原理的理解和 MATLAB 编程的熟练程度,特别是在处理更复杂数据和模型拟合方面。我也会继续探索更多的拟合算法,以便更好地处理不同类型的数据和问题。这次实验为我打下了良好的基础,我会在今后的学习中不断提升自己。