def comb(N,k,exact=0): """Combinations of N things taken k at a time. If exact==0, then floating point precision is used, otherwise exact long integer is computed. Notes: - Array arguments accepted only for exact=0 case. - If k > N, N < 0, or k < 0, then a 0 is returned. """ if exact: if (k > N) or (N < 0) or (k < 0): return 0L N,k = map(long,(N,k)) top = N val = 1L while (top > (N-k)): val *= top top -= 1 n = 1L while (n < k+1L): val /= n n += 1 return val else: k,N = asarray(k), asarray(N) lgam = special.gammaln cond = (k <= N) & (N >= 0) & (k >= 0) sv = special.errprint(0) vals = exp(lgam(N+1) - lgam(N-k+1) - lgam(k+1)) sv = special.errprint(sv) return where(cond, vals, 0.0)
def factorial(n,exact=0): """n! = special.gamma(n+1) If exact==0, then floating point precision is used, otherwise exact long integer is computed. Notes: - Array argument accepted only for exact=0 case. - If n<0, the return value is 0. """ if exact: if n < 0: return 0L n = long(n) val = 1L k = 1L while (k < n+1L): val = val*k k += 1 return val else: n = asarray(n) sv = special.errprint(0) vals = special.gamma(n+1) sv = special.errprint(sv) return where(n>=0,vals,0)
def irfft(x, n=None, axis=-1, overwrite_x=0): """ irfft(x, n=None, axis=-1, overwrite_x=0) -> y Return inverse discrete Fourier transform of real sequence x. The contents of x is interpreted as the output of rfft(..) function. The returned real array contains [y(0),y(1),...,y(n-1)] where for n is even y(j) = 1/n (sum[k=1..n/2-1] (x[2*k-1]+sqrt(-1)*x[2*k]) * exp(sqrt(-1)*j*k* 2*pi/n) + c.c. + x[0] + (-1)**(j) x[n-1]) and for n is odd y(j) = 1/n (sum[k=1..(n-1)/2] (x[2*k-1]+sqrt(-1)*x[2*k]) * exp(sqrt(-1)*j*k* 2*pi/n) + c.c. + x[0]) c.c. denotes complex conjugate of preceeding expression. Optional input: see rfft.__doc__ """ tmp = asarray(x) t = tmp.typecode() if t in 'DF': raise TypeError,"1st argument must be real sequence" work_function = fftpack.drfft return _raw_fft(tmp,n,axis,-1,overwrite_x,work_function)
def rfft(x, n=None, axis=-1, overwrite_x=0): """ rfft(x, n=None, axis=-1, overwrite_x=0) -> y Return discrete Fourier transform of real sequence x. The returned real arrays contains [y(0),Re(y(1)),Im(y(1)),...,Re(y(n/2))] if n is even [y(0),Re(y(1)),Im(y(1)),...,Re(y(n/2)),Im(y(n/2))] if n is odd where y(j) = sum[k=0..n-1] x[k] * exp(-sqrt(-1)*j*k* 2*pi/n) j = 0..n-1 Note that y(-j) = y(n-j). Optional input: n Defines the length of the Fourier transform. If n is not specified then n=x.shape[axis] is set. If n<x.shape[axis], x is truncated. If n>x.shape[axis], x is zero-padded. axis The transform is applied along the given axis of the input array (or the newly constructed array if n argument was used). overwrite_x If set to true, the contents of x can be destroyed. Notes: y == rfft(irfft(y)) within numerical accuracy. """ tmp = asarray(x) t = tmp.typecode() if t in 'DF': raise TypeError,"1st argument must be real sequence" work_function = fftpack.drfft return _raw_fft(tmp,n,axis,1,overwrite_x,work_function)
def factorial2(n,exact=0): """n!! = special.gamma(n/2+1)*2**((m+1)/2)/sqrt(pi) n odd = 2**(n) * n! n even If exact==0, then floating point precision is used, otherwise exact long integer is computed. Notes: - Array argument accepted only for exact=0 case. - If n<0, the return value is 0. """ if exact: if n < -1: return 0L if n <= 0: return 1L n = long(n) val = 1L k = n while (k > 0): val = val*k k -= 2 return val else: n = asarray(n) vals = zeros(n.shape,'d') cond1 = (n % 2) & (n >= -1) cond2 = (1-(n % 2)) & (n >= -1) oddn = extract(cond1,n) evenn = extract(cond2,n) nd2o = oddn / 2.0 nd2e = evenn / 2.0 insert(vals,cond1,special.gamma(nd2o+1)/sqrt(pi)*pow(2.0,nd2o+0.5)) insert(vals,cond2,special.gamma(nd2e+1) * pow(2.0,nd2e)) return vals
def ifftn(x, shape=None, axes=None, overwrite_x=0): """ ifftn(x, s=None, axes=None, overwrite_x=0) -> y Return inverse multi-dimensional discrete Fourier transform of arbitrary type sequence x. The returned array contains y[j_1,..,j_d] = 1/p * sum[k_1=0..n_1-1, ..., k_d=0..n_d-1] x[k_1,..,k_d] * prod[i=1..d] exp(sqrt(-1)*2*pi/n_i * j_i * k_i) where d = len(x.shape), n = x.shape, and p = prod[i=1..d] n_i. Optional input: see fftn.__doc__ """ tmp = asarray(x) t = tmp.typecode() if t=='D': overwrite_x = overwrite_x or (tmp is not x and not \ hasattr(x,'__array__')) work_function = fftpack.zfftnd elif t=='F': raise NotImplementedError else: overwrite_x = 1 work_function = fftpack.zfftnd return _raw_fftnd(tmp,shape,axes,-1,overwrite_x,work_function)
def imresize(arr,newsize,interp='bilinear',mode=None): newsize=list(newsize) newsize.reverse() newsize = tuple(newsize) arr = asarray(arr) func = {'nearest':0,'bilinear':2,'bicubic':3,'cubic':3} im = toimage(arr,mode=mode) im = im.resize(newsize,resample=func[interp]) return fromimage(im)
def _apply_func(x,g,func): # g is list of indices into x # separating x into different groups # func should be applied over the groups g = unique(r_[0,g,len(x)]) output = [] for k in range(len(g)-1): output.append(func(x[g[k]:g[k+1]])) return asarray(output)
def triu(m, k=0): """ returns the elements on and above the k-th diagonal of m. k=0 is the main diagonal, k > 0 is above and k < 0 is below the main diagonal. """ svsp = getattr(m,'spacesaver',lambda:0)() m = asarray(m,savespace=1) out = (1-tri(m.shape[0], m.shape[1], k-1, m.typecode()))*m out.savespace(svsp) return out
def lstsq(a, b, cond=None, overwrite_a=0, overwrite_b=0): """ lstsq(a, b, cond=None, overwrite_a=0, overwrite_b=0) -> x,resids,rank,s Return least-squares solution of a * x = b. Inputs: a -- An M x N matrix. b -- An M x nrhs matrix or M vector. cond -- Used to determine effective rank of a. Outputs: x -- The solution (N x nrhs matrix) to the minimization problem: 2-norm(| b - a * x |) -> min resids -- The residual sum-of-squares for the solution matrix x (only if M>N and rank==N). rank -- The effective rank of a. s -- Singular values of a in decreasing order. The condition number of a is abs(s[0]/s[-1]). """ a1, b1 = map(asarray_chkfinite,(a,b)) if len(a1.shape) != 2: raise ValueError, 'expected matrix' m,n = a1.shape if len(b1.shape)==2: nrhs = b1.shape[1] else: nrhs = 1 if m != b1.shape[0]: raise ValueError, 'incompatible dimensions' gelss, = get_lapack_funcs(('gelss',),(a1,b1)) if n>m: # need to extend b matrix as it will be filled with # a larger solution matrix b2 = zeros((n,nrhs),gelss.typecode) if len(b1.shape)==2: b2[:m,:] = b1 else: b2[:m,0] = b1 b1 = b2 overwrite_a = overwrite_a or (a1 is not a and not hasattr(a,'__array__')) overwrite_b = overwrite_b or (b1 is not b and not hasattr(b,'__array__')) if gelss.module_name[:7] == 'flapack': lwork = calc_lwork.gelss(gelss.prefix,m,n,nrhs)[1] v,x,s,rank,info = gelss(a1,b1,cond = cond, lwork = lwork, overwrite_a = overwrite_a, overwrite_b = overwrite_b) else: raise NotImplementedError,'calling gelss from %s' % (gelss.module_name) if info>0: raise LinAlgError, "SVD did not converge in Linear Least Squares" if info<0: raise ValueError,\ 'illegal value in %-th argument of internal gelss'%(-info) resids = asarray([],x.typecode()) if n<m: x1 = x[:n] if rank==n: resids = sum(x[n:]**2) x = x1 return x,resids,rank,s
def hessenberg(a,calc_q=0,overwrite_a=0): """ Compute Hessenberg form of a matrix. Inputs: a -- the matrix calc_q -- if non-zero then calculate unitary similarity transformation matrix q. overwrite_a=0 -- if non-zero then discard the contents of a, i.e. a is used as a work array if possible. Outputs: h -- Hessenberg form of a [calc_q=0] h, q -- matrices such that a = q * h * q^T [calc_q=1] """ a1 = asarray(a) if len(a1.shape) != 2 or (a1.shape[0] != a1.shape[1]): raise ValueError, 'expected square matrix' overwrite_a = overwrite_a or (a1 is not a and not hasattr(a,'__array__')) gehrd,gebal = get_lapack_funcs(('gehrd','gebal'),(a1,)) ba,lo,hi,pivscale,info = gebal(a,permute=1,overwrite_a = overwrite_a) if info<0: raise ValueError,\ 'illegal value in %-th argument of internal gebal (hessenberg)'%(-info) n = len(a1) lwork = calc_lwork.gehrd(gehrd.prefix,n,lo,hi) hq,tau,info = gehrd(ba,lo=lo,hi=hi,lwork=lwork,overwrite_a=1) if info<0: raise ValueError,\ 'illegal value in %-th argument of internal gehrd (hessenberg)'%(-info) if not calc_q: for i in range(lo,hi): hq[i+2:hi+1,i] = 0.0 return hq # XXX: Use ORGHR routines to compute q. ger,gemm = get_blas_funcs(('ger','gemm'),(hq,)) typecode = hq.typecode() q = None for i in range(lo,hi): if tau[i]==0.0: continue v = zeros(n,typecode=typecode) v[i+1] = 1.0 v[i+2:hi+1] = hq[i+2:hi+1,i] hq[i+2:hi+1,i] = 0.0 h = ger(-tau[i],v,v,a=diag(ones(n,typecode=typecode)),overwrite_a=1) if q is None: q = h else: q = gemm(1.0,q,h) if q is None: q = diag(ones(n,typecode=typecode)) return hq,q
def fft(x, n=None, axis=-1, overwrite_x=0): """ fft(x, n=None, axis=-1, overwrite_x=0) -> y Return discrete Fourier transform of arbitrary type sequence x. The returned complex array contains [y(0),y(1),..,y(n/2-1),y(-n/2),...,y(-1)] if n is even [y(0),y(1),..,y((n-1)/2),y(-(n-1)/2),...,y(-1)] if n is odd where y(j) = sum[k=0..n-1] x[k] * exp(-sqrt(-1)*j*k* 2*pi/n) j = 0..n-1 Note that y(-j) = y(n-j). Optional input: n Defines the length of the Fourier transform. If n is not specified then n=x.shape[axis] is set. If n<x.shape[axis], x is truncated. If n>x.shape[axis], x is zero-padded. axis The trasnform is applied along the given axis of the input array (or the newly constructed array if n argument was used). overwrite_x If set to true, the contents of x can be destroyed. Notes: y == fft(ifft(y)) within numerical accuracy. """ tmp = asarray(x) t = tmp.typecode() if t=='D': overwrite_x = overwrite_x or (tmp is not x and not \ hasattr(x,'__array__')) work_function = fftpack.zfft elif t=='F': raise NotImplementedError else: overwrite_x = 1 work_function = fftpack.zrfft #return _raw_fft(tmp,n,axis,1,overwrite_x,work_function) if n is None: n = tmp.shape[axis] elif n != tmp.shape[axis]: tmp = _fix_shape(tmp,n,axis) overwrite_x = 1 if axis == -1 or axis == len(tmp.shape) - 1: return work_function(tmp,n,1,0,overwrite_x) tmp = swapaxes(tmp, axis, -1) tmp = work_function(tmp,n,1,0,overwrite_x) return swapaxes(tmp, axis, -1)
def imrotate(arr,angle,interp='bilinear'): """Rotate an image counter-clockwise by angle degrees. Interpolation methods can be: 'nearest' : for nearest neighbor 'bilinear' : for bilinear 'cubic' or 'bicubic' : for bicubic """ arr = asarray(arr) func = {'nearest':0,'bilinear':2,'bicubic':3,'cubic':3} im = toimage(arr) im = im.rotate(angle,resample=func[interp]) return fromimage(im)
def ifftshift(x,axes=None): """ ifftshift(x,axes=None) - > y Inverse of fftshift. """ tmp = asarray(x) ndim = len(tmp.shape) if axes is None: axes = range(ndim) y = tmp for k in axes: n = tmp.shape[k] p2 = n-(n+1)/2 mylist = concatenate((arange(p2,n),arange(p2))) y = take(y,mylist,k) return y
def fftn(x, shape=None, axes=None, overwrite_x=0): """ fftn(x, shape=None, axes=None, overwrite_x=0) -> y Return multi-dimensional discrete Fourier transform of arbitrary type sequence x. The returned array contains y[j_1,..,j_d] = sum[k_1=0..n_1-1, ..., k_d=0..n_d-1] x[k_1,..,k_d] * prod[i=1..d] exp(-sqrt(-1)*2*pi/n_i * j_i * k_i) where d = len(x.shape) and n = x.shape. Note that y[..., -j_i, ...] = y[..., n_i-j_i, ...]. Optional input: shape Defines the shape of the Fourier transform. If shape is not specified then shape=take(x.shape,axes). If shape[i]>x.shape[i] then the i-th dimension is padded with zeros. If shape[i]<x.shape[i], then the i-th dimension is truncated to desired length shape[i]. axes The transform is applied along the given axes of the input array (or the newly constructed array if shape argument was used). overwrite_x If set to true, the contents of x can be destroyed. Notes: y == fftn(ifftn(y)) within numerical accuracy. """ tmp = asarray(x) t = tmp.typecode() if t=='D': overwrite_x = overwrite_x or (tmp is not x and not \ hasattr(x,'__array__')) work_function = fftpack.zfftnd elif t=='F': raise NotImplementedError else: overwrite_x = 1 work_function = fftpack.zfftnd return _raw_fftnd(tmp,shape,axes,1,overwrite_x,work_function)
def fftshift(x,axes=None): """ fftshift(x, axes=None) -> y Shift zero-frequency component to center of spectrum. This function swaps half-spaces for all axes listed (defaults to all). Notes: If len(x) is even then the Nyquist component is y[0]. """ tmp = asarray(x) ndim = len(tmp.shape) if axes is None: axes = range(ndim) y = tmp for k in axes: n = tmp.shape[k] p2 = (n+1)/2 mylist = concatenate((arange(p2,n),arange(p2))) y = take(y,mylist,k) return y
def pade(an, m): """Given Taylor series coefficients in an, return a Pade approximation to the function as the ratio of two polynomials p / q where the order of q is m. """ an = asarray(an) N = len(an) - 1 n = N-m if (n < 0): raise ValueError, \ "Order of q <m> must be smaller than len(an)-1." Akj = eye(N+1,n+1) Bkj = zeros((N+1,m),'d') for row in range(1,m+1): Bkj[row,:row] = -(an[:row])[::-1] for row in range(m+1,N+1): Bkj[row,:] = -(an[row-m:row])[::-1] C = hstack((Akj,Bkj)) pq = dot(linalg.inv(C),an) p = pq[:n+1] q = r_[1.0,pq[n+1:]] return poly1d(p[::-1]), poly1d(q[::-1])
def ifft(x, n=None, axis=-1, overwrite_x=0): """ ifft(x, n=None, axis=-1, overwrite_x=0) -> y Return inverse discrete Fourier transform of arbitrary type sequence x. The returned complex array contains [y(0),y(1),...,y(n-1)] where y(j) = 1/n sum[k=0..n-1] x[k] * exp(sqrt(-1)*j*k* 2*pi/n) Optional input: see fft.__doc__ """ tmp = asarray(x) t = tmp.typecode() if t=='D': overwrite_x = overwrite_x or (tmp is not x and not \ hasattr(x,'__array__')) work_function = fftpack.zfft elif t=='F': raise NotImplementedError else: overwrite_x = 1 work_function = fftpack.zrfft #return _raw_fft(tmp,n,axis,-1,overwrite_x,work_function) if n is None: n = tmp.shape[axis] elif n != tmp.shape[axis]: tmp = _fix_shape(tmp,n,axis) overwrite_x = 1 if axis == -1 or axis == len(tmp.shape) - 1: return work_function(tmp,n,-1,1,overwrite_x) tmp = swapaxes(tmp, axis, -1) tmp = work_function(tmp,n,-1,1,overwrite_x) return swapaxes(tmp, axis, -1)
def _geneig(a1,b,left,right,overwrite_a,overwrite_b): b1 = asarray(b) overwrite_b = overwrite_b or (b1 is not b and not hasattry(b,'__array__')) if len(b1.shape) != 2 or b1.shape[0] != b1.shape[1]: raise ValueError, 'expected square matrix' ggev, = get_lapack_funcs(('ggev',),(a1,b1)) cvl,cvr = left,right if ggev.module_name[:7] == 'clapack': raise NotImplementedError,'calling ggev from %s' % (ggev.module_name) res = ggev(a1,b1,lwork=-1) lwork = res[-2][0] if ggev.prefix in 'cz': alpha,beta,vl,vr,work,info = ggev(a1,b1,cvl,cvr,lwork, overwrite_a,overwrite_b) w = alpha / beta else: alphar,alphai,beta,vl,vr,work,info = ggev(a1,b1,cvl,cvr,lwork, overwrite_a,overwrite_b) w = (alphar+_I*alphai)/beta if info<0: raise ValueError,\ 'illegal value in %-th argument of internal ggev'%(-info) if info>0: raise LinAlgError,"generalized eig algorithm did not converge" only_real = scipy_base.logical_and.reduce(scipy_base.equal(w.imag,0.0)) if not (ggev.prefix in 'cz' or only_real): t = w.typecode() if left: vl = _make_complex_eigvecs(w, vl, t) if right: vr = _make_complex_eigvecs(w, vr, t) if not (left or right): return w if left: if right: return w, vl, vr return w, vl return w, vr
def lu_factor(a, overwrite_a=0): """Return raw LU decomposition of a matrix and pivots, for use in solving a system of linear equations. Inputs: a --- an NxN matrix Outputs: lu --- the lu factorization matrix piv --- an array of pivots """ a1 = asarray(a) if len(a1.shape) != 2 or (a1.shape[0] != a1.shape[1]): raise ValueError, 'expected square matrix' overwrite_a = overwrite_a or (a1 is not a and not hasattr(a,'__array__')) getrf, = get_lapack_funcs(('getrf',),(a1,)) lu, piv, info = getrf(a,overwrite_a=overwrite_a) if info<0: raise ValueError,\ 'illegal value in %-th argument of internal getrf (lu_factor)'%(-info) if info>0: warn("Diagonal number %d is exactly zero. Singular matrix." % info, RuntimeWarning) return lu, piv
def bicg(A,b,x0=None,tol=1e-5,maxiter=None,xtype=None): """Use BIConjugate Gradient iteration to solve A x = b Inputs: A -- An array or an object with matvec(x) and rmatvec(x) methods to represent A * x and A^H * x respectively. May also have psolve(b) and rpsolve(b) methods for representing solutions to the preconditioning equations M * x = b and M^H * x = b respectively. b -- An n-length vector Outputs: x -- The converged solution info -- output result 0 : successful exit >0 : convergence to tolerance not achieved, number of iterations <0 : illegal input or breakdown Optional Inputs: x0 -- (0) default starting guess tol -- (1e-5) relative tolerance to achieve maxiter -- (10*n) maximum number of iterations xtype -- The type of the result. If None, then it will be determined from A.typecode() and b. If A does not have a typecode method then it will compute A.matvec(x0) to get a typecode. To save the extra computation when A does not have a typecode attribute use xtype=0 for the same type as b or use xtype='f','d','F',or 'D' """ b = sb.asarray(b)+0.0 n = len(b) if maxiter is None: maxiter = n*10 x = x0 if x is None: x = sb.zeros(n) if xtype is None: try: atyp = A.typecode() except AttributeError: atyp = None if atyp is None: atyp = A.matvec(x).typecode() typ = _coerce_rules[b.typecode(),atyp] elif xtype == 0: typ = b.typecode() else: typ = xtype if typ not in 'fdFD': raise ValueError, "xtype must be 'f', 'd', 'F', or 'D'" x = sb.asarray(x,typ) b = sb.asarray(b,typ) matvec, psolve, rmatvec, rpsolve = (None,)*4 ltr = _type_conv[typ] revcom = _iterative.__dict__[ltr+'bicgrevcom'] stoptest = _iterative.__dict__[ltr+'stoptest2'] resid = tol ndx1 = 1 ndx2 = -1 work = sb.zeros(6*n,typ) ijob = 1 info = 0 ftflag = True bnrm2 = -1.0 iter_ = maxiter while 1: x, iter_, resid, info, ndx1, ndx2, sclr1, sclr2, ijob = \ revcom(b, x, work, iter_, resid, info, ndx1, ndx2, ijob) slice1 = slice(ndx1-1, ndx1-1+n) slice2 = slice(ndx2-1, ndx2-1+n) if (ijob == -1): break elif (ijob == 1): if matvec is None: matvec = get_matvec(A) work[slice2] *= sclr2 work[slice2] += sclr1*matvec(work[slice1]) elif (ijob == 2): if rmatvec is None: rmatvec = get_rmatvec(A) work[slice2] *= sclr2 work[slice2] += sclr1*rmatvec(work[slice1]) elif (ijob == 3): if psolve is None: psolve = get_psolve(A) work[slice1] = psolve(work[slice2]) elif (ijob == 4): if rpsolve is None: rpsolve = get_rpsolve(A) work[slice1] = rpsolve(work[slice2]) elif (ijob == 5): if matvec is None: matvec = get_matvec(A) work[slice2] *= sclr2 work[slice2] += sclr1*matvec(x) elif (ijob == 6): if ftflag: info = -1 ftflag = False bnrm2, resid, info = stoptest(work[slice1], b, bnrm2, tol, info) ijob = 2 return x, info
def fligner(*args,**kwds): """Perform Levene test with the null hypothesis that all input samples have equal variances. Inputs are sample vectors: bartlett(x,y,z,...) One keyword input, center, can be used with values center = 'mean', center='median' (default), center='trimmed' Outputs: (Xsq, pval) Xsq -- the Test statistic pval -- significance level if null is rejected with this value of X (prob. that null is true but rejected with this p-value.) References: http://www.stat.psu.edu/~bgl/center/tr/TR993.ps Fligner, M.A. and Killeen, T.J. (1976). Distribution-free two-sample tests for scale. 'Journal of the American Statistical Association.' 71(353), 210-213. """ k = len(args) if k < 2: raise ValueError, "Must enter at least two input sample vectors." if 'center' in kwds.keys(): center = kwds['center'] else: center = 'median' if not center in ['mean','median','trimmed']: raise ValueError, "Keyword argument <center> must be 'mean', 'median'"\ + "or 'trimmed'." if center == 'median': func = stats.median elif center == 'mean': func = stats.mean else: func = stats.trim_mean Ni = asarray([len(args[j]) for j in range(k)]) Yci = asarray([func(args[j]) for j in range(k)]) Ntot = sum(Ni) # compute Zij's Zij = [abs(asarray(args[i])-Yci[i]) for i in range(k)] allZij = [] g = [0] for i in range(k): allZij.extend(list(Zij[i])) g.append(len(allZij)) a = distributions.norm.ppf(stats.rankdata(allZij)/(2*(Ntot+1.0)) + 0.5) # compute Aibar Aibar = _apply_func(a,g,sum) / Ni anbar = stats.mean(a) varsq = stats.var(a) Xsq = sum(Ni*(asarray(Aibar)-anbar)**2.0)/varsq pval = distributions.chi2.sf(Xsq,k-1) # 1 - cdf return Xsq, pval
def levene(*args,**kwds): """Perform Levene test with the null hypothesis that all input samples have equal variances. Inputs are sample vectors: bartlett(x,y,z,...) One keyword input, center, can be used with values center = 'mean', center='median' (default), center='trimmed' center='median' is recommended for skewed (non-normal) distributions center='mean' is recommended for symmetric, moderate-tailed, dist. center='trimmed' is recommended for heavy-tailed distributions. Outputs: (W, pval) W -- the Test statistic pval -- significance level if null is rejected with this value of W (prob. that null is true but rejected with this p-value.) References: http://www.itl.nist.gov/div898/handbook/eda/section3/eda35a.htm Levene, H. (1960). In Contributions to Probability and Statistics: Essays in Honor of Harold Hotelling, I. Olkin et al. eds., Stanford University Press, pp. 278-292. Brown, M. B. and Forsythe, A. B. (1974), Journal of the American Statistical Association, 69, 364-367 """ k = len(args) if k < 2: raise ValueError, "Must enter at least two input sample vectors." Ni = zeros(k) Yci = zeros(k,'d') if 'center' in kwds.keys(): center = kwds['center'] else: center = 'median' if not center in ['mean','median','trimmed']: raise ValueError, "Keyword argument <center> must be 'mean', 'median'"\ + "or 'trimmed'." if center == 'median': func = stats.median elif center == 'mean': func = stats.mean else: func = stats.trim_mean for j in range(k): Ni[j] = len(args[j]) Yci[j] = func(args[j]) Ntot = sum(Ni) # compute Zij's Zij = [None]*k for i in range(k): Zij[i] = abs(asarray(args[i])-Yci[i]) # compute Zbari Zbari = zeros(k,'d') Zbar = 0.0 for i in range(k): Zbari[i] = stats.mean(Zij[i]) Zbar += Zbari[i]*Ni[i] Zbar /= Ntot numer = (Ntot-k)*sum(Ni*(Zbari-Zbar)**2) # compute denom_variance dvar = 0.0 for i in range(k): dvar += sum((Zij[i]-Zbari[i])**2) denom = (k-1.0)*dvar W = numer / denom pval = distributions.f.sf(W,k-1,Ntot-k) # 1 - cdf return W, pval
def ansari(x,y): """Determine if the scale parameter for two distributions with equal medians is the same using the Ansari-Bradley statistic. Specifically, compute the AB statistic and the probability of error that the null hypothesis is true but rejected with the computed statistic as the critical value. One can reject the null hypothesis that the ratio of variances is 1 if returned probability of error is small (say < 0.05) """ x,y = asarray(x),asarray(y) n = len(x) m = len(y) if (m < 1): raise ValueError, "Not enough other observations." if (n < 1): raise ValueError, "Not enough test observations." N = m+n xy = r_[x,y] # combine rank = stats.rankdata(xy) symrank = amin(array((rank,N-rank+1)),0) AB = sum(symrank[:n]) uxy = unique(xy) repeats = (len(uxy) != len(xy)) exact = ((m<55) and (n<55) and not repeats) if repeats and ((m < 55) or (n < 55)): print "Ties preclude use of exact statistic." if exact: astart, a1, ifault = statlib.gscale(n,m) ind = AB-astart total = sum(a1) if ind < len(a1)/2.0: cind = int(ceil(ind)) if (ind == cind): pval = 2.0*sum(a1[:cind+1])/total else: pval = 2.0*sum(a1[:cind])/total else: find = int(floor(ind)) if (ind == floor(ind)): pval = 2.0*sum(a1[find:])/total else: pval = 2.0*sum(a1[find+1:])/total return AB, min(1.0,pval) # otherwise compute normal approximation if N % 2: # N odd mnAB = n*(N+1.0)**2 / 4.0 / N varAB = n*m*(N+1.0)*(3+N**2)/(48.0*N**2) else: mnAB = n*(N+2.0)/4.0 varAB = m*n*(N+2)*(N-2.0)/48/(N-1.0) if repeats: # adjust variance estimates # compute sum(tj * rj**2) fac = sum(symrank**2) if N % 2: # N odd varAB = m*n*(16*N*fac-(N+1)**4)/(16.0 * N**2 * (N-1)) else: # N even varAB = m*n*(16*fac-N*(N+2)**2)/(16.0 * N * (N-1)) z = (AB - mnAB)/sqrt(varAB) pval = (1-distributions.norm.cdf(abs(z)))*2.0 return AB, pval
def toimage(arr,high=255,low=0,cmin=None,cmax=None,pal=None, mode=None,channel_axis=None): """Takes a Numeric array and returns a PIL image. The mode of the PIL image depends on the array shape, the pal keyword, and the mode keyword. For 2-D arrays, if pal is a valid (N,3) byte-array giving the RGB values (from 0 to 255) then mode='P', otherwise mode='L', unless mode is given as 'F' or 'I' in which case a float and/or integer array is made For 3-D arrays, the channel_axis argument tells which dimension of the array holds the channel data. For 3-D arrays if one of the dimensions is 3, the mode is 'RGB' by default or 'YCbCr' if selected. if the The Numeric array must be either 2 dimensional or 3 dimensional. """ data = asarray(arr) if iscomplexobj(data): raise ValueError, "Cannot convert a complex-valued array." shape = list(data.shape) valid = len(shape)==2 or ((len(shape)==3) and \ ((3 in shape) or (4 in shape))) assert valid, "Not a suitable array shape for any mode." if len(shape) == 2: shape = (shape[1],shape[0]) # columns show up first if mode == 'F': image = Image.fromstring(mode,shape,data.astype('f').tostring()) return image if mode in [None, 'L', 'P']: bytedata = bytescale(data,high=high,low=low,cmin=cmin,cmax=cmax) image = Image.fromstring('L',shape,bytedata.tostring()) if pal is not None: image.putpalette(asarray(pal,typecode=_UInt8).tostring()) # Becomes a mode='P' automagically. elif mode == 'P': # default gray-scale pal = arange(0,256,1,typecode='b')[:,NewAxis] * \ ones((3,),typecode='b')[NewAxis,:] image.putpalette(asarray(pal,typecode=_UInt8).tostring()) return image if mode == '1': # high input gives threshold for 1 bytedata = ((data > high)*255).astype('b') image = Image.fromstring('L',shape,bytedata.tostring()) image = image.convert(mode='1') return image if cmin is None: cmin = amin(ravel(data)) if cmax is None: cmax = amax(ravel(data)) data = (data*1.0 - cmin)*(high-low)/(cmax-cmin) + low if mode == 'I': image = Image.fromstring(mode,shape,data.astype('i').tostring()) else: raise ValueError, _errstr return image # if here then 3-d array with a 3 or a 4 in the shape length. # Check for 3 in datacube shape --- 'RGB' or 'YCbCr' if channel_axis is None: if (3 in shape): ca = Numeric.nonzero(asarray(shape) == 3)[0] else: ca = Numeric.nonzero(asarray(shape) == 4) if len(ca): ca = ca[0] else: raise ValueError, "Could not find channel dimension." else: ca = channel_axis numch = shape[ca] if numch not in [3,4]: raise ValueError, "Channel axis dimension is not valid." bytedata = bytescale(data,high=high,low=low,cmin=cmin,cmax=cmax) if ca == 2: strdata = bytedata.tostring() shape = (shape[1],shape[0]) elif ca == 1: strdata = transpose(bytedata,(0,2,1)).tostring() shape = (shape[2],shape[0]) elif ca == 0: strdata = transpose(bytedata,(1,2,0)).tostring() shape = (shape[2],shape[1]) if mode is None: if numch == 3: mode = 'RGB' else: mode = 'RGBA' if mode not in ['RGB','RGBA','YCbCr','CMYK']: raise ValueError, _errstr if mode in ['RGB', 'YCbCr']: assert numch == 3, "Invalid array shape for mode." if mode in ['RGBA', 'CMYK']: assert numch == 4, "Invalid array shape for mode." # Here we know data and mode is coorect image = Image.fromstring(mode, shape, strdata) return image