Saturday, October 3, 2009

sin(1/x)的内里乾坤

在学习微积分的时候,大多数教程都会给出 y=sin(1/x),作为不连续函数的例子。这个函数的草图很容易画,大多数教程上也会有这么一个图,
x=-1:.0011:1;
y = sin(1./x);
plot(x,y,'-b');




从这图上看不出什么模式出来,然而,如果用散点图,
x=-1:.0011:1;
y = sin(1./x);
plot(x,y,'.r');
则如下图,

在散点图中似乎存在着某种规律和模式。

我们继续用下面的代码来仔细看看,

% this program show some interesting patterns hidden in the "randomness" of
% sin(1/x) near zero.

n=1:4000;
x = 1./n; % range of x is [.00025 1];
y = sin(n);
plot(x,y,'.b');
legend('x=1/n y=sin(n) n=1:4000','Location','NorthOutside');
legend boxoff;

这个图显然不太合理,因为大多数点都被压缩到很窄小的区域,而居中广阔的区域却只有少数几个点享用。因此,我们需要调整x轴的分辨率和定义范围。

如何调整?
我们可以用histgram函数来看看数据定义域的直方图,由此可以大概知道数据的分布情况。
用简单命令,
N =hist(x)

N =

3991 5 1 1 1 0 0 0 0 1

可以看出,x在[0,0.1]这个区间内,有3991个点!
而在[0.1,1.0]这个区间内只有9个点!
可见分布的极其不均匀。

因此,为了让“镜头”对准“大多数”,我们需要调整“镜头”的取向和焦距了。
这可以由命令
axis([xmin xmax ymin ymax]);
来调节。

我们先试着用
axis([0.0 .1 -1 1]);
得到的结果是这样的,

说明镜头对准的是少数的“权贵阶级”,仍未对准“沉默的大多数”,
实际上,用
xx= x(find(x<.1));hist(xx) 可以看出,在此区间内,分布极其不均匀, 此时的直方图如下,


















继续尝试,xx= x(find(x<.01));hist(xx) 发现此时分布有些好了,起码能看出点梯度来。


















此时的散点图如下,已能看出一些模式,但是大多数点仍偏居一隅!







再继续尝试,xx= x(find(x<.003));hist(xx),

这时效果更为理想,有些接近正态分布了。 此时的散点图如下,





最后尝试,xx= x(find(x<.001));hist(xx), 这时效果更为理想,更接近正态分布了。

此时的散点图如下,



所以我们最终决定采取x显示区间为[.0002, .001],认为此时的效果最好。


从某种意义上,这是matlab的一个小小缺陷。因为axis auto并不能为我们选取一个适当的尺度来发现数据中隐藏的pattern,或许上面的分析能够改进这个功能的设计。

我们的观点是,合适的尺度应该让图中的主要点表现为类正态分布,如此,则人能够更好的把握数据中的pattern.

No comments: