首页 文章

在MATLAB中涉及积分的曲线拟合方程

提问于
浏览
2

我有一个方程式,我试图适应一些实验数据 . 在过去,我使用了 lsqcurvefit 并传入了实验数据,以及描述我的拟合数据的函数 . 例如 .

model = @(p,x) exp(-p(1).*x);
startingVals = 0.5;
lsqcurvefit(model,startingVals,expData_x,exptData_y)

这将与MATLAB完美匹配,返回最符合我数据的 p 的值 . 在内部,我猜它正在调整 p 的值,这是一种最小化差值平方和的智能方法 .

现在我有一个不具分析性的模型,想要找到最接近的拟合 B . 一个例子是:

model = integral(@(v)besselj(0,x.*v.*B), 0, 40);

(只是一个例子,也许它可以解析地解决,但我的一个肯定不能解决) .

因此,为了计算我放入 B 的试用版的模型,它计算每个 x 的函数 . 到目前为止,我一直在做的是为一系列试验计算模型,例如 B = 1:1:10 . 这将给我10个向量,每个向量具有不同的模型点集 . 然后我会运行脚本,找到每个模型计算中减去实验数据的最小残差 .

这似乎工作正常,但现在我正在使用一个以上的拟合项 . 例如

model = integral(@(v)(C.*D).*besselj(0,x.*v.*B).^(E), 0, 40);

我现在可能想要找到 B, C, D and E 的最佳拟合值 . 我的方法仍然可行,但会产生大量的实验性试验,例如循环通过10个值,每个生成10,000个单独的曲线 .

我的方法是否正常,或者我错过了更简单的方法来适应这些功能?

谢谢

edit: Working code thanks to David.

请注意,有时 lsqcurvefit 会返回复杂的数字,但这是另一个问题 . 显然,真实的数据不是一个完美的契合,但我不知道你可以将这些功能传递给lsqcurvefit .

A = 0.2; %input variables to 'solve' for later
B = 0.3;
C = 0.4;
D = 0.5;
x = logspace(-2,2,200); %x data

options = optimset('MaxFunEvals', 200,'MaxIter', 200,'TolFun',1e-10,'Display','off');

genData = arrayfun(@(x) integral(@(v) A.*B.*besselj(0,x.*v.*C).^D, 0, 40),x); %generate some data
genData = real(genData); 

model = @(p,x) real(arrayfun(@(x) integral(@(v) p(1).*p(2).*besselj(0,x.*v.*p(3)).^p(4), 0, 40),x)); 

startingVals = [0.5 0.5 0.5 0.5]; %guess values
lb = [0.1 0.1 0.1 0.1]; %lower bound
ub = [1 1 1 1]; %upper bound

[p] = lsqcurvefit(model,startingVals,x,genData,lb,ub,options); %do the fit, takes a while

fitData = real(arrayfun(@(x) integral(@(v) p(1).*p(2).*besselj(0,x.*v.*p(3)).^p(4), 0, 40),x)); %regenrate data based on fitted values

semilogx(x,genData,'ro')
hold on
semilogx(x,fitData,'b')

1 回答

  • 3

    这应该让 lsqcurvefit 能够在 model 上工作:

    model=@(p,x) arrayfun(@(x) integral(@(v) p(1).*p(2).*besselj(0,x.*v.*p(3)).^p(4), 0, 40),x);
    

    但是我编造了一些系数 BCDE 并且性能不确定是不是因为我选择了不好的数字或是否是一个慢速的方法 .

相关问题