Tuesday, April 12, 2011

Kolmogorov 0-1 Law

    对于一个无穷随机序列{Xi},关于它的一个尾事件(tail event),发生的概率要么是0,要么是1,没有中间状态。
    那么,什么事尾事件呢?其标准定义可以参考Wikipedia:http://en.wikipedia.org/wiki/Kolmogorov_0-1_law。它定义在整个序列上,该事件和任意有限个随机变量之间独立,也就是说,该事件和任意有限个元素之间都是无关的,只存在于无穷随机序列的“尾巴”上。
    尾事件揭示了现代概率论的一个重要事实,尽管一个随机序列本身是捉摸不定的,但它的长期表现却是确定的。
    与Kolmogorov 0-1律相关的还有Hewitt-Savage 0-1 律:http://en.wikipedia.org/wiki/Hewitt%E2%80%93Savage_zero-one_law。说明的也是同一事实。

Saturday, April 2, 2011

一个Python引用引起的困惑

先来看一段程序:
funs = [lambda x: x**k for k in range(0, 4)]
res = [f(2) for f in funs]
print res
结果是什么呢?
结果是这样的:[8, 8, 8, 8],如果不感到意外,说明你已经理解了python,或者没看懂:)
如果意外,请看下面的分析:
实际上,[lambda x: x**k for k in range(0, 4)],创建了4个lambda表达式,每个表达式都是
lambda x: x**k,而k最终是等于3。于是4个lambda表达式都是lambda x: x**3 !
怎样才能根据不同的k生成不同的表达式呢?原因是要对k生成多个对象!!
函数的参数是作为引用传入的,因此我们可以对lambda表达式增加一个参数,k:
funs = [lambda x, k=k: x**k for k in range(0, 4)]
重新运行程序,得到res的值为
[1, 2, 4, 8]!
神奇的python!
如果你是一个python程序员,不清楚python的引用机制,你将时常困惑。

Thursday, March 31, 2011

Python中使用pickle对内建类型(built in types)进行对象序列化(object serialization and deseirialzation)

有对象要持久化,就离不开序列化和反序列化。对象是立体的,而存储却是现行的,因此叫序列化。
比如我们构造一个python对象:
d = {'coffee': 1, 'tea': 2, 'water': 3}
这是一个字典。
进行序列化的操作:
f = open('favorite.dict', 'wb')
import pickle
pickle.dump(d, f)
f.close()
进行反序列化操作:
f = open('favorite.dict', 'rb')
d = pickle.load(f)
print str(d)
是不是很容易呢?

Wednesday, March 30, 2011

Python中的可改写类型与不可改写类型 (mutable and immutable types in python)

Python的内建类型分为两种:一种是不可改写类型,另一种是可改写类型。
Python的变量是一个引用,其所指对象的类型及内容信息完全存储在对象本身,而不存储在变量上。
不可改写类型包括bool, int, float, string, tuple,这些类型的特点是一旦被赋值,无法在对象上就地(in place)修改对象的内容。如果要改写变量所指对象的内容,则必须新建一个对象,使新的对象具有需要的值,再将这个对象赋给变量。变量原先所指的对象的引用计数减1。可改写性是对象的内在属性,你无法通过任何方法就地改写对象本身。

s = 'abcd'
s[0] = 'd'
以上句子非法,原因是s是不可改写类型,无法就地修改其所引用字符串的内容。
可改写对象包括list, dictionary, set。这些类型可以包含任意同构或异构(同构是异构的一种特例)的对象。对list等类型的对象可以进行就地操作,比如改写list中的一个元素。而元素本身是否可改写,则取决于元素本身所属的类型,如此递归。

l = [1, 2, 3, 4]
l[0] = 3
以上句子合法,原因是l是可改写类型。

Saturday, March 26, 2011

介绍基于云的研究利器——WolframAlpha.com

今天在研究一个函数的性质,期间需要积分一个函数1/(1+t^2)。而我忘记了积分公式,不过这没关系,当你需要算积分时,也不需要求助于收费的Mathematica软件。你只需要打开
http://www.wolframalpha.com/
网站,输入:
integrate 1/(1+t^2) dt,即可得到
http://www.wolframalpha.com/input/?i=integrate+1%2F%281%2Bt^2%29+dt
得到不定积分函数为atan(t)。
这是不是很容易呢?

Thursday, March 24, 2011

UNIX文件系统Cache机制

UNIX利用Cache来提高文件访问的速度,几乎无处不在,应当在使用中引起我们的注意,或许,你测量的机器性能就包括Cache的贡献呢!
UNIX把文件划分为一个个数据块,每一个数据块叫做一个Block。内核为每一个Block创建了唯一的一个buffer与之对应。
Buffer被内核按照数据块的编号散列在一个Hash表中,通过该Hash表,内核可以快速查找用户程序所需要的block。
处于空闲、busy、delayed to write状态的block除了会被放在hash表中,还会被放在一个叫做free block list的链表中,以便于程序方便的get和put block buffer。
当用户程序读取一个block时,首先会去hash表中查找该block是否已经有buffer,如果有,则直接从该buffer中读取数据。此时,减少了一次从物理硬盘中读取数据的操作,从而提高了速度。当该数据不在buffer中,则从free buffer list中获取一个buffer,然后调用硬盘驱动程序从物理硬盘中读取数据,填充到buffer中,供前述的用户程序读取。
在写入时,用户数据先写入到buffer中。然后有三种可能:被同步写入物理硬盘,被异步写入物理硬盘,被延迟写入。前两者大家已经比较熟悉,延迟写入针对的是不就之后就有新的用户程序改写这块block的数据的情况,则减少相应的物理硬盘写入次数,从而提高速度。
block buffer在被使用(读取、写入)之后,会被置于free buffer list中。内容并不会被立刻清除。如果新的访问操作正好命中一个被释放的block,则从里面直接取出。否则,则按照last recently accessed (FIFO)的策略取出一个free buffer并访问它。