Package obitools :: Package statistics :: Module noncentralhypergeo
[hide private]
[frames] | no frames]

Source Code for Module obitools.statistics.noncentralhypergeo

  1  from decimal import * 
  2  from math import log 
  3   
  4  #from obitools.utils import moduleInDevelopment 
  5   
  6  #moduleInDevelopment(__name__) 
  7   
  8  # from : http://www.programmish.com/?p=25 
  9   
10 -def dec_log(self, base=10):
11 cur_prec = getcontext().prec 12 getcontext().prec += 2 13 baseDec = Decimal(10) 14 retValue = self 15 16 if isinstance(base, Decimal): 17 baseDec = base 18 elif isinstance(base, float): 19 baseDec = Decimal("%f" % (base)) 20 else: 21 baseDec = Decimal(base) 22 23 integer_part = Decimal(0) 24 while retValue < 1: 25 integer_part = integer_part - 1 26 retValue = retValue * baseDec 27 while retValue >= baseDec: 28 integer_part = integer_part + 1 29 retValue = retValue / baseDec 30 31 retValue = retValue ** 10 32 decimal_frac = Decimal(0) 33 partial_part = Decimal(1) 34 while cur_prec > 0: 35 partial_part = partial_part / Decimal(10) 36 digit = Decimal(0) 37 while retValue >= baseDec: 38 digit += 1 39 retValue = retValue / baseDec 40 decimal_frac = decimal_frac + digit * partial_part 41 retValue = retValue ** 10 42 cur_prec -= 1 43 getcontext().prec -= 2 44 45 return integer_part + decimal_frac
46
47 -class Interval(object):
48 - def __init__(self,begin,end,facteur=1):
49 self._begin = begin 50 self._end = end 51 self._facteur=facteur
52
53 - def __str__(self):
54 return '[%d,%d] ^ %d' % (self._begin,self._end,self._facteur)
55
56 - def __repr__(self):
57 return 'Interval(%d,%d,%d)' % (self._begin,self._end,self._facteur)
58
59 - def begin(self):
60 return (self._begin,self._facteur,True)
61
62 - def end(self):
63 return (self._end,-self._facteur,False)
64 65
66 -def cmpb(i1,i2):
67 x= cmp(i1[0],i2[0]) 68 if x==0: 69 x = cmp(i2[2],i1[2]) 70 return x
71
72 -class Product(object):
73 - def __init__(self,i=None):
74 if i is not None: 75 self.prod=[i] 76 else: 77 self.prod=[] 78 self._simplify()
79
80 - def _simplify(self):
81 bornes=[] 82 prod =[] 83 84 if self.prod: 85 86 for i in self.prod: 87 bornes.append(i.begin()) 88 bornes.append(i.end()) 89 bornes.sort(cmpb) 90 91 92 j=0 93 r=len(bornes) 94 for i in xrange(1,len(bornes)): 95 if bornes[i][0]==bornes[j][0] and bornes[i][2]==bornes[j][2]: 96 bornes[j]=(bornes[j][0],bornes[j][1]+bornes[i][1],bornes[i][2]) 97 r-=1 98 else: 99 j+=1 100 bornes[j]=bornes[i] 101 102 bornes=bornes[0:r] 103 104 facteur=0 105 close=1 106 107 for b,level,open in bornes: 108 if not open: 109 close=0 110 else: 111 close=1 112 if facteur: 113 prod.append(Interval(debut,b-close,facteur)) 114 debut=b+1-close 115 facteur+=level 116 117 self.prod=prod
118 119 120 121
122 - def __mul__(self,p):
123 res = Product() 124 res.prod=list(self.prod) 125 res.prod.extend(p.prod) 126 res._simplify() 127 return res
128
129 - def __div__(self,p):
130 np = Product() 131 np.prod = [Interval(x._begin,x._end,-x._facteur) for x in p.prod] 132 return self * np
133
134 - def __str__(self):
135 return str(self.prod)
136
137 - def log(self):
138 p=Decimal(0) 139 for k in self.prod: 140 p+= Decimal(k._facteur) * reduce(lambda x,y:x+dec_log(Decimal(y),Decimal(10)),xrange(k._begin,k._end+1),Decimal(0)) 141 return p
142
143 - def product(self):
144 p=Decimal(1) 145 for k in self.prod: 146 p*= reduce(lambda x,y:x*Decimal(y),xrange(k._begin,k._end+1),Decimal(1)) ** Decimal(k._facteur) 147 return p
148
149 - def __call__(self,log=True):
150 if log: 151 return self.log() 152 else: 153 return self.product()
154 155
156 -def fact(n):
157 return Product(Interval(1,n))
158
159 -def cnp(n,p):
160 return fact(n)/fact(p)/fact(n-p)
161
162 -def hypergeometic(x,n,M,N):
163 ''' 164 165 @param x: Variable aleatoire 166 @type x: int 167 @param n: taille du tirage 168 @type n: int 169 @param M: boule gagnante 170 @type M: int 171 @param N: nombre total dans l'urne 172 @type N: int 173 174 p(x)= cnp(M,x) * cnp(N-M,n-x) / cnp(N,n) 175 ''' 176 return cnp(M,x) * cnp(N-M,n-x) / cnp(N,n)
177
178 -def nchypergeometique(x,n,M,N,r):
179 ''' 180 181 @param x: Variable aleatoire 182 @type x: int 183 @param n: taille du tirage 184 @type n: int 185 @param M: boule gagnante 186 @type M: int 187 @param N: nombre total dans l'urne 188 @type N: int 189 @param r: odd ratio 190 @type r: float 191 192 p(x)= cnp(M,x) * cnp(N-M,n-x) / cnp(N,n) 193 ''' 194 195 xmin = max(0,n-N+M) 196 xmax = min(n,M) 197 lr = dec_log(r) 198 xlr = x * lr 199 num = cnp(M,x) * cnp(N-M,n-x) 200 den = [cnp(M,y) * cnp(N-M,n-y) / num for y in xrange(xmin,xmax+1)] 201 fden = [lr * y - xlr for y in xrange(xmin,xmax+1)] 202 203 inverse=reduce(lambda x,y : x+y, 204 map(lambda i,j: i(False) * 10**j ,den,fden)) 205 return 1/inverse
206