zoukankan      html  css  js  c++  java
  • 每日一程-10.五种基本随机数测试-续

    Author: Notus(hehe_xiao@qq.com)
    Create: 2019-02-17
    Update: 2019-02-17

    随机数测试-续:Frequencey test(monobit test), Serial test(two-bit test), Poker test and Runs test

    环境

    Python version: 3.7.1

    代码如下(PseudorandomTest.py)

    '''
    	Pseudorandom Sequences Tests: 
    		1. Frequency test (monobit test)
    		2. Serial test (two-bit test)
    		3. Poker test
    		4. Runs test
    		5. Autocorrelation test
    	@Author: Notus(hehe_xiao@qq.com)
    	@Create: 2019-02-15
    	@Update: 2019-02-17
    '''
    
    # 1. Frequency test(monobit test)
    def monobitTest(num):
    	n = len(num)
    	n0 = num.count('0')
    	n1 = num.count('1')
    	X = (n0 - n1) ** 2 / n
    	return n, n0, n1, X
    
    # 2. Serial test(two-bit test)
    def serialTest(num):
    	n = len(num)
    	n0 = num.count('0')
    	n1 = num.count('1')
    	n00 = n01 = n10 = n11 = 0
    
    	for i in range(0, n-1):
    		i0 = num[i]
    		i1 = num[i+1]
    		if i0 == '0':
    			if i1 == '0': 
    				n00 += 1
    			else: 
    				n01 += 1
    		else:
    			if i1 == '0': 
    				n10 += 1
    			else: 
    				n11 += 1
    		i += 1
    
    	X = 4 * (n00**2 + n01**2 + n10**2 + n11**2) / (n-1) - 2 * (n0**2 + n1**2) / n + 1
    	return n, n00, n01, n10, n11, X	
    
    
    # 3. Poker test
    def pokerTest(num, m):
    	n = len(num)
    	k = n // m
    	if k < 5 * (2 ** m):
    		raise ValueError("Error: the value of m is invalid for Poker Test!")
    
    	# ni count list, 0 <= i <= 2**m - 1
    	ni_list = [0] * (2 ** m)
    
    	# counting 	
    	for b in range(0, n-m, m):
    		index = 0
    		for c in range(m):
    			index = index * 2 + int(num[b + c])
    		ni_list[index] += 1
    
    	s = 0
    	for i in range(1, 2**m + 1):
    		s += ni_list[i - 1] ** 2
    
    	X = (2 ** m) * s / k - k
    	return k, ni_list, X
    
    
    # 4. Runs test
    def runsTest(num):
    	n = len(num)
    	e = {}
    	for i in range(1, n + 3):
    		e_i = (n - i + 3) / (2 ** (i + 2))
    		if e_i >= 5:
    			e[i] = e_i
    	k = max(e.keys())
    	B = [0] * k
    	G = [0] * k
    	
    	def countBG(bit, runLength):
    		counts = 0
    		contNumbs = 0				# continuous number counts
    		for idx in range(n):
    			if num[idx] != bit: 
    				if contNumbs == runLength:
    					counts += 1
    				contNumbs = 0
    				continue
    
    			contNumbs += 1
    
    			# last block or gap
    			if contNumbs == runLength and idx == n - 1: 
    				counts += 1 
    		return counts
    
    	for i in range(k):
    		B[i] = countBG('1', i + 1)
    		G[i] = countBG('0', i + 1)
    
    	x1 = x2 = 0
    	for i in range(1, k + 1):
    		x1 += (B[i-1] - e[i]) ** 2 / e[i]
    		x2 += (G[i-1] - e[i]) ** 2 / e[i]
    	X = x1 + x2
    
    	return e, k, B, G, X
    
    # 5. Autocorrelation test
    # Todo
    
    if __name__ == '__main__':
    	num = ('11100' + '01100' + '01000' + '10100' + '11101' + '11100' + '10010' + '01001') * 4
    	
    	x1 = monobitTest(num)
    	print("frequency test: 
    n = {}, n0 = {}, n1 = {}, 
    X1 = {}
    ".format(*x1))
    
    	x2 = serialTest(num)
    	print("serial test: 
    n = {}, n00 = {}, n01 = {}, n10 = {}, n11 = {}, 
    X2 = {}
    ".format(*x2))
    
    	try:
    		x3 = pokerTest(num, 3)
    	except ValueError as err:
    		print(err.args[0])
    		sys.exit()
    	print("poker test: 
    k = {}, ni_list = {} 
    X3 = {}
    ".format(*x3))
    	
    	x4 = runsTest(num)
    	print("runs test: 
    e = {}, k = {}, B = {}, G = {} 
    X4 = {}".format(*x4))
    
    

    运行结果

    python PseudorandomTest.py
    frequency test:
    n = 160, n0 = 84, n1 = 76,
    X1 = 0.4
    
    serial test:
    n = 160, n00 = 44, n01 = 40, n10 = 40, n11 = 35,
    X2 = 0.6251572327043959
    
    poker test:
    k = 53, ni_list = [5, 10, 6, 4, 12, 3, 6, 7]
    X3 = 9.641509433962263
    
    runs test:
    e = {1: 20.25, 2: 10.0625, 3: 5.0}, k = 3, B = [25, 4, 5], G = [8, 20, 12]
    X4 = 31.791306264856992
    
  • 相关阅读:
    关于python urlopen 一个类似radio流的timeout方法
    Python nltk English Detection
    Python依赖打包发布详细
    python 怎么和命令行交互
    Python中多维数组flatten的技巧
    Python中的url编码问题
    python数据持久存储:pickle模块的基本使用
    Python控制台输出不换行(进度条等)
    UnicodeEncodeError: 'ascii' codec can't encode character u'xe9' in position 7: ordinal not in range(128) [duplicate]
    json.loads(s) returns error message like this: ValueError: Invalid control character at: line 1 column 33 (char 33)
  • 原文地址:https://www.cnblogs.com/leo1875/p/10389966.html
Copyright © 2011-2022 走看看