

clc
clear
close all
% 读取
tbl = readtable('浓度变化.xlsx', 'ReadVariableNames', false, 'ReadRowNames', true, 'DatetimeType', 'datetime');
time = tbl{'时间',:};
Cin = tbl{'Cin',:};
Cout = tbl{'Cout',:};
% 对齐时间
time = (time-time(1)).*24.*60;
newtime = linspace(time(1),time(end),50*numel(time));
% 插值
Cin = interp1(time, Cin,newtime);
Cout = interp1(time,Cout,newtime);
time = newtime;
% 穷举可能的参数
Pd = exp(linspace(log(5),log(180),100));
dt = linspace(3500,120000,100);
[Pd, dt] = meshgrid(Pd, dt);
sse = zeros(size(Pd));
for i = 1:size(Pd,1)
for j = 1:size(Pd,2)
sse(i,j) = objective([Pd(i,j), dt(i,j)], time, Cin, Cout);
end
i
end
% 画出xyz图(x: pd, y: dt, z: 误差平方和)
s = surf(Pd, dt, sse, 'EdgeColor', 'none');
view(2);
% 目标函数,误差平方和最小化
function sse = objective(coeff, time, Cin, Cout)
Pd = coeff(1);
dt = coeff(2);
pred = predict(time, Cin, Pd, dt); % 用模型公式预测Cout值
sse = pred-Cout; % 差分找误差平方和
sse = sse*sse';
end
function Cout = predict(time, Cin, Pd, dt) % 预测
gval = g(time, Pd, dt); % 权重函数
gval(1) = gval(2);
Cout = zeros(size(Cin));
for i = 2:numel(time) % 遍历每个时刻t求Cout(t)
v = gval(1:i).*Cin(i:-1:1); % 求被积函数在0到t的值
v(2:end-1) = v(2:end-1).*2; % 复化梯形公式求积分值
Cout(i) = sum(v)./2.*time(i)./(i-1); % 复化梯形公式求积分值
end
end
function val = g(T, Pd, dt) % 按公式定义
sig = sqrt(2.*Pd.*T./dt);
val = 1./T.*normpdf(T./dt, 1, sig);
end