初始步骤
我想我们应该首先在 Matlab 中获得您要建模的函数的表示。您的公式的直接翻译如下所示:
function y = targetfunction(A,V,P,bc,b)
y = (A/2) * (1 - V * sin((b-bc) / P));
end
掌握数据
我的下一步将是生成一些可以使用的数据(您自然会使用自己的数据)。所以这是一个生成一些嘈杂数据的函数。请注意,我已经为参数提供了一些值。
function [y b] = generateData(npoints,noise)
A = 2;
V = 1;
P = 0.7;
bc = 0;
b = 2 * pi * rand(npoints,1);
y = targetfunction(A,V,P,bc,b) + noise * randn(npoints,1);
end
该函数rand
在区间上生成随机点[0,1]
,我将它们乘以2*pi
在区间上随机获得点[0, 2*pi]
。然后我在这些点应用了目标函数,并添加了一些噪声(该函数randn
生成正态分布的随机变量)。
拟合参数
最复杂的函数是将模型拟合到您的数据的函数。为此,我使用了函数fminunc
,它可以进行无约束的最小化。例程如下所示:
function [A V P bc] = bestfit(y,b)
x0(1) = 1; %# A
x0(2) = 1; %# V
x0(3) = 0.5; %# P
x0(4) = 0; %# bc
f = @(x) norm(y - targetfunction(x(1),x(2),x(3),x(4),b));
x = fminunc(f,x0);
A = x(1);
V = x(2);
P = x(3);
bc = x(4);
end
让我们逐行浏览。首先,我定义f
要最小化的函数。这不是太难。为了在 Matlab 中最小化一个函数,它需要将单个向量作为参数。因此,我们必须将我们的四个参数打包到一个向量中,我在前四行中这样做了。我使用的值与我用来生成数据的值很接近,但并不相同。
然后我定义我想要最小化的函数。它需要一个参数x
,将其解包并提供给targetfunction
,以及b
我们数据集中的点。希望这些接近y
。y
我们通过减去y
和应用函数来测量它们的距离,该函数norm
对每个分量求平方,将它们相加并取平方根(即它计算均方根误差)。
然后我调用fminunc
我们的函数以最小化,并对参数进行初始猜测。这使用一个内部例程来为每个参数找到最接近的匹配项,并将它们返回到向量中x
。
最后,我从 vector 中解压参数x
。
把它们放在一起
我们现在拥有了我们需要的所有组件,所以我们只需要一个最终函数将它们联系在一起。这里是:
function master
%# Generate some data (you should read in your own data here)
[f b] = generateData(1000,1);
%# Find the best fitting parameters
[A V P bc] = bestfit(f,b);
%# Print them to the screen
fprintf('A = %f\n',A)
fprintf('V = %f\n',V)
fprintf('P = %f\n',P)
fprintf('bc = %f\n',bc)
%# Make plots of the data and the function we have fitted
plot(b,f,'.');
hold on
plot(sort(b),targetfunction(A,V,P,bc,sort(b)),'r','LineWidth',2)
end
如果我运行这个函数,我会看到它被打印到屏幕上:
>> master
Local minimum found.
Optimization completed because the size of the gradient is less than
the default value of the function tolerance.
A = 1.991727
V = 0.979819
P = 0.695265
bc = 0.067431
并出现以下情节:
这种合身对我来说已经足够好了。如果您对我在这里所做的任何事情有任何疑问,请告诉我。