将上限拟合为一组点

时间:2015-03-05 23:21:29

标签: matlab

我有以下关于Gauss circle problem的代码,它找到圆的晶格点数,半径R的变化和它们的面积之间的误差。然后,它绘制了R对错误的图表。

  %LatticeError plots graph of error between the lattice points in a circle of radius R and pi R^2, against R. 
R = 0:0.5:500;
  %Calculates the area of each circle
Area = pi .* (R.^2);
  %Creates an array of the number of points contained in each circle
LatticePts = arrayfun(@lattice,R); 
Error = abs(LatticePts - Area);
plot(R,Error)

我希望能够使用Matlab来近似函数, f(R)= a *(R ^ b),这是上限在R的范围内出现错误但是我不知道怎么做,有什么想法?

1 个答案:

答案 0 :(得分:2)

在给定的一组点(xi,yi)上放置y = ax ^ b形式的曲线等于在集合上放置一条线(log(xi),log(yi)),因为幂函数变为对数 - 对数刻度线性。

convhull应用于(log(xi),log(yi))的集合,给出了这些点的凸包。该凸包的任何边缘都给出了与数据集紧密配合的线。严格地说,这些中没有“最佳”线,但选择一个在值范围中间最低的值(即R = 250左右)是合理的。这就是我在下面所做的。为了完整起见,我在开头包括了格点数的计算。

错误计算

Radius = [];
Error = [];
for R = 0.5:0.5:500;
    Area = pi*R^2;
    n = floor(R);
    x = -n:n;
    y = -n:n;
    [X,Y] = meshgrid(x,y);
    LatticePts = nnz(X.^2+Y.^2<=R^2);
    Radius = [Radius, R];
    Error = [Error, max(1,abs(LatticePts - Area))];
end

最大值为1的原因是避免出现零或接近零的对数问题。

对数船体对数日志

ind = convhull(log(Radius), log(Error));

这给出了逆时针列出的极值点的指数。这实际上是与我想要的顺序相反的顺序:它从下限开始,这是无趣的。顶部的那些位于列表的末尾,所以我从头开始搜索它:

凸包的一侧躺在R = 250:

i = numel(ind);
while (Radius(ind(i))<250)
    i = i-1;
end

计算a,b和输出

R1 = Radius(ind(i));
E1 = Error(ind(i));
R2 = Radius(ind(i+1));
E2 = Error(ind(i+1));
b = log(E1/E2)/log(R1/R2);
a = E1/R1^b;
plot(Radius, Error, '.');
hold on
plot(Radius, a*Radius.^b , 'r-');
hold off
fprintf('a = %.3f, b = %.3f\n', a,b);

我得到了= 3.219,b = 0.617。这是情节:

gauss