不依赖曲线拟合工具箱,也可以使用fminsearch解决这个问题。我首先生成了一些您已经拥有但没有与我们共享的数据。必须对参数 a 和 b 进行初始猜测 (p0)。然后我通过最小化数据和拟合之间的平方误差来进行优化,得到向量p_fit,其中包含a和b的优化参数。最后将结果可视化。
% ----- Generating some data for x, y and t (which you already got)
N = 10; % num of data points
x = linspace(0,5,N);
t = linspace(0,10,N);
% random parameters
a = rand()*5; % a between 0 and 5
b = (rand()-1); % b between -1 and 0
y = a*sqrt(x).*exp(b*t) + rand(size(x))*0.1; % noisy data
% ----- YOU START HERE WITH YOUR PROBLEM -----
% put x and t into a 2 row matrix for simplicity
D(1,:) = x;
D(2,:) = t;
% create model function with parameters p(1) = a and p(2) = b
model = @(p, D) p(1)*sqrt(D(1,:)).*exp(p(2)*D(2,:));
e = @(p) sum((y - model(p,D)).^2); % minimize squared errors
p0 = [1,-1]; % an initial guess (positive a and probably negative b for a decay)
[p_fit, r1] = fminsearch(e, p0); % Optimize
% ----- VISUALIZATION ----
figure
plot(x,y,'ko')
hold on
X = linspace(min(x), max(x), 100);
T = linspace(min(t), max(t), 100);
plot(X, model(p_fit, [X; T]), 'r--')
legend('data', sprintf('fit: y(t,x) = %.2f*sqrt(x)*exp(%.2f*t)', p_fit))
结果可能类似于
许多评论后更新
您的数据是列向量,我的解决方案使用行向量。当 errorfunction 试图计算列向量 (y) 和行向量(模型函数的结果)的差异时,就会发生错误。 Easy hack:将它们全部变成行向量并使用我的方法。结果是:a = 0.5296 和 b = 0.0013。
但是,优化取决于最初的猜测p0,您可能想尝试一下。
clear variables
load matlab.mat
% put x and t into a 2 row matrix for simplicity
D(1,:) = x;
D(2,:) = t;
y = reshape(y, 1, length(y)); % <-- also y is a row vector, now
% create model function with parameters p(1) = a and p(2) = b
model = @(p, D) p(1)*sqrt(D(1,:)).*exp(p(2)*D(2,:));
e = @(p) sum((y - model(p,D)).^2); % minimize squared errors
p0 = [1,0]; % an initial guess (positive a and probably negative b for a decay)
[p_fit, r1] = fminsearch(e, p0); % Optimize
% p_fit = nlinfit(D, y, model, p0) % as a working alternative with dependency on the statistics toolbox
% ----- VISUALIZATION ----
figure
plot(x,y,'ko', 'markerfacecolor', 'black', 'markersize',5)
hold on
X = linspace(min(x), max(x), 100);
T = linspace(min(t), max(t), 100);
plot(X, model(p_fit, [X; T]), 'r-', 'linewidth', 2)
legend('data', sprintf('fit: y(t,x) = %.2f*sqrt(x)*exp(%.2f*t)', p_fit))
虽然结果看起来不太令人满意。但这主要是因为您的数据。看看这里: