1 | from math import * |
---|
2 | from random import * |
---|
3 | |
---|
4 | # function x=randht(n, varargin) |
---|
5 | |
---|
6 | # RANDHT generates n observations distributed as some continous heavy- |
---|
7 | # tailed distribution. Options are power law, log-normal, stretched |
---|
8 | # exponential, power law with cutoff, and exponential. Can specify lower |
---|
9 | # cutoff, if desired. |
---|
10 | # |
---|
11 | # Example: |
---|
12 | # x = randht(10000,'powerlaw',alpha); |
---|
13 | # x = randht(10000,'xmin',xmin,'powerlaw',alpha); |
---|
14 | # x = randht(10000,'cutoff',alpha, lambda); |
---|
15 | # x = randht(10000,'exponential',lambda); |
---|
16 | # x = randht(10000,'lognormal',mu,sigma); |
---|
17 | # x = randht(10000,'stretched',lambda,beta); |
---|
18 | # |
---|
19 | # See also PLFIT, PLVAR, PLPVA |
---|
20 | # |
---|
21 | # Source: http://www.santafe.edu/~aaronc/powerlaws/ |
---|
22 | |
---|
23 | |
---|
24 | # Version 1.0.2 (2008 April) |
---|
25 | # Copyright (C) 2007 Aaron Clauset (Santa Fe Institute) |
---|
26 | |
---|
27 | # Ported to python by Joel Ornstein (2011 August) |
---|
28 | # (joel_ornstein@hmc.edu) |
---|
29 | |
---|
30 | # Distributed under GPL 2.0 |
---|
31 | # http://www.gnu.org/copyleft/gpl.html |
---|
32 | # RANDHT comes with ABSOLUTELY NO WARRANTY |
---|
33 | # |
---|
34 | # Notes: |
---|
35 | # |
---|
36 | def randht(n,*varargin): |
---|
37 | Type = ''; |
---|
38 | xmin = 1; |
---|
39 | alpha = 2.5; |
---|
40 | beta = 1; |
---|
41 | Lambda = 1; |
---|
42 | mu = 1; |
---|
43 | sigma = 1; |
---|
44 | |
---|
45 | |
---|
46 | # parse command-line parameters; trap for bad input |
---|
47 | i=0; |
---|
48 | while i<len(varargin): |
---|
49 | argok = 1; |
---|
50 | if type(varargin[i])==str: |
---|
51 | if varargin[i] == 'xmin': |
---|
52 | xmin = varargin[i+1] |
---|
53 | i = i + 1 |
---|
54 | elif varargin[i] == 'powerlaw': |
---|
55 | Type = 'PL' |
---|
56 | alpha = varargin[i+1] |
---|
57 | i = i + 1 |
---|
58 | elif varargin[i] == 'cutoff': |
---|
59 | Type = 'PC'; |
---|
60 | alpha = varargin[i+1] |
---|
61 | Lambda = varargin[i+2] |
---|
62 | i = i + 2 |
---|
63 | elif varargin[i] == 'exponential': |
---|
64 | Type = 'EX' |
---|
65 | Lambda = varargin[i+1] |
---|
66 | i = i + 1 |
---|
67 | elif varargin[i] == 'lognormal': |
---|
68 | Type = 'LN'; |
---|
69 | mu = varargin[i+1] |
---|
70 | sigma = varargin[i+2] |
---|
71 | i = i + 2 |
---|
72 | elif varargin[i] == 'stretched': |
---|
73 | Type = 'ST' |
---|
74 | Lambda = varargin[i+1] |
---|
75 | beta = varargin[i+2] |
---|
76 | i = i + 2 |
---|
77 | else: argok=0 |
---|
78 | |
---|
79 | |
---|
80 | if not argok: |
---|
81 | print '(RANDHT) Ignoring invalid argument #' ,i+1 |
---|
82 | |
---|
83 | i = i+1 |
---|
84 | |
---|
85 | if n<1: |
---|
86 | print '(RANDHT) Error: invalid ''n'' argument; using default.\n' |
---|
87 | n = 10000; |
---|
88 | |
---|
89 | if xmin < 1: |
---|
90 | print '(RANDHT) Error: invalid ''xmin'' argument; using default.\n' |
---|
91 | xmin = 1; |
---|
92 | |
---|
93 | |
---|
94 | |
---|
95 | |
---|
96 | x=[] |
---|
97 | if Type == 'EX': |
---|
98 | x=[] |
---|
99 | for i in range(n): |
---|
100 | x.append(xmin - (1./Lambda)*log(1-random())) |
---|
101 | elif Type == 'LN': |
---|
102 | y=[] |
---|
103 | for i in range(10*n): |
---|
104 | y.append(exp(mu+sigma*normalvariate(0,1))) |
---|
105 | |
---|
106 | while True: |
---|
107 | y= filter(lambda X:X>=xmin,y) |
---|
108 | q = len(y)-n; |
---|
109 | if q==0: break |
---|
110 | |
---|
111 | if q>0: |
---|
112 | r = range(len(y)); |
---|
113 | shuffle(r) |
---|
114 | ytemp = [] |
---|
115 | for j in range(len(y)): |
---|
116 | if j not in r[0:q]: |
---|
117 | ytemp.append(y[j]) |
---|
118 | y=ytemp |
---|
119 | break |
---|
120 | if (q<0): |
---|
121 | for j in range(10*n): |
---|
122 | y.append(exp(mu+sigma*normalvariate(0,1))) |
---|
123 | |
---|
124 | x = y |
---|
125 | |
---|
126 | elif Type =='ST': |
---|
127 | x=[] |
---|
128 | for i in range(n): |
---|
129 | x.append(pow(pow(xmin,beta) - (1./Lambda)*log(1.-random()),(1./beta))) |
---|
130 | elif Type == 'PC': |
---|
131 | |
---|
132 | x = [] |
---|
133 | y=[] |
---|
134 | for i in range(10*n): |
---|
135 | y.append(xmin - (1./Lambda)*log(1.-random())) |
---|
136 | while True: |
---|
137 | ytemp=[] |
---|
138 | for i in range(10*n): |
---|
139 | if random()<pow(y[i]/float(xmin),-alpha):ytemp.append(y[i]) |
---|
140 | y = ytemp |
---|
141 | x = x+y |
---|
142 | q = len(x)-n |
---|
143 | if q==0: break; |
---|
144 | |
---|
145 | if (q>0): |
---|
146 | r = range(len(x)) |
---|
147 | shuffle(r) |
---|
148 | |
---|
149 | xtemp = [] |
---|
150 | for j in range(len(x)): |
---|
151 | if j not in r[0:q]: |
---|
152 | xtemp.append(x[j]) |
---|
153 | x=xtemp |
---|
154 | break; |
---|
155 | |
---|
156 | if (q<0): |
---|
157 | y=[] |
---|
158 | for j in range(10*n): |
---|
159 | y.append(xmin - (1./Lambda)*log(1.-random())) |
---|
160 | |
---|
161 | |
---|
162 | else: |
---|
163 | x=[] |
---|
164 | for i in range(n): |
---|
165 | x.append(xmin*pow(1.-random(),-1./(alpha-1.))) |
---|
166 | |
---|
167 | return x |
---|
168 | |
---|
169 | |
---|