我有一些实验数据和一个我想尝试拟合的理论模型。我已经用模型制作了一个函数文件 - 代码如下所示
function [ Q,P ] = RodFit(k,C )
% Function file for the theoretical scattering from a Rod
% R = radius, L = length
R = 10; % radius in Å
L = 1000; % length in Å
Q = 0.001:0.0001:0.5;
fun = @(x) ( (2.*besselj(1,Q.*R.*sin(x)))./...
(Q.*R.*sin(x)).*...
(sin(Q.*L.*cos(x)./2))./...
(Q.*L.*cos(x)./2)...
).^2.*sin(x);
P = (integral(fun,0,pi/2,'ArrayValued',true))*k+C;
end
Q 是 x 值,P 是 y 值。我可以从 matlab 命令行很好地调用该函数,它工作正常,例如 [Q,P] = RodFit(1,0.001) 给了我一个我可以使用绘图的结果plot(Q,P)
但我不知道如何最好地找到适合某些实验数据的方法。理想情况下,我想使用优化工具箱和 lsqcurvefit,因为这样我也可以优化 R 和 L 参数。但我不知道如何将(x,y)数据传递给 lsqcurvefit。我已经尝试使用下面的代码,但它不起作用
File = 30; % the specific observation you want to fit the model to
ydata = DataFiles{1,File}.data(:,2)';
% RAdius = linspace(10,1000,length(ydata));
% LEngth = linspace(100,10000,length(ydata));
Multiplier = linspace(1e-3,1e3,length(ydata));
Constant = linspace(0,1,length(ydata));
xdata = [Multiplier; Constant]; % RAdius; LEngth;
L = lsqcurvefit(@RodFit,[1;0],xdata,ydata);
它给了我错误信息:
Error using *
Inner matrix dimensions must agree.
Error in RodFit (line 15)
P = (integral(fun,0,pi/2,'ArrayValued',true))*k+C;
Error in lsqcurvefit (line 199)
initVals.F = feval(funfcn_x_xdata{3},xCurrent,XDATA,varargin{:});
Caused by:
Failure in initial user-supplied objective function evaluation. LSQCURVEFIT cannot continue.
我尝试过 i) 使所有向量/矩阵的长度相同,并且 ii) 尝试.*
改用。没有任何效果,我给出了同样的错误信息
任何形式的帮助都将不胜感激,无论是关于应该使用什么方法的建议,对我的代码的建议还是第三点。
编辑回答 Osmoses: 一个非常好的观点,但我不认为这是问题所在。刚刚检查了所有向量/矩阵的大小,它们应该没问题
>> size(Q)
ans =
1 1780
>> size(P)
ans =
1 1780
>> size(xdata)
ans =
2 1780
>> size([1;0.001]) - the initial guess/start point for xdata (x0)
ans =
2 1
>> size(ydata)
ans =
1 1780
更新
我想我已经确定了问题所在。当我直接指定输入时,RodFit 函数可以正常工作,例如[Q,P] = RodFit(1,0.001);
。
但是,如果我将 x0 定义为x0 = [1,0.001]
我无法将 x0 传递给函数
>> x0 = [1;0.001]
x0 =
1.0000
0.0010
>> RodFit(x0);
Error using *
Inner matrix dimensions must agree.
Error in RodFit (line 15)
P = (integral(fun,0,pi/2,'ArrayValued',true))*k+C;
如果我x0 = [1,0.001]
清楚地使用,也会发生同样的情况,matlab 仅将 x0 解释为输入,k
并尝试多重播放长度(ydata)的向量和长度(x0)的向量,这显然失败了。
所以我的问题是我需要编写代码,以便lsqcurvefit了解 xdata 和 x0 的第一列是k
变量,而 xdata 和 x0 的第二列是C
变量。根据文档 -传递矩阵参数- 我应该能够将 x0 作为矩阵传递给求解器。然后,求解器还应该以与 x0 相同的格式传递 xdata。