对于视觉实验,我需要确定人们在出现不同对比刺激时的最低性能阈值。 matlab指南提供了一个非常有用且随时可用的脚本,用于使用以下代码对采集的数据进行数据拟合:
xdata = ...
[0.8 1.27 2.19 3.39 5.03 7.75 12.02 19.27 29.83];
ydata = ...
[52.78 50 66.67 75 69.44 86.11 80.56 75 86.11];
fun = @(x)x(1)*exp(x(2)*xdata)-ydata;
x0 = [100,-1];
options = optimoptions(@lsqnonlin,'Algorithm','trust-region-reflective');
x = lsqnonlin(fun,x0,[],[],options)
plot(xdata,ydata,'ko')
hold on
tlist = linspace(xdata(1),xdata(end));
plot(tlist,x(1)*exp(x(2)*tlist),'b-')
xlabel PercentContrast
ylabel PercentCorrect
title('Exponential Fit to Data')
legend('Data','Exponential Fit')
hold off
这将产生以下图片: Data-fitting example 1
现在我想确定75%的阈值。理想情况下,我会在y轴上创建一条75行,然后确定绘制的数据曲线与此线相交的位置。不幸的是,当我尝试使用linspace命令创建这样一行时,并尝试在现有代码中实现它:
hold on
thr = linspace(0,30);
tlist = linspace(xdata(1),xdata(end));
plot(tlist,x(1)*exp(x(2)*tlist),'b-',thr)
xlabel xdata
ylabel ydata
title('Exponential Fit to Data')
legend('Data','Exponential Fit')
hold off
结果是一个错误,我似乎无法弄清楚如何或在哪里实现该行并确定相交。 注意:我无法访问Matlab的曲线拟合工具箱。
答案 0 :(得分:0)
ax = axis(); %gets axis bounds xmin, xmax, ymin, ymax
hold on;
plot([ax(1),ax(2)],[75,75]);
有几种方法可以做到这一点。一种方法是使用图来直观地估计两条线之间的交点。
最准确的解决方案是注意到你有一个可逆的封闭形式功能。
invf = @(t) log(t/x(1))/x(2);
使用您的代码生成的x
,我们可以找到invf(75)
,原来是
>> invf(75)
ans = 14.0534
或者,您可以以编程方式搜索tlist
和x(1)*exp(x(2)*tlist)
定义的曲线,以查找tlist
中的参数,使我们的拟合函数最接近75.即查找t
在tlist
中,abs(x(1)*exp(x(2)*t) - 75)
最小化。
>> [~,tidx] = min(abs(x(1)*exp(x(2)*tlist) - 75));
>> t = tlist(tidx)
t = 13.9955
即使拟合函数不可逆,最后一种方法也能正常工作。