def recoverM3( k, P12, P13, P123 ): """Recover M3 from P_12, P_13 and P_123""" # Get singular vectors U1, _, U2 = svdk( P12, k ) _, _, U3 = svdk( P13, k ) U2, U3 = U2.T, U3.T # Check U_1.T P_{12} U_2 is invertible assert( sc.absolute( det( U1.T.dot( P12 ).dot( U2 ) ) ) > 1e-16 ) while True: # Get a random basis set theta = orthogonal( k ) eta = U3.dot( theta ).T # Get the eigen value matrix L B123 = lambda eta_: U1.T.dot( P123( eta_ ) ).dot( U2 ).dot( inv( U1.T.dot( P12 ). dot( U2 ) ) ) l, R1 = eig( B123( eta[0] ) ) R1 = array( map( lambda col: col/norm(col), R1.T ) ).T assert( norm(R1.T[0]) - 1.0 < 1e-10 ) # Restart if not ( sc.isreal( l ).all() ): continue L = [l.real] for i in xrange( 1, k ): l = diag( inv(R1).dot( B123( eta[i] ).dot( R1 ) ) ) # Restart if not ( sc.isreal( l ).all() ): continue L.append( l ) L = array( sc.vstack( L ) ) M3_ = U3.dot( inv(theta.T) ).dot( L ) return M3_
def par_duff_bif(sigma=2.0, alpha=2.0, mu=0.5): #All parameters set to one for this simple illustration. k2 = sp.sqrt(sigma**2 + 4 * mu**2) k = sp.linspace(0.0, 2.0 * k2, 1000) #print(k) ahigh = sp.sqrt(4 / 3 / alpha * (sigma + sp.sqrt(k**2 - 4 * mu**2))) #print(ahigh) mask_high = sp.isreal(ahigh) plt.plot(k[mask_high], sp.real(ahigh[mask_high]), '-k') alow = sp.sqrt(4 / 3 / alpha * (sigma - sp.sqrt(k**2 - 4 * mu**2))) mask_low = sp.isreal(alow) plt.plot(k[mask_low], sp.real(alow[mask_low]), '--k') plt.plot(k[k < k2], k[k < k2] * 0, '-k') plt.plot(k[k > k2], k[k > k2] * 0, '--k') plt.xlabel('$k$') plt.ylabel('a') plt.grid('on') plt.annotate('$k_2$', xy=(k2 + .03, 0.03)) plt.title('Bifurcation Diagram using $k$ as a control parameter.') plt.axis([0, 2.0 * k2, -0.1, sp.ceil(max(sp.real(ahigh)))])
def evalgrid1D(f, evalgrid=None, nGrid=10, minval=0.0, maxval=0.99999, dimF=0): ''' evaluate a function f(x) on all values of a grid. -------------------------------------------------------------------------- Input: f(x) : callable target function evalgrid: 1-D array prespecified grid of x-values nGrid : number of x-grid points to evaluate f(x) minval : minimum x-value for optimization of f(x) maxval : maximum x-value for optimization of f(x) -------------------------------------------------------------------------- Output: evalgrid : x-values resultgrid : f(x)-values -------------------------------------------------------------------------- ''' if evalgrid is None: step = (maxval - minval) / (nGrid) evalgrid = SP.arange(minval, maxval + step, step) if dimF: resultgrid = SP.ones((evalgrid.shape[0], dimF)) * 9999999999999.0 else: resultgrid = SP.ones(evalgrid.shape[0]) * 9999999999999.0 for i in xrange(evalgrid.shape[0]): fevalgrid = f(evalgrid[i]) is_real = False try: is_real = SP.isreal(fevalgrid).all() except: is_real = SP.isreal(fevalgrid) assert is_real, "function returned imaginary value" resultgrid[i] = fevalgrid return (evalgrid, resultgrid)
def evalgrid1D(f, evalgrid = None, nGrid=10, minval=0.0, maxval = 0.99999, dimF=0): ''' evaluate a function f(x) on all values of a grid. -------------------------------------------------------------------------- Input: f(x) : callable target function evalgrid: 1-D array prespecified grid of x-values nGrid : number of x-grid points to evaluate f(x) minval : minimum x-value for optimization of f(x) maxval : maximum x-value for optimization of f(x) -------------------------------------------------------------------------- Output: evalgrid : x-values resultgrid : f(x)-values -------------------------------------------------------------------------- ''' if evalgrid is None: step = (maxval-minval)/(nGrid) evalgrid = SP.arange(minval,maxval+step,step) if dimF: resultgrid = SP.ones((evalgrid.shape[0],dimF))*9999999999999.0 else: resultgrid = SP.ones(evalgrid.shape[0])*9999999999999.0 for i in xrange(evalgrid.shape[0]): fevalgrid = f(evalgrid[i]) is_real=False try: is_real = SP.isreal(fevalgrid).all() except: is_real = SP.isreal(fevalgrid) assert is_real,"function returned imaginary value" resultgrid[i] = fevalgrid return (evalgrid,resultgrid)
def geoidheight(lat, lon): """ Calculate geoid height using the EGM96 Geopotential Model. Parameters ---------- lat : array_like Lateral coordinates [degrees]. Values must be -90 <= lat <= 90. lon : array_like Longitudinal coordinates [degrees]. Values must be 0 <= lon <= 360. Returns ------- out : array_like Geoidheight [meters] Examples -------- >>> geoidheight(30, 20) 25.829999999999995 >>> geoidheight([30, 20],[40, 20]) [9.800000000000002, 14.43] """ global _EGM96 # convert the input value to array itype, lat = to_ndarray(lat) itype, lon = to_ndarray(lon) if lat.shape != lon.shape: raise AerotbxValueError("Inputs must contain equal number of values.") if (lat < -90).any() or (lat > 90).any() or not sp.isreal(lat).all(): raise AerotbxValueError("Lateral coordinates must be real numbers " "between -90 and 90 degrees.") if (lon < 0).any() or (lon > 360).any() or not sp.isreal(lon).all(): raise AerotbxValueError("Longitudinal coordinates must be real numbers " "between 0 and 360 degrees.") # if the model is not loaded, do so if _EGM96 is None: _EGM96 = _loadEGM96() # shift lateral values to the right reference and flatten coordinates lats = sp.deg2rad(-lat + 90).ravel() lons = sp.deg2rad(lon).ravel() # evaluate the spline and reshape the result evl = _EGM96.ev(lats, lons).reshape(lat.shape) return from_ndarray(itype, evl)
def geoidheight(lat, lon): """ Calculate geoid height using the EGM96 Geopotential Model. Parameters ---------- lat : array_like Lateral coordinates [degrees]. Values must be -90 <= lat <= 90. lon : array_like Longitudinal coordinates [degrees]. Values must be 0 <= lon <= 360. Returns ------- out : array_like Geoidheight [meters] Examples -------- >>> geoidheight(30, 20) 25.829999999999995 >>> geoidheight([30, 20],[40, 20]) [9.800000000000002, 14.43] """ global _EGM96 #convert the input value to array itype, lat = to_ndarray(lat) itype, lon = to_ndarray(lon) if lat.shape != lon.shape: raise Exception("Inputs must contain equal number of values.") if (lat < -90).any() or (lat > 90).any() or not sp.isreal(lat).all(): raise Exception("Lateral coordinates must be real numbers" \ " between -90 and 90 degrees.") if (lon < 0).any() or (lon > 360).any() or not sp.isreal(lon).all(): raise Exception("Longitudinal coordinates must be real numbers" \ " between 0 and 360 degrees.") #if the model is not loaded, do so if _EGM96 is None: _EGM96 = _loadEGM96() #shift lateral values to the right reference and flatten coordinates lats = sp.deg2rad(-lat + 90).ravel() lons = sp.deg2rad(lon).ravel() #evaluate the spline and reshape the result evl = _EGM96.ev(lats, lons).reshape(lat.shape) return from_ndarray(itype, evl)
def dispersion_relation_extraordinary(kx, ky, k, nO, nE, c): """Dispersion relation for the extraordinary wave. NOTE See eq. 16 in Glytsis, "Three-dimensional (vector) rigorous coupled-wave analysis of anisotropic grating diffraction", JOSA A, 7(8), 1990 Always give positive real or negative imaginary. """ if kx.shape != ky.shape or c.size != 3: raise ValueError('kx and ky must have the same length and c must have 3 components') kz = S.empty_like(kx) for ii in xrange(0, kx.size): alpha = nE**2 - nO**2 beta = kx[ii]/k * c[0] + ky[ii]/k * c[1] # coeffs C = S.array([nO**2 + c[2]**2 * alpha, \ 2. * c[2] * beta * alpha, \ nO**2 * (kx[ii]**2 + ky[ii]**2) / k**2 + alpha * beta**2 - nO**2 * nE**2]) # two solutions of type +x or -x, purely real or purely imag tmp_kz = k * S.roots(C) # get the negative imaginary part or the positive real one if S.any(S.isreal(tmp_kz)): kz[ii] = S.absolute(tmp_kz[0]) else: kz[ii] = -1j * S.absolute(tmp_kz[0]) return kz
def delayedsignalF(x,t0_pts): #============================================================== """ Delay a signal with a non integer value (computation in frequency domain) Synopsis: y=delayedsignalF(x,t0_pts) Inputs: x vector of length N t0_pts is a REAL delay expressed wrt the sampling time Ts=1: t0_pts = 1 corresponds to one time dot t0_pts may be positive, negative, non integer t0_pts>0: shift to the right t0_pts<0: shift to the left Rk: the length of FFT is 2^(nextpow2(N)+1 """ # # M. Charbit, Jan. 2010 #============================================================== N = len(x) p = ceil(log2(N))+1; Lfft = int(2.0**p); Lffts2 = Lfft/2; fftx = fft(x, Lfft); ind = concatenate((range(Lffts2+1), range(Lffts2+1-Lfft,0)),axis=0) fftdelay = exp(-2j*pi*t0_pts*ind/Lfft); fftdelay[Lffts2] = real(fftdelay[Lffts2]); ifftdelay = ifft(fftx*fftdelay); y = ifftdelay[range(N)]; if isreal(any(x)): y=real(y) return y
def sample_moments( X, k ): """Get the sample moments from data""" N, d = X.shape # Partition X into two halves to independently estimate M2 and M3 X1, X2 = X[:N/2], X[N/2:] # Get the moments M1 = X1.mean(0) M1_ = X2.mean(0) M2 = Pairs( X1, X1 ) M3 = lambda theta: TriplesP( X2, X2, X2, theta ) #M3 = Triples( X2, X2, X2 ) # TODO: Ah, not computing sigma2! # Estimate \sigma^2 = k-th eigenvalue of M2 - mu mu^T sigma2 = svdvals( M2 - outer( M1, M1 ) )[k-1] assert( sc.isreal( sigma2 ) and sigma2 > 0 ) # P (M_2) is the best kth rank apprximation to M2 - sigma^2 I P = approxk( M2 - sigma2 * eye( d ), k ) B = matrix_tensorify( eye(d), M1_ ) T = lambda theta: M3(theta) - sigma2 * ( M1_.dot(theta) * eye( d ) + outer( M1_, theta ) + outer( theta, M1_ ) ) #T = M3 - sigma2 * ( B + B.swapaxes(2, 1) + B.swapaxes(2, 0) ) return P, T
def npred(cev): rts = sp.roots([p[3] / 4., p[2] / 3., p[1] / 2., p[0] + cev, -C]) nmax = max([sp.real(i) for i in rts if sp.isreal(i)]) cbar = p[0] + p[1] * nmax / 2. + p[2] * (nmax**2) / 3. + p[3] * ( nmax**3) / 4. return nmax, cbar
def delayedsignalF(x, t0_pts): #============================================================== """ Delay a signal with a non integer value (computation in frequency domain) Synopsis: y=delayedsignalF(x,t0_pts) Inputs: x vector of length N t0_pts is a REAL delay expressed wrt the sampling time Ts=1: t0_pts = 1 corresponds to one time dot t0_pts may be positive, negative, non integer t0_pts>0: shift to the right t0_pts<0: shift to the left Rk: the length of FFT is 2^(nextpow2(N)+1 """ # # M. Charbit, Jan. 2010 #============================================================== N = len(x) p = ceil(log2(N)) + 1 Lfft = int(2.0**p) Lffts2 = Lfft / 2 fftx = fft(x, Lfft) ind = concatenate((range(Lffts2 + 1), range(Lffts2 + 1 - Lfft, 0)), axis=0) fftdelay = exp(-2j * pi * t0_pts * ind / Lfft) fftdelay[Lffts2] = real(fftdelay[Lffts2]) ifftdelay = ifft(fftx * fftdelay) y = ifftdelay[range(N)] if isreal(any(x)): y = real(y) return y
def _flowinput(flow): """Parse the flow input used in the aerodynamics module""" #pop flow from the input gamma = flow.pop("gamma", 1.4) #check if single input is given if len(flow) != 1: raise Exception("Function needs exactly one flow input.") #pop the flow variable and type mtype, flow = flow.popitem() if not sp.isreal(gamma).all() or not sp.isreal(flow).all(): raise Exception("Flow input variables must be real numbers.") #convert the input values to arrays ftype, flow = to_ndarray(flow) gtype, gamma = to_ndarray(gamma) #check if the given gamma value is valid if (gamma <= 1).any(): raise Exception("Specific heat ratio inputs must be real numbers" \ " greater than 1.") #if both inputs are non-scalar, they should be equal in shape if gamma.size > 1 and flow.size > 1 and gamma.shape != flow.shape: raise Exception("Inputs must be same shape or at least one input" \ " must be scalar.") #if one of the variables is an array, the other should match it size if gamma.size > flow.size: n = gamma.shape itype = gtype flow = sp.ones(n, sp.float64) * flow[0] else: n = flow.shape itype = ftype gamma = sp.ones(n, sp.float64) * gamma[0] return gamma, flow, mtype.lower(), itype
def setup(self, s, k, ells, **kwargs): ells = scipy.asarray(self.ells) super(FFTlogBessel, self).setup(s, k, ells + 1. / 2., **kwargs) if self.direction == 1: self.norm = (2 * constants.pi)**(3. / 2.) * self.k**(-3. / 2.) * ( (-1j)**ells)[:, None] self.integrand = scipy.array([self.s**(3. / 2.)] * len(ells)) else: self.norm = (2. * constants.pi)**(-3. / 2.) * self.s**( -3. / 2.) * (1j**ells)[:, None] self.integrand = scipy.array([self.k**(3. / 2)] * len(ells)) if scipy.isreal(self.norm).all(): self.norm = self.norm.real
def recover_M3( k, P12, P13, P123 ): """Recover M3 from P_12, P_13 and P_123""" d, _ = P12.shape # Get singular vectors U1, _, U2 = svdk( P12, k ) _, _, U3 = svdk( P13, k ) U2, U3 = U2.T, U3.T while True: # Get a random basis set theta = orthogonal( k ) P12i = inv( U1.T.dot( P12 ).dot( U2 ) ) #B123_ = sc.einsum( 'ijk,ia,jb,kc->abc', P123, U1, U2, U3 ) #B123 = sc.einsum( 'ajc,jb ->abc', B123_, P12i ) B123 = lambda theta: U1.T.dot( P123( U3.dot( theta ) ) ).dot( U2 ).dot( P12i ) l, R1 = eig( B123( theta.T[0] ) ) R1 = array( map( lambda col: col/norm(col), R1.T ) ).T assert( norm(R1.T[0]) - 1.0 < 1e-3 ) # Restart if not ( sc.isreal( l ).all() ): continue L = [l.real] for i in xrange( 1, k ): l = diag( inv(R1).dot( B123( theta.T[i] ).dot( R1 ) ) ) # Restart if not ( sc.isreal( l ).all() ): continue L.append( l ) L = array( sc.vstack( L ) ) M3_ = U3.dot( inv(theta.T) ).dot( L ) return M3_
def par_duff_bif(sigma = 2.0, alpha = 2.0, mu = 0.5): #All parameters set to one for this simple illustration. k2 = sp.sqrt(sigma**2 + 4*mu**2) k = sp.linspace(0.0, 2.0 * k2, 1000) #print(k) ahigh = sp.sqrt(4/3/alpha*(sigma+sp.sqrt(k**2-4*mu**2))) #print(ahigh) mask_high = sp.isreal(ahigh) plt.plot(k[mask_high],sp.real(ahigh[mask_high]),'-k') alow = sp.sqrt(4/3/alpha*(sigma-sp.sqrt(k**2-4*mu**2))) mask_low = sp.isreal(alow) plt.plot(k[mask_low],sp.real(alow[mask_low]),'--k') plt.plot(k[k<k2],k[k<k2]*0,'-k') plt.plot(k[k>k2],k[k>k2]*0,'--k') plt.xlabel('$k$') plt.ylabel('a') plt.grid('on') plt.annotate('$k_2$', xy=(k2+.03,0.03)) plt.title('Bifurcation Diagram using $k$ as a control parameter.'); plt.axis([0,2.0*k2,-0.1,sp.ceil(max(sp.real(ahigh)))]);
def test_all(self): for k,v,s,o,expected in self.cases: sc = simplicial_complex((v,s)) M = whitney_innerproduct(sc,k) M = M.todense() #Permute the matrix to coincide with the ordering of the known matrix permute = [sc[k].simplex_to_index[simplex(x)] for x in o] M = M[permute,:][:,permute] assert_almost_equal(M,expected) #check whether matrix is S.P.D. self.assert_(alltrue(isreal(eigvals(M)))) self.assert_(min(real(eigvals(M))) >= 0) assert_almost_equal(M,M.T)
def test_all(self): for k, v, s, o, expected in self.cases: sc = simplicial_complex((v, s)) M = whitney_innerproduct(sc, k) M = M.todense() #Permute the matrix to coincide with the ordering of the known matrix permute = [sc[k].simplex_to_index[simplex(x)] for x in o] M = M[permute, :][:, permute] assert_almost_equal(M, expected) #check whether matrix is S.P.D. self.assert_(alltrue(isreal(eigvals(M)))) self.assert_(min(real(eigvals(M))) >= 0) assert_almost_equal(M, M.T)
def dispersion_relation_extraordinary(kx, ky, k, nO, nE, c): """Dispersion relation for the extraordinary wave. NOTE See eq. 16 in Glytsis, "Three-dimensional (vector) rigorous coupled-wave analysis of anisotropic grating diffraction", JOSA A, 7(8), 1990 Always give positive real or negative imaginary. """ if kx.shape != ky.shape or c.size != 3: raise ValueError( "kx and ky must have the same length and c must have 3 components" ) kz = S.empty_like(kx) for ii in range(0, kx.size): alpha = nE ** 2 - nO ** 2 beta = kx[ii] / k * c[0] + ky[ii] / k * c[1] # coeffs C = S.array( [ nO ** 2 + c[2] ** 2 * alpha, 2.0 * c[2] * beta * alpha, nO ** 2 * (kx[ii] ** 2 + ky[ii] ** 2) / k ** 2 + alpha * beta ** 2 - nO ** 2 * nE ** 2, ] ) # two solutions of type +x or -x, purely real or purely imag tmp_kz = k * S.roots(C) # get the negative imaginary part or the positive real one if S.any(S.isreal(tmp_kz)): kz[ii] = S.absolute(tmp_kz[0]) else: kz[ii] = -1j * S.absolute(tmp_kz[0]) return kz
def fit(self, X, w): if len(X) == 0: raise NotEnoughParticles("Fitting not possible.") self.X_arr = X.as_matrix() ctree = cKDTree(X) _, indices = ctree.query(X, k=min(self.k + 1, X.shape[0])) covs, inv_covs, dets = list(zip(*[self._cov_and_inv(n, indices) for n in range(X.shape[0])])) self.covs = sp.array(covs) self.inv_covs = sp.array(inv_covs) self.determinants = sp.array(dets) self.normalization = sp.sqrt( (2 * sp.pi) ** self.X_arr.shape[1] * self.determinants) if not sp.isreal(self.normalization).all(): raise Exception("Normalization not real") self.normalization = sp.real(self.normalization)
def nLLeval(self, h2=0.0, REML=True, logdelta=None, delta=None, dof=None, scale=1.0, penalty=0.0): ''' evaluate -ln( N( U^T*y | U^T*X*beta , h2*S + (1-h2)*I ) ), where ((1-a2)*K0 + a2*K1) = USU^T -------------------------------------------------------------------------- Input: h2 : mixture weight between K and Identity (environmental noise) REML : boolean if True : compute REML if False : compute ML dof : Degrees of freedom of the Multivariate student-t (default None uses multivariate Normal likelihood) logdelta: log(delta) allows to optionally parameterize in delta space delta : delta allows to optionally parameterize in delta space scale : Scale parameter the multiplies the Covariance matrix (default 1.0) -------------------------------------------------------------------------- Output dictionary: 'nLL' : negative log-likelihood 'sigma2' : the model variance sigma^2 'beta' : [D*1] array of fixed effects weights beta 'h2' : mixture weight between Covariance and noise 'REML' : True: REML was computed, False: ML was computed 'a2' : mixture weight between K0 and K1 'dof' : Degrees of freedom of the Multivariate student-t (default None uses multivariate Normal likelihood) 'scale' : Scale parameter that multiplies the Covariance matrix (default 1.0) -------------------------------------------------------------------------- ''' if (h2 < 0.0) or (h2 > 1.0): return {'nLL': 3E20, 'h2': h2, 'REML': REML, 'scale': scale} k = self.S.shape[0] N = self.y.shape[0] D = self.UX.shape[1] #if REML == True: # # this needs to be fixed, please see test_gwas.py for details # raise NotImplementedError("REML in lmm object not supported, please use lmm_cov.py instead") if logdelta is not None: delta = SP.exp(logdelta) if delta is not None: Sd = (self.S + delta) * scale else: Sd = (h2 * self.S + (1.0 - h2)) * scale UXS = self.UX / NP.lib.stride_tricks.as_strided( Sd, (Sd.size, self.UX.shape[1]), (Sd.itemsize, 0)) UyS = self.Uy / Sd XKX = UXS.T.dot(self.UX) XKy = UXS.T.dot(self.Uy) yKy = UyS.T.dot(self.Uy) logdetK = SP.log(Sd).sum() if (k < N): #low rank part # determine normalization factor if delta is not None: denom = (delta * scale) else: denom = ((1.0 - h2) * scale) XKX += self.UUX.T.dot(self.UUX) / (denom) XKy += self.UUX.T.dot(self.UUy) / (denom) yKy += self.UUy.T.dot(self.UUy) / (denom) logdetK += (N - k) * SP.log(denom) # proximal contamination (see Supplement Note 2: An Efficient Algorithm for Avoiding Proximal Contamination) # available at: http://www.nature.com/nmeth/journal/v9/n6/extref/nmeth.2037-S1.pdf # exclude SNPs from the RRM in the likelihood evaluation if len(self.exclude_idx) > 0: num_exclude = len(self.exclude_idx) # consider only excluded SNPs G_exclude = self.G[:, self.exclude_idx] self.UW = self.U.T.dot( G_exclude) # needed for proximal contamination UWS = self.UW / NP.lib.stride_tricks.as_strided( Sd, (Sd.size, num_exclude), (Sd.itemsize, 0)) assert UWS.shape == (k, num_exclude) WW = NP.eye(num_exclude) - UWS.T.dot(self.UW) WX = UWS.T.dot(self.UX) Wy = UWS.T.dot(self.Uy) assert WW.shape == (num_exclude, num_exclude) assert WX.shape == (num_exclude, D) assert Wy.shape == (num_exclude, ) if (k < N): #low rank part self.UUW = G_exclude - self.U.dot(self.UW) WW += self.UUW.T.dot(self.UUW) / denom WX += self.UUW.T.dot(self.UUX) / denom Wy += self.UUW.T.dot(self.UUy) / denom #TODO: do cholesky, if fails do eigh # compute inverse efficiently [S_WW, U_WW] = LA.eigh(WW) UWX = U_WW.T.dot(WX) UWy = U_WW.T.dot(Wy) assert UWX.shape == (num_exclude, D) assert UWy.shape == (num_exclude, ) # compute S_WW^{-1} * UWX WX = UWX / NP.lib.stride_tricks.as_strided( S_WW, (S_WW.size, UWX.shape[1]), (S_WW.itemsize, 0)) # compute S_WW^{-1} * UWy Wy = UWy / S_WW # determinant update logdetK += SP.log(S_WW).sum() assert WX.shape == (num_exclude, D) assert Wy.shape == (num_exclude, ) # perform updates (instantiations for a and b in Equation (1.5) of Supplement) yKy += UWy.T.dot(Wy) XKy += UWX.T.dot(Wy) XKX += UWX.T.dot(WX) ####### [SxKx, UxKx] = LA.eigh(XKX) #optionally regularize the beta weights by penalty if penalty > 0.0: SxKx += penalty i_pos = SxKx > 1E-10 beta = UxKx[:, i_pos].dot(UxKx[:, i_pos].T.dot(XKy) / SxKx[i_pos]) r2 = yKy - XKy.dot(beta) if dof is None: #Use the Multivariate Gaussian if REML: XX = self.X.T.dot(self.X) [Sxx, Uxx] = LA.eigh(XX) logdetXX = SP.log(Sxx).sum() logdetXKX = SP.log(SxKx).sum() sigma2 = r2 / (N - D) nLL = 0.5 * (logdetK + logdetXKX - logdetXX + (N - D) * (SP.log(2.0 * SP.pi * sigma2) + 1)) variance_beta = None else: sigma2 = r2 / (N) nLL = 0.5 * (logdetK + N * (SP.log(2.0 * SP.pi * sigma2) + 1)) if delta is not None: h2 = 1.0 / (delta + 1) # This is a faster version of h2 * sigma2 * np.diag(LA.inv(XKX)) # where h2*sigma2 is sigma2_g variance_beta = h2 * sigma2 * (UxKx[:, i_pos] / SxKx[i_pos] * UxKx[:, i_pos]).sum(-1) result = { 'nLL': nLL, 'sigma2': sigma2, 'beta': beta, 'variance_beta': variance_beta, 'h2': h2, 'REML': REML, 'a2': self.a2, 'scale': scale } else: #Use multivariate student-t if REML: XX = self.X.T.dot(self.X) [Sxx, Uxx] = LA.eigh(XX) logdetXX = SP.log(Sxx).sum() logdetXKX = SP.log(SxKx).sum() nLL = 0.5 * (logdetK + logdetXKX - logdetXX + (dof + (N - D)) * SP.log(1.0 + r2 / dof)) nLL += 0.5 * (N - D) * SP.log(dof * SP.pi) + SS.gammaln( 0.5 * dof) - SS.gammaln(0.5 * (dof + (N - D))) else: nLL = 0.5 * (logdetK + (dof + N) * SP.log(1.0 + r2 / dof)) nLL += 0.5 * N * SP.log(dof * SP.pi) + SS.gammaln( 0.5 * dof) - SS.gammaln(0.5 * (dof + N)) result = { 'nLL': nLL, 'dof': dof, 'beta': beta, 'variance_beta': None, 'h2': h2, 'REML': REML, 'a2': self.a2, 'scale': scale } assert SP.all( SP.isreal(nLL) ), "nLL has an imaginary component, possibly due to constant covariates" if result['variance_beta'] is None: del result['variance_beta'] return result
def flowisentropic(**flow): """ Evaluate the isentropic relations with any flow variable. This function accepts a given set of specific heat ratios and a single input of isentropic flow variables. Inputs can be a single scalar or an array_like data structure. Parameters ---------- gamma : array_like, optional Specific heat ratio. Values must be greater than 1. M : array_like Mach number. Values must be greater than or equal to 0. T : array_like Temperature ratio T/T0. Values must be 0 <= T <= 1. P : array_like Pressure ratio P/P0. Values must be 0 <= P <= 1. rho : array_like Density ratio rho/rho0. Values must be 0 <= rho <= 1. sub : array_like Subsonic area ratio A/A*. Values must be greater than or equal to 1. sup : array_like Supersonic area ratio A/A*. Values must be greater than or equal to 1. Returns ------- out : (M, T, P, rho, area) Tuple of Mach number, temperature ratio, pressure ratio, density ratio and area ratio. Notes ----- This function accepts one and only one of the isentropic flow variables. It will raise an Exception when more than one input is given. Examples -------- >>> flowisentropic(M=3) (3.0, 0.35714285714285715, 0.027223683703862824, 0.076226314370815895, 4.2345679012345689) >>> flowisentropic(gamma=1.4, sup=1.6) (1.9352576078182122, 0.57174077399894296, 0.14131786852470815, 0.24717122680666009, 1.6000000000000001) >>> flowisentropic(T=sp.linspace(0, 1, 100)) (array, array, array, array, array) """ #parse the input gamma, flow, mtype, itype = _flowinput(flow) #calculate gamma-ratios for use in the equations a = (gamma + 1) / 2 b = (gamma - 1) / 2 c = a / (gamma - 1) #preshape mach array M = sp.empty(flow.shape, sp.float64) #use the isentropic relations to solve for the mach number if mtype in ["mach", "m"]: if (flow < 0).any() or not sp.isreal(flow).all(): raise Exception("Mach number inputs must be real numbers" \ " greater than or equal to 0.") M = flow elif mtype in ["temp", "t"]: if (flow < 0).any() or (flow > 1).any(): raise Exception("Temperature ratio inputs must be real numbers" \ " 0 <= T <= 1.") M[flow == 0] = sp.inf M[flow != 0] = sp.sqrt( (1 / b[flow != 0]) * (flow[flow != 0]**(-1) - 1)) elif mtype in ["pres", "p"]: if (flow < 0).any() or (flow > 1).any(): raise Exception("Pressure ratio inputs must be real numbers" \ " 0 <= P <= 1.") M[flow == 0] = sp.inf M[flow != 0] = sp.sqrt((1/b[flow != 0]) * \ (flow[flow != 0]**((gamma[flow != 0]-1)/-gamma[flow != 0]) - 1)) elif mtype in ["dens", "d", "rho"]: if (flow < 0).any() or (flow > 1).any(): raise Exception("Density ratio inputs must be real numbers" \ " 0 <= rho <= 1.") M[flow == 0] = sp.inf M[flow != 0] = sp.sqrt((1/b[flow != 0]) * \ (flow[flow != 0]**((gamma[flow != 0]-1)/-1) - 1)) elif mtype in ["sub", "sup"]: if (flow < 1).any(): raise Exception("Area ratio inputs must be real numbers greater" \ " than or equal to 1.") M[:] = 0.2 if mtype == "sub" else 1.8 for _ in xrange(_AETB_iternum): K = M**2 f = -flow + a**(-c) * ((1 + b * K)**c) / M #mach-area relation g = a**(-c) * ( (1 + b * K)**(c - 1)) * (b * (2 * c - 1) * K - 1) / K #deriv M = M - (f / g) #Newton-Raphson M[flow == 1] = 1 M[sp.isinf(flow)] = sp.inf else: raise Exception("Keyword input must be an acceptable string to" \ " select input parameter.") d = 1 + b * M**2 T = d**(-1) P = d**(-gamma / (gamma - 1)) rho = d**(-1 / (gamma - 1)) area = sp.empty(M.shape, sp.float64) r = sp.logical_and(M != 0, sp.isfinite(M)) area[r] = a[r]**(-c[r]) * d[r]**c[r] / M[r] area[sp.logical_not(r)] = sp.inf return from_ndarray(itype, M, T, P, rho, area)
def flownormalshock(**flow): """ Evaluate the normal shock wave relations with any flow variable. This function accepts a given set of specific heat ratios and a single input of normal shock wave flow variables. Inputs can be a scalar or an array_like data structure. Parameters ---------- gamma : array_like, optional Specific heat ratio. Values must be greater than 1. M : array_like Upstream Mach number. Values must be greater than or equal to 1. M2 : array_like Downstream Mach number. Values must be SQRT((GAMMA-1)/(2*GAMMA)) <= M <= 1. T : array_like Temperature ratio T2/T1. Values must be greater than or equal to 1. P : array_like Pressure ratio P2/P1. Values must be greater than or equal to 1. rho : array_like Density ratio rho2/rho1. Values must be 1 <= rho <= (GAMMA+1)/(GAMMA-1). P0 : array_like Total pressure ratio P02/P01. Values must be 0 <= P0 <= 1. Pitot : array_like Rayleigh-Pitot ratio P02/P1. Values must be greater than or equal to ((GAMMA+1)/2)**(-GAMMA/(GAMMA+1)). Returns ------- out : (M, M2, T, P, rho, P0, Pitot) Tuple of upstream Mach number, downstream Mach number, temperature ratio, pressure ratio, density ratio, total pressure ratio, rayleigh-pitot ratio. Notes ----- This function accepts one and only one of the normal shock flow variables. It will raise an Exception when more than one input is given. Examples -------- >>> flownormalshock(M=2) (2.0, 0.57735026918962573, 1.6874999999999998, 4.5, 2.666666666666667, 0.72087386148474542, 5.640440812823317) >>> flownormalshock(gamma=1.4, Pitot=3.4) (1.4964833298836788, 0.70233741753226209, 1.3178766042516246, 2.4460394160563674, 1.8560458605647578, 0.93089743233402389, 3.3999999999999977) >>> flownormalshock(M2=[0.5, 0.6, 0.7]) (list, list, list, list, list, list, list) """ #parse the input gamma, flow, mtype, itype = _flowinput(flow) #calculate gamma-ratios for use in the equations a = (gamma + 1) / 2 b = (gamma - 1) / 2 c = gamma / (gamma - 1) #preshape mach array M = sp.empty(flow.shape, sp.float64) #use the normal shock relations to solve for the mach number if mtype in ["mach", "m1", "m"]: if (flow < 1).any(): raise Exception("Mach number inputs must be real numbers" \ " greater than or equal to 1.") M = flow elif mtype in ["down", "mach2", "m2", "md"]: lowerbound = sp.sqrt((gamma - 1) / (2 * gamma)) if (flow < lowerbound).any() or (flow > 1).any(): raise Exception("Mach number downstream inputs must be real" \ " numbers SQRT((GAMMA-1)/(2*GAMMA)) <= M <= 1.") M[flow <= lowerbound] = sp.inf M[flow > lowerbound] = sp.sqrt( (1 + b * flow**2) / (gamma * flow**2 - b)) elif mtype in ["pres", "p"]: if (flow < 1).any() or not sp.isreal(flow).all(): raise Exception("Pressure ratio inputs must be real numbers" \ " greater than or equal to 1.") M = sp.sqrt(((flow - 1) * (gamma + 1) / (2 * gamma)) + 1) elif mtype in ["dens", "d", "rho"]: upperbound = (gamma + 1) / (gamma - 1) if (flow < 1).any() or (flow > upperbound).any(): raise Exception("Density ratio inputs must be real numbers" \ " 1 <= rho <= (GAMMA+1)/(GAMMA-1).") M[flow >= upperbound] = sp.inf M[flow < upperbound] = sp.sqrt(2 * flow / (1 + gamma + flow - flow * gamma)) elif mtype in ["temp", "t"]: if (flow < 1).any(): raise Exception("Temperature ratio inputs must be real numbers" \ " greater than or equal to 1.") B = b + gamma / a - gamma * b / a - flow * a M = sp.sqrt((-B + sp.sqrt(B**2 - \ 4*b*gamma*(1-gamma/a)/a)) / (2*gamma*b/a)) elif mtype in ["totalp", "p0"]: if (flow < 0).any() or (flow > 1).any(): raise Exception("Total pressure ratio inputs must be real" \ " numbers 0 <= P0 <= 1.") M[:] = 2.0 #initial guess for the solution for _ in xrange(_AETB_iternum): f = -flow + (1 + (gamma/a)*(M**2 - 1))**(1-c) \ * (a*M**2 / (1 + b*M**2))**c g = 2*M*(a*M**2 / (b*M**2 + 1))**(c-1)*((gamma* \ (M**2-1))/a + 1)**(-c)*(a*c + gamma*(-c*(b*M**4 + 1) \ + b*M**4 + M**2)) / (b*M**2 + 1)**2 M = M - (f / g) #Newton-Raphson M[flow == 0] = sp.inf elif mtype in ["pito", "pitot", "rp"]: lowerbound = a**c if (flow < lowerbound).any(): raise Exception("Rayleigh-Pitot ratio inputs must be real" \ " numbers greater than or equal to ((G+1)/2)**(-G/(G+1)).") M[:] = 5.0 #initial guess for the solution K = a**(2 * c - 1) for _ in xrange(_AETB_iternum): f = -flow + K * M**(2 * c) / (gamma * M**2 - b)**( c - 1) #Rayleigh-Pitot g = 2 * K * M**(2 * c - 1) * (gamma * M**2 - b)**(-c) * (gamma * M**2 - b * c) M = M - (f / g) #Newton-Raphson else: raise Exception("Keyword input must be an acceptable string to" \ " select input parameter.") #normal shock relations M2 = sp.sqrt((1 + b * M**2) / (gamma * M**2 - b)) rho = ((gamma + 1) * M**2) / (2 + (gamma - 1) * M**2) P = 1 + (M**2 - 1) * gamma / a T = P / rho P0 = P**(1 - c) * rho**(c) P1 = a**(2 * c - 1) * M**(2 * c) / (gamma * M**2 - b)**(c - 1) #handle infinite mach M2[M == sp.inf] = sp.sqrt( (gamma[M == sp.inf] - 1) / (2 * gamma[M == sp.inf])) T[M == sp.inf] = sp.inf P[M == sp.inf] = sp.inf rho[M == sp.inf] = (gamma[M == sp.inf] + 1) / (gamma[M == sp.inf] - 1) P0[M == sp.inf] = 0 P1[M == sp.inf] = sp.inf return from_ndarray(itype, M, M2, T, P, rho, P0, P1)
A.T # matrix A transpose A * A # matrix multiplication A ** 2 # Matrix 2 to the power of 2 (same as A*A) B = 5 * sp.diag([1.0, 3, 5]) sp.mat(B) # converts B to matrix type sp.mat(B).I # computes matrix inverse of sp.mat(B) # isnan, isfinite, isinf are newly added functions to NumPy C = B # copy matrix B into C C[0, 1] = sp.nan # insert NaN value into 1st row, 2nd column element sp.isnan(C) # yields all 'False' elements except one element as True # looking at complex numbers a4 = sp.array([1 + 1j, 2, 5j]) # create complex array sp.iscomplexobj(a4) # determine whether a4 is complex (TRUE) sp.isreal(a4) # determines element by element which are REAL or COMPLEX sp.iscomplex(a4) # determination of COMPLEX elements type(a4) # outputs type and functional dependencies # concatenating matrices and arrays: a5 = sp.array([1, 2, 3]) a6 = sp.array([4, 5, 6]) sp.vstack((a5, a6)) # vertical array concatenation sp.hstack((a5, a6)) # horizontal array concat dstack((a5, a6)) # vertical array concat, transposed # view all variables that have been created thus far: sp.who() # python command, similar to MATLAB # importing and using matplotlib (plotting library from MATLAB) t = sp.linspace(0, 100) # create time array 't'
def __call__(self, X, evalfunc, maxEpochs=100, verbose=True, convergenceThreshold=None): """ Run the conjugate gradient descent. evalfunc is a function handler which has only one input vairble and X is the input module. X should have a property named params and implement a copy method. Generally, X.params should return a numpy/scipy array. An minimal example is given below showing how to use this class: from scipy import array, zeros class T(object): def __init__(self): self._params = array([0.0, 0.0]) @property def params(self): return self._params @params.setter def params(self, value): self._params = value def copy(self): c = T() c.params = self.params.copy() return c class F(object): def __init__(self): self.A = array([[1.0, 1.0], [1.0, 2.0], [1.0, 3.0], [1.0, 4.0], [1.0, 5.0]]) self.b = array([2.0, 3.0, 4.0, 5.0, 6.0]) def cost(self, module): errors = 0.0 G = array([0.0, 0.0]) for i in range(self.A.shape[0]): dx = dot(self.A[i], module.params) - self.b[i] errors += 0.5 * dx * dx G += dx * self.A[i] return errors, G sample_X = T() sample_CostFunction = F() PRConjugateG = PRConjugateGradientDescent(verbose=True) PRConjugateG(sample_X, sample_CostFunction.cost) print sample_X.params """ # The module object must have a property whose name is params and also # implemented the copy function. assert hasattr(X, "params"), "X should have a property named params." assert hasattr(X, "copy"), "X should have a copy method." # Print the optimizer parameters print(self) epoch = 0 lineSearchFailed = False strfmt = "Epoch {" + ":{:d}".format(len(str(maxEpochs))) + "d} | error: {:.12f}" realmin = finfo(float).tiny reason = "" # Get function value and gradient f1, g1 = evalfunc(X) fX = [] # Search direction is the steepest s = -g1.copy() # This is the slope d1 = -dot(s, s) # Initial step is 1.0 / (1.0 - d1) z1 = 1.0 / (1.0 - d1) # Setup the convergence threhold minDelta = 1e-8 minRatio = 1e-6 if convergenceThreshold is not None: deltaThreshold = convergenceThreshold[0] ratioThreshold = convergenceThreshold[1] while epoch < maxEpochs: epoch += 1 # make a copy of current values X0 = X.copy() f0 = f1 g0 = g1.copy() # begin line search X.params[:] += z1 * s f2, g2 = evalfunc(X) d2 = dot(g2, s) # initialize point 3 equal to point 1 f3 = f1 d3 = d1 z3 = -z1 M = self.maxEvaluate success = False limit = -1.0 # declare some global variables A = 0.0 B = 0.0 z2 = 0.0 while True: while (f2 > f1 + z1 * self.RHO * d1 or d2 > -self.SIG * d1) and M > 0: # tighten the bracket limit = z1 if f2 > f1: z2 = self.quadraticFit(z3, d3, f2, f3) else: A, B, z2 = self.cubicFit(d2, d3, f2, f3, z3) # if we have a numerical problem then bisect if isnan(z2) or isinf(z2): z2 = z3 * 0.5 # do not accept too close to limits z2 = min(z2, self.reEvaluate * z3) z2 = max(z2, (1.0 - self.reEvaluate) * z3) # update the step z1 += z2; X.params[:] += z2 * s; f2, g2 = evalfunc(X) M -= 1; d2 = dot(g2, s) # z3 is now relative to the location of z2 z3 -= z2 pass # this is a failure if f2 > f1 + z1 * self.RHO * d1 or d2 > -self.SIG * d1: break elif d2 > self.SIG * d1: success = True break # this is also a failure elif M == 0: break # make cubic extrapolation A, B, z2 = self.cubicExtrapolate(d2, d3, f2, f3, z3) # numeric problem or wrong sign if not isreal(z2) or isnan(z2) or isinf(z2) or z2 < 0.0: if limit < -0.5: z2 = z1 * (self.extrapolate - 1.0) else: z2 = (limit - z1) * 0.5 # extrapolation beyond max elif limit > -0.5 and (z2 + z1) > limit: z2 = (limit - z1) * 0.5 # extrapolation beyond limit elif limit < -0.5 and (z2 + z1) > z1 * self.extrapolate: z2 = z1 * (self.extrapolate - 1.0) elif z2 < -z3 * self.reEvaluate: z2 = -z3 * self.reEvaluate # too close to limit elif limit > -0.5 and z2 < (limit - z1) * (1.0 - self.reEvaluate): z2 = (limit - z1) * (1.0 - self.reEvaluate) # set point 3 equal to point 2 f3 = f2 d3 = d2 z3 = -z2 # update current estimate z1 += z2 X.params[:] += z2 * s f2, g2 = evalfunc(X) M -= 1 d2 = dot(g2, s) pass if success == True: fX.append(f2) if verbose: print(strfmt.format(epoch, f2)) # The error decrease rate is below the convergence criteria, so # the optimization is done successfully. if (f1 - f2) < deltaThreshold or (f1 - f2) / f1 < ratioThreshold: break f1 = f2 # Polack-Ribiere direction s = (dot(g2, g2) - dot(g1, g2)) / dot(g1, g1) * s - g2 # swap derivatives tmp = g1 g1 = g2 g2 = tmp d2 = dot(g1, s) # new slope must be positive, otherwise use steepest direction if d2 > 0.0: s = -g1 d2 = -dot(s, s) z1 *= min(self.maxSlope, d1 / (d2 - realmin)) d1 = d2 lineSearchFailed = False else: # restore point from the point before line search X = X0.copy() f1 = f0 g1 = g0 # line search failed twice in a row or we ran out of time if lineSearchFailed: reason = "Line search failed twice in a row!" break if epoch > maxEpochs: reason = "Maximum number of epochs reached!" break # swap derivatives tmp = g1 g1 = g2 g2 = tmp # try steepest s = -g1 d1 = -dot(s, s) z1 = 1.0 / (1.0 - d1) lineSearchFailed = True if success: print("PRCG converged with {:d} epochs. Final error: {:f}".format(epoch, f1)) else: print("PRCG failed to converge: {:s}".format(reason)) return fX
def recover_M3_we( k, P12, P13, P123, P12e, P13e, P123e, delta=0.01 ): """Recover M3 from P_12, P_13 and P_123 (with error information)""" d, _ = P12.shape # Inputs logger.add_err( "P12", P12e, P12, 2 ) logger.add_consts( "P12", P12e, k, 2 ) logger.add_err( "P13", P12e, P12, 2 ) logger.add_consts( "P13", P12e, k, 2 ) logger.add_terr( "P123", P123e, P123, d ) logger.add_tconsts( "P123", P123e, d ) # Get singular vectors U1, _, U2 = svdk( P12, k ) _, _, U3 = svdk( P13, k ) U2, U3 = U2.T, U3.T U1e, _, U2e = svdk( P12, k ) _, _, U3e = svdk( P13, k ) U2e, U3e = U2e.T, U3e.T # Check U_1.T P_{12} U_2 is invertible assert( sc.absolute( det( U1.T.dot( P12 ).dot( U2 ) ) ) > 1e-16 ) while True: # Get a random basis set theta = orthogonal( k ) P12i = inv( U1.T.dot( P12 ).dot( U2 ) ) #B123_ = sc.einsum( 'ijk,ia,jb,kc->abc', P123, U1, U2, U3 ) #B123 = sc.einsum( 'ajc,jb ->abc', B123_, P12i ) B123 = lambda theta: U1.T.dot( P123( U3.dot( theta ) ) ).dot( U2 ).dot( P12i ) P12ie = inv( U1e.T.dot( P12e ).dot( U2e ) ) #B123e_ = sc.einsum( 'ijk,ia,jb,kc->abc', P123e, U1e, U2e, U3e ) #B123e = sc.einsum( 'ajc,jb ->abc', B123e_, P12ie ) B123e = lambda theta: U1e.T.dot( P123e( U3e.dot( theta ) ) ).dot( U2e ).dot( P12ie ) logger.add_terr( "B123", B123, B123e, k ) l, R1 = eig( B123( theta.T[0] ) ) R1 = array( map( lambda col: col/norm(col), R1.T ) ).T assert( norm(R1.T[0]) - 1.0 < 1e-10 ) le, R1e = eig( B123e( theta.T[0] ) ) logger.add_err( "R", R1e, R1, 2 ) logger.add_consts( "R", R1e, k, 2 ) # Restart if not ( sc.isreal( l ).all() ): continue L = [l.real] for i in xrange( 1, k ): l = diag( inv(R1).dot( B123( theta.T[i] ).dot( R1 ) ) ) # Restart if not ( sc.isreal( l ).all() ): continue L.append( l ) L = array( sc.vstack( L ) ) Le = [le.real] for i in xrange( 1, k ): le = diag( inv(R1e).dot( B123e( theta.T[i] ).dot( R1e ) ) ) Le.append( le ) Le = array( sc.vstack( Le ) ) logger.add_err( "L", Le, L, 2 ) M3_ = U3.dot( inv(theta.T) ).dot( L ) return M3_
def recover_components( k, P, T, Pe, Te, delta=0.01 ): """Recover the k components given input moments M2 and M3 (Pe, Te) are exact P and T""" d, _ = P.shape # Input error logger.add_err( "P", Pe, P, 2 ) logger.add_consts( "Pe", Pe, k, 2 ) logger.add_consts( "P", P, k, 2 ) logger.add_terr( "T", Te, T, d ) logger.add_tconsts( "Te", Te, d ) logger.add_tconsts( "T", T, d ) # Get the whitening matrix of M2 W, Wt = get_whitener( P, k ) We, _ = get_whitener( Pe, k ) logger.add_err( "W", We, W, 2 ) logger.add_consts( "We", We, k, 2 ) logger.add_consts( "W", W, k, 2 ) Tw = lambda theta: W.T.dot( T( W.dot( theta ) ) ).dot( W ) Twe = lambda theta: We.T.dot( Te( We.dot( theta ) ) ).dot( We ) #Tw = sc.einsum( 'ijk,ia,jb,kc->abc', T, W, W, W ) #Twe = sc.einsum( 'ijk,ia,jb,kc->abc', Te, We, We, We ) logger.add_terr( "Tw", Twe, Tw, k ) # Repeat [-\log(\delta] times for confidence 1-\delta to find best # \theta t = int( sc.ceil( -log( delta ) ) ) best = (-sc.inf, None, None) for i in xrange( t ): # Project Tw onto a matrix theta = sc.rand( k ) theta = theta/theta.sum() # Find the eigen separation X = Tw(theta) #X = Tw.dot(theta) sep = column_sep( X ) if sep > best[0]: best = sep, theta, X # Find the eigenvectors as well sep, theta, X = best S, U = eig( X, left=True, right=False ) assert( sc.isreal( S ).all() and sc.isreal( U ).all() ) S, U = S.real, U.real Xe = Twe( theta ) ##Xe = Twe.dot( theta ) sepe = column_sep( Xe ) Se, Ue = eig( Xe, left=True, right=False ) Se, Ue = Se.real, Ue.real logger.add( "D", sep/sepe ) logger.add_err( "lambda", Se, S, sc.inf ) logger.add_err( "v", Se, S, 'col' ) M = sc.zeros( (d, k) ) for i in xrange(k): M[:, i] = S[i]/theta.dot(U.T[i]) * Wt.dot(U.T[i]) return M
def nLLeval(self,h2=0.0,REML=True, logdelta = None, delta = None, dof = None, scale = 1.0,penalty=0.0): ''' evaluate -ln( N( U^T*y | U^T*X*beta , h2*S + (1-h2)*I ) ), where ((1-a2)*K0 + a2*K1) = USU^T -------------------------------------------------------------------------- Input: h2 : mixture weight between K and Identity (environmental noise) REML : boolean if True : compute REML if False : compute ML dof : Degrees of freedom of the Multivariate student-t (default None uses multivariate Normal likelihood) logdelta: log(delta) allows to optionally parameterize in delta space delta : delta allows to optionally parameterize in delta space scale : Scale parameter the multiplies the Covariance matrix (default 1.0) -------------------------------------------------------------------------- Output dictionary: 'nLL' : negative log-likelihood 'sigma2' : the model variance sigma^2 'beta' : [D*1] array of fixed effects weights beta 'h2' : mixture weight between Covariance and noise 'REML' : True: REML was computed, False: ML was computed 'a2' : mixture weight between K0 and K1 'dof' : Degrees of freedom of the Multivariate student-t (default None uses multivariate Normal likelihood) 'scale' : Scale parameter that multiplies the Covariance matrix (default 1.0) -------------------------------------------------------------------------- ''' if (h2<0.0) or (h2>1.0): return {'nLL':3E20, 'h2':h2, 'REML':REML, 'scale':scale} k=self.S.shape[0] N=self.y.shape[0] D=self.UX.shape[1] #if REML == True: # # this needs to be fixed, please see test_gwas.py for details # raise NotImplementedError("this feature is not ready to use at this time, please use lmm_cov.py instead") if logdelta is not None: delta = SP.exp(logdelta) if delta is not None: Sd = (self.S+delta)*scale else: Sd = (h2*self.S + (1.0-h2))*scale UXS = self.UX / NP.lib.stride_tricks.as_strided(Sd, (Sd.size,self.UX.shape[1]), (Sd.itemsize,0)) UyS = self.Uy / Sd XKX = UXS.T.dot(self.UX) XKy = UXS.T.dot(self.Uy) yKy = UyS.T.dot(self.Uy) logdetK = SP.log(Sd).sum() if (k<N):#low rank part # determine normalization factor if delta is not None: denom = (delta*scale) else: denom = ((1.0-h2)*scale) XKX += self.UUX.T.dot(self.UUX)/(denom) XKy += self.UUX.T.dot(self.UUy)/(denom) yKy += self.UUy.T.dot(self.UUy)/(denom) logdetK+=(N-k) * SP.log(denom) # proximal contamination (see Supplement Note 2: An Efficient Algorithm for Avoiding Proximal Contamination) # available at: http://www.nature.com/nmeth/journal/v9/n6/extref/nmeth.2037-S1.pdf # exclude SNPs from the RRM in the likelihood evaluation if len(self.exclude_idx) > 0: num_exclude = len(self.exclude_idx) # consider only excluded SNPs G_exclude = self.G[:,self.exclude_idx] self.UW = self.U.T.dot(G_exclude) # needed for proximal contamination UWS = self.UW / NP.lib.stride_tricks.as_strided(Sd, (Sd.size,num_exclude), (Sd.itemsize,0)) assert UWS.shape == (k, num_exclude) WW = NP.eye(num_exclude) - UWS.T.dot(self.UW) WX = UWS.T.dot(self.UX) Wy = UWS.T.dot(self.Uy) assert WW.shape == (num_exclude, num_exclude) assert WX.shape == (num_exclude, D) assert Wy.shape == (num_exclude,) if (k<N):#low rank part self.UUW = G_exclude - self.U.dot(self.UW) WW += self.UUW.T.dot(self.UUW)/denom WX += self.UUW.T.dot(self.UUX)/denom Wy += self.UUW.T.dot(self.UUy)/denom #TODO: do cholesky, if fails do eigh # compute inverse efficiently [S_WW,U_WW] = LA.eigh(WW) UWX = U_WW.T.dot(WX) UWy = U_WW.T.dot(Wy) assert UWX.shape == (num_exclude, D) assert UWy.shape == (num_exclude,) # compute S_WW^{-1} * UWX WX = UWX / NP.lib.stride_tricks.as_strided(S_WW, (S_WW.size,UWX.shape[1]), (S_WW.itemsize,0)) # compute S_WW^{-1} * UWy Wy = UWy / S_WW # determinant update logdetK += SP.log(S_WW).sum() assert WX.shape == (num_exclude, D) assert Wy.shape == (num_exclude,) # perform updates (instantiations for a and b in Equation (1.5) of Supplement) yKy += UWy.T.dot(Wy) XKy += UWX.T.dot(Wy) XKX += UWX.T.dot(WX) ####### [SxKx,UxKx]= LA.eigh(XKX) #optionally regularize the beta weights by penalty if penalty>0.0: SxKx+=penalty i_pos = SxKx>1E-10 beta = SP.dot(UxKx[:,i_pos],(SP.dot(UxKx[:,i_pos].T,XKy)/SxKx[i_pos])) r2 = yKy-XKy.dot(beta) if dof is None:#Use the Multivariate Gaussian if REML: XX = self.X.T.dot(self.X) [Sxx,Uxx]= LA.eigh(XX) logdetXX = SP.log(Sxx).sum() logdetXKX = SP.log(SxKx).sum() sigma2 = r2 / (N - D) nLL = 0.5 * ( logdetK + logdetXKX - logdetXX + (N-D) * ( SP.log(2.0*SP.pi*sigma2) + 1 ) ) else: sigma2 = r2 / (N) nLL = 0.5 * ( logdetK + N * ( SP.log(2.0*SP.pi*sigma2) + 1 ) ) result = { 'nLL':nLL, 'sigma2':sigma2, 'beta':beta, 'h2':h2, 'REML':REML, 'a2':self.a2, 'scale':scale } else:#Use multivariate student-t if REML: XX = self.X.T.dot(self.X) [Sxx,Uxx]= LA.eigh(XX) logdetXX = SP.log(Sxx).sum() logdetXKX = SP.log(SxKx).sum() nLL = 0.5 * ( logdetK + logdetXKX - logdetXX + (dof + (N-D)) * SP.log(1.0+r2/dof) ) nLL += 0.5 * (N-D)*SP.log( dof*SP.pi ) + SS.gammaln( 0.5*dof ) - SS.gammaln( 0.5* (dof + (N-D) )) else: nLL = 0.5 * ( logdetK + (dof + N) * SP.log(1.0+r2/dof) ) nLL += 0.5 * N*SP.log( dof*SP.pi ) + SS.gammaln( 0.5*dof ) - SS.gammaln( 0.5* (dof + N )) result = { 'nLL':nLL, 'dof':dof, 'beta':beta, 'h2':h2, 'REML':REML, 'a2':self.a2, 'scale':scale } assert SP.all(SP.isreal(nLL)), "nLL has an imaginary component, possibly due to constant covariates" return result
def real_and_positive(x): return sp.isreal(x) and x > 0
def non_infinitesimal_mcmc(beta_hats, Pi, Sigi2, sig_12, start_betas=None, h2=None, n=1000, ld_radius=100, num_iter=60, burn_in=10, zero_jump_prob=0.05, ld_dict=None): """ MCMC of non-infinitesimal model """ m = len(beta_hats) curr_betas = sp.copy(start_betas) curr_post_means = sp.zeros(m) avg_betas = sp.zeros(m) # Iterating over effect estimates in sequential order iter_order = sp.arange(m) for k in range(num_iter): #Big iteration #Force an alpha shrink if estimates are way off compared to heritability estimates. (Improves MCMC convergence.) h2_est = max(0.00001, sp.sum(curr_betas**2)) alpha = min(1 - zero_jump_prob, 1.0 / h2_est, (h2 + 1 / sp.sqrt(n)) / h2_est) rand_ps = sp.random.random(m) for i, snp_i in enumerate(iter_order): if Sigi2[snp_i] == 0: curr_post_means[snp_i] = 0 curr_betas[snp_i] = 0 else: hdmp = (Sigi2[snp_i] / Pi[snp_i]) #(h2 / Mp) hdmpn = hdmp + sig_12 #1.0 / n hdmp_hdmpn = (hdmp / hdmpn) c_const = (Pi[snp_i] / sp.sqrt(hdmpn)) d_const = (1 - Pi[snp_i]) / (sp.sqrt(sig_12)) start_i = max(0, snp_i - ld_radius) focal_i = min(ld_radius, snp_i) stop_i = min(m, snp_i + ld_radius + 1) #Local LD matrix D_i = ld_dict[snp_i] #Local (most recently updated) effect estimates local_betas = curr_betas[start_i:stop_i] #Calculate the local posterior mean, used when sampling. local_betas[focal_i] = 0 res_beta_hat_i = beta_hats[snp_i] - sp.dot(D_i, local_betas) b2 = res_beta_hat_i**2 d_const_b2_exp = d_const * sp.exp(-b2 / (2.0 * sig_12)) if sp.isreal(d_const_b2_exp): numerator = c_const * sp.exp(-b2 / (2.0 * hdmpn)) if sp.isreal(numerator): if numerator == 0: postp = 0 else: postp = numerator / (numerator + d_const_b2_exp) assert sp.isreal( postp), 'Posterior mean is not a real number?' else: postp = 0 else: postp = 1 curr_post_means[snp_i] = hdmp_hdmpn * postp * res_beta_hat_i if rand_ps[i] < postp * alpha: #Sample from the posterior Gaussian dist. proposed_beta = stats.norm.rvs( 0, (hdmp_hdmpn) * sig_12, size=1) + hdmp_hdmpn * res_beta_hat_i else: #Sample 0 proposed_beta = 0 curr_betas[snp_i] = proposed_beta #UPDATE BETA if k >= burn_in: avg_betas += curr_post_means #Averaging over the posterior means instead of samples. avg_betas = avg_betas / float(num_iter - burn_in) return {'betas': avg_betas, 'inf_betas': start_betas}
def entropic_reestimate(omega, theta=None, Z=1, maxiter=100, tol=1e-7, verbose=False): """ Re-estimates a statistic parameter vector entropically [1]_. Parameters ---------- omega : array_like Evidence vector theta : array_like, optional Parameter vector to be re-estimated under given evidence and learning rate (default None) Z : {-1, 0, +1}, optional -1: Algorithm reduces to traditional MLE (e.g the Baum-Welch) 0: ? +1: Algorithm will seek maximum structure maxiter : int, optional Maximum number of iterations of Fixed-point loop (default 100) verbose : bool, optional Display verbose output (default off) Returns ------- theta_hat : array_like Learned parameter vector Z : float Final Learning rate _lambda : float Limiting value of Lagrange multiplier Examples -------- >>> from entropy_map import entropic_reestimate >>> omega = [1, 2] >>> theta = [0.50023755, 0.49976245] >>> theta_hat, final_Z, _lambda = entropic_reestimate(omega, theta, Z=1, tol=1e-6) >>> theta_hat array([ 0.33116253, 0.66883747]) >>> final_Z 0.041828014112488016 >>> _lambda -3.0152672618320637 References ---------- .. [1] Matthiew Brand, "Pattern learning via entropy maximization" """ def _debug(msg=''): if verbose: print msg # XXX TODO: handle Z = 0 case assert Z != 0 # if no initial theta specified, start with uniform candidate if theta is None: theta = almost_uniform_vector(len(omega)) # all arrays must be numpy-like omega = array(omega, dtype='float64') theta = array(theta, dtype='float64') # XXX TODO: trim-off any evidence which 'relatively close to 0' (since such evidence can't justify anything!) informative_indices = nonzero(minimum(omega, theta) > _EPSILON) _omega = omega[informative_indices] _theta = theta[informative_indices] # prepare initial _lambda which will ensure that Lambert's W is real-valued if Z > 0: critical_lambda = min(-Z*(2 + log(_omega/Z))) _lambda = critical_lambda - 1 # or anything less than the critical value above elif Z < 0: # make an educated guess _lambda = -mean(Z*(log(_theta) + 1) + _omega/_theta) assert all(-_omega*exp(1+_lambda/Z)/Z > -1/e), -_omega*exp(1+_lambda/Z)/Z # Fixed-point loop _theta_hat = _theta iteration = 0 converged = False _debug("entropy_map: starting Fixed-point loop ..\n") _debug("Initial model: %s"%_theta) _debug("Initial lambda: %s"%_lambda) _debug("Initila learning rate (Z): %s"%Z) while not converged: # exhausted ? if maxiter <= iteration: break # if necessary, re-scale learning rate (Z) so that exp(1 + _lambda/Z) is not 'too small' if _lambda < 0: if Z > 0: new_Z = -_lambda/_BEAR elif Z < 0: new_Z = _lambda/_BEAR if new_Z != Z: Z = new_Z _debug("N.B:- We'll re-scale learning rate (Z) to %s to prevent Lambert's W function from vanishing."%(Z)) # prepare argument (vector) for Lambert's W function z = -_omega*exp(1 + _lambda/Z)/Z assert all(isreal(z)) if any(z < -1/e): _debug("Lambert's W: argument z = %s out of range (-1/e, +inf)"%z) break # compute Lambert's W function at z if Z <= 0: g = W(z, k=0) else: g = W(z, k=-1) assert all(isreal(g)) g = real(g) # check against division by zero (btw we re-scaled Z to prevent this) # assert all(g != 0) assert all(abs(g) > _EPSILON) # re-estimate _theta _theta_hat = (-_omega/Z)/g assert all(_theta_hat >= 0) # normalize the approximated _theta_hat parameter _theta_hat = normalize_probabilities(_theta_hat) # re-estimate _lambda _lambda_hat = -(Z*(log(_theta_hat[0]) + 1) + _omega[0]/_theta_hat[0]) # [0] or any other index [i] # check whether _lambda values have convergede converged, _, relative_error = check_converged(_lambda, _lambda_hat, tol=tol) # verbose for debugging, etc. _debug("Iteration: %d"%iteration) _debug('Current parameter estimate:\n%s'%_theta) _debug('lambda: %s'%_lambda) _debug("Relative error in lambda over last iteration: %s"%relative_error) _debug("Learning rate (Z): %s"%Z) # update _lambda and _theta _lambda = _lambda_hat _theta = _theta_hat # goto next iteration iteration += 1 _debug('\n') _debug("Done.") _debug('Final parameter estimate:\n%s'%_theta) _debug('lambda: %s'%_lambda) _debug("Relative error in lambda over last iteration: %s"%relative_error) _debug("Learning rate (Z): %s"%Z) # converged ? if converged: _debug("entropic_reestimate: loop converged after %d iterations (tolerance was set to %s)"%(iteration,tol)) else: _debug("entropic_reestimate: loop did not converge after %d iterations (tolerance was set to %s)"\ %(maxiter,tol)) # render results theta_hat = 0*theta theta_hat[informative_indices] = _theta_hat return theta_hat, Z, _lambda
def flowisentropic(**flow): """ Evaluate the isentropic relations with any flow variable. This function accepts a given set of specific heat ratios and a single input of isentropic flow variables. Inputs can be a single scalar or an array_like data structure. Parameters ---------- gamma : array_like, optional Specific heat ratio. Values must be greater than 1. M : array_like Mach number. Values must be greater than or equal to 0. T : array_like Temperature ratio T/T0. Values must be 0 <= T <= 1. P : array_like Pressure ratio P/P0. Values must be 0 <= P <= 1. rho : array_like Density ratio rho/rho0. Values must be 0 <= rho <= 1. sub : array_like Subsonic area ratio A/A*. Values must be greater than or equal to 1. sup : array_like Supersonic area ratio A/A*. Values must be greater than or equal to 1. Returns ------- out : (M, T, P, rho, area) Tuple of Mach number, temperature ratio, pressure ratio, density ratio and area ratio. Notes ----- This function accepts one and only one of the isentropic flow variables. It will raise an Exception when more than one input is given. Examples -------- >>> flowisentropic(M=3) (3.0, 0.35714285714285715, 0.027223683703862824, 0.076226314370815895, 4.2345679012345689) >>> flowisentropic(gamma=1.4, sup=1.6) (1.9352576078182122, 0.57174077399894296, 0.14131786852470815, 0.24717122680666009, 1.6000000000000001) >>> flowisentropic(T=sp.linspace(0, 1, 100)) (array, array, array, array, array) """ #parse the input gamma, flow, mtype, itype = _flowinput(flow) #calculate gamma-ratios for use in the equations a = (gamma+1) / 2 b = (gamma-1) / 2 c = a / (gamma-1) #preshape mach array M = sp.empty(flow.shape, sp.float64) #use the isentropic relations to solve for the mach number if mtype in ["mach", "m"]: if (flow < 0).any() or not sp.isreal(flow).all(): raise Exception("Mach number inputs must be real numbers" \ " greater than or equal to 0.") M = flow elif mtype in ["temp", "t"]: if (flow < 0).any() or (flow > 1).any(): raise Exception("Temperature ratio inputs must be real numbers" \ " 0 <= T <= 1.") M[flow == 0] = sp.inf M[flow != 0] = sp.sqrt((1/b[flow != 0])*(flow[flow != 0]**(-1) - 1)) elif mtype in ["pres", "p"]: if (flow < 0).any() or (flow > 1).any(): raise Exception("Pressure ratio inputs must be real numbers" \ " 0 <= P <= 1.") M[flow == 0] = sp.inf M[flow != 0] = sp.sqrt((1/b[flow != 0]) * \ (flow[flow != 0]**((gamma[flow != 0]-1)/-gamma[flow != 0]) - 1)) elif mtype in ["dens", "d", "rho"]: if (flow < 0).any() or (flow > 1).any(): raise Exception("Density ratio inputs must be real numbers" \ " 0 <= rho <= 1.") M[flow == 0] = sp.inf M[flow != 0] = sp.sqrt((1/b[flow != 0]) * \ (flow[flow != 0]**((gamma[flow != 0]-1)/-1) - 1)) elif mtype in ["sub", "sup"]: if (flow < 1).any(): raise Exception("Area ratio inputs must be real numbers greater" \ " than or equal to 1.") M[:] = 0.2 if mtype == "sub" else 1.8 for _ in xrange(_AETB_iternum): K = M ** 2 f = -flow + a**(-c) * ((1+b*K)**c) / M #mach-area relation g = a**(-c) * ((1+b*K)**(c-1)) * (b*(2*c - 1)*K - 1) / K #deriv M = M - (f / g) #Newton-Raphson M[flow == 1] = 1 M[sp.isinf(flow)] = sp.inf else: raise Exception("Keyword input must be an acceptable string to" \ " select input parameter.") d = 1 + b*M**2 T = d**(-1) P = d**(-gamma/(gamma-1)) rho = d**(-1/(gamma-1)) area = sp.empty(M.shape, sp.float64) r = sp.logical_and(M != 0, sp.isfinite(M)) area[r] = a[r]**(-c[r]) * d[r]**c[r] / M[r] area[sp.logical_not(r)] = sp.inf return from_ndarray(itype, M, T, P, rho, area)
def non_infinitesimal_mcmc(beta_hats, Pi, Sigi2, sig_12, start_betas=None, h2=None, n=1000, ld_radius=100, num_iter=60, burn_in=10, zero_jump_prob=0.05, ld_dict=None): """ MCMC of non-infinitesimal model """ m = len(beta_hats) curr_betas = sp.copy(start_betas) curr_post_means = sp.zeros(m) avg_betas = sp.zeros(m) # Iterating over effect estimates in sequential order iter_order = sp.arange(m) for k in range(num_iter): #Big iteration #Force an alpha shrink if estimates are way off compared to heritability estimates. (Improves MCMC convergence.) h2_est = max(0.00001,sp.sum(curr_betas ** 2)) alpha = min(1-zero_jump_prob, 1.0 / h2_est, (h2 + 1 / sp.sqrt(n)) / h2_est) rand_ps = sp.random.random(m) for i, snp_i in enumerate(iter_order): if Sigi2[snp_i]==0: curr_post_means[snp_i] = 0 curr_betas[snp_i] = 0 else: hdmp = (Sigi2[snp_i]/Pi[snp_i])#(h2 / Mp) hdmpn = hdmp + sig_12#1.0 / n hdmp_hdmpn = (hdmp / hdmpn) c_const = (Pi[snp_i] / sp.sqrt(hdmpn)) d_const = (1 - Pi[snp_i]) / (sp.sqrt(sig_12)) start_i = max(0, snp_i - ld_radius) focal_i = min(ld_radius, snp_i) stop_i = min(m, snp_i + ld_radius + 1) #Local LD matrix D_i = ld_dict[snp_i] #Local (most recently updated) effect estimates local_betas = curr_betas[start_i: stop_i] #Calculate the local posterior mean, used when sampling. local_betas[focal_i] = 0 res_beta_hat_i = beta_hats[snp_i] - sp.dot(D_i , local_betas) b2 = res_beta_hat_i ** 2 d_const_b2_exp = d_const * sp.exp(-b2 / (2.0*sig_12)) if sp.isreal(d_const_b2_exp): numerator = c_const * sp.exp(-b2 / (2.0 * hdmpn)) if sp.isreal(numerator): if numerator == 0: postp = 0 else: postp = numerator / (numerator + d_const_b2_exp) assert sp.isreal(postp), 'Posterior mean is not a real number?' else: postp = 0 else: postp = 1 curr_post_means[snp_i] = hdmp_hdmpn * postp * res_beta_hat_i if rand_ps[i] < postp * alpha: #Sample from the posterior Gaussian dist. proposed_beta = stats.norm.rvs(0, (hdmp_hdmpn) * sig_12, size=1) + hdmp_hdmpn * res_beta_hat_i else: #Sample 0 proposed_beta = 0 curr_betas[snp_i] = proposed_beta #UPDATE BETA if k >= burn_in: avg_betas += curr_post_means #Averaging over the posterior means instead of samples. avg_betas = avg_betas/float(num_iter-burn_in) return {'betas':avg_betas, 'inf_betas':start_betas}
def duff_amp_solve(mu = 0.01, k = 0.013, alpha = .2, sigma = (-0.5,.5)): sigma = sp.linspace(sigma[0],sigma[1],1000) #print(sigma.size) #print(sigma) a = sp.zeros((sigma.size,3))*1j first = 1 #print(a) for idx, sig in enumerate(sigma): #print(idx) p = sp.array([alpha**2, 0, -16./3.*alpha*sig, 0, 64./9.*(mu**2 + sig**2),0,-64./9.*k**2]) soln = sp.roots(p) #print('original soln') #print(soln) #print(soln) #print(sp.sort(soln)[0:5:2]) sorted_indices = sp.argsort(sp.absolute(soln)) a[idx,:] = soln[sorted_indices][0:5:2] if sum(sp.isreal(a[idx,:])) == 3 and first == 1: first = 0 #if sp.absolute(a[idx,2] - a[idx,1]) < sp.absolute(a[idx,1] - a[idx,0]): solns = sp.sort(sp.absolute(a[idx,:])) #print(solns) if (solns[2] - solns[1]) > (solns[1]-solns[0]): ttl = 'Hardening spring' softening = False else: ttl = 'Softening spring' softening = True #print(solns) first_bif_index = idx if first == 0 and sum(sp.isreal(a[idx,:])) == 1: first = 2 second_bif_index = idx if softening == True: low_sig = sigma[0:second_bif_index] low_amp = sp.zeros(second_bif_index) low_amp[0:first_bif_index] = sp.absolute(sp.sum(sp.isreal(a[0:first_bif_index,:])*a[0:first_bif_index,:],axis = 1)) low_amp[first_bif_index:second_bif_index] = sp.absolute(a[first_bif_index:second_bif_index,:]).min(axis = 1) med_sig = sigma[first_bif_index:second_bif_index] med_amp = sp.sort(sp.absolute(a[first_bif_index:second_bif_index,:]),axis = 1)[:,1] high_sig = sigma[first_bif_index:] high_amp = sp.zeros(sigma.size - first_bif_index) high_amp[0:second_bif_index - first_bif_index] = sp.absolute(a[first_bif_index:second_bif_index,:]).max(axis = 1) high_amp[second_bif_index - first_bif_index:] = sp.absolute(sp.sum(sp.isreal(a[second_bif_index:,:])*a[second_bif_index:,:],axis = 1)) else: high_sig = sigma[0:second_bif_index] high_amp = sp.zeros(second_bif_index) high_amp[0:first_bif_index] = sp.absolute(sp.sum(sp.isreal(a[0:first_bif_index,:])*a[0:first_bif_index,:],axis = 1)) high_amp[first_bif_index:second_bif_index] = sp.absolute(a[first_bif_index:second_bif_index,:]).max(axis = 1) med_sig = sigma[first_bif_index:second_bif_index] med_amp = sp.sort(sp.absolute(a[first_bif_index:second_bif_index,:]),axis = 1)[:,1] low_sig = sigma[first_bif_index:] low_amp = sp.zeros(sigma.size - first_bif_index) low_amp[0:second_bif_index - first_bif_index] = sp.absolute(a[first_bif_index:second_bif_index,:]).min(axis = 1) low_amp[second_bif_index - first_bif_index:] = sp.absolute(sp.sum(sp.isreal(a[second_bif_index:,:])*a[second_bif_index:,:],axis = 1)) plt.plot(low_sig,low_amp,'-b') plt.plot(med_sig, med_amp, '--g') plt.plot(high_sig,high_amp,'-r') plt.title(ttl) plt.xlabel('$\sigma$') plt.ylabel('a') return
def flownormalshock(**flow): """ Evaluate the normal shock wave relations with any flow variable. This function accepts a given set of specific heat ratios and a single input of normal shock wave flow variables. Inputs can be a scalar or an array_like data structure. Parameters ---------- gamma : array_like, optional Specific heat ratio. Values must be greater than 1. M : array_like Upstream Mach number. Values must be greater than or equal to 1. M2 : array_like Downstream Mach number. Values must be SQRT((GAMMA-1)/(2*GAMMA)) <= M <= 1. T : array_like Temperature ratio T2/T1. Values must be greater than or equal to 1. P : array_like Pressure ratio P2/P1. Values must be greater than or equal to 1. rho : array_like Density ratio rho2/rho1. Values must be 1 <= rho <= (GAMMA+1)/(GAMMA-1). P0 : array_like Total pressure ratio P02/P01. Values must be 0 <= P0 <= 1. Pitot : array_like Rayleigh-Pitot ratio P02/P1. Values must be greater than or equal to ((GAMMA+1)/2)**(-GAMMA/(GAMMA+1)). Returns ------- out : (M, M2, T, P, rho, P0, Pitot) Tuple of upstream Mach number, downstream Mach number, temperature ratio, pressure ratio, density ratio, total pressure ratio, rayleigh-pitot ratio. Notes ----- This function accepts one and only one of the normal shock flow variables. It will raise an Exception when more than one input is given. Examples -------- >>> flownormalshock(M=2) (2.0, 0.57735026918962573, 1.6874999999999998, 4.5, 2.666666666666667, 0.72087386148474542, 5.640440812823317) >>> flownormalshock(gamma=1.4, Pitot=3.4) (1.4964833298836788, 0.70233741753226209, 1.3178766042516246, 2.4460394160563674, 1.8560458605647578, 0.93089743233402389, 3.3999999999999977) >>> flownormalshock(M2=[0.5, 0.6, 0.7]) (list, list, list, list, list, list, list) """ #parse the input gamma, flow, mtype, itype = _flowinput(flow) #calculate gamma-ratios for use in the equations a = (gamma+1) / 2 b = (gamma-1) / 2 c = gamma / (gamma-1) #preshape mach array M = sp.empty(flow.shape, sp.float64) #use the normal shock relations to solve for the mach number if mtype in ["mach", "m1", "m"]: if (flow < 1).any(): raise Exception("Mach number inputs must be real numbers" \ " greater than or equal to 1.") M = flow elif mtype in ["down", "mach2", "m2", "md"]: lowerbound = sp.sqrt((gamma - 1)/(2*gamma)) if (flow < lowerbound).any() or (flow > 1).any(): raise Exception("Mach number downstream inputs must be real" \ " numbers SQRT((GAMMA-1)/(2*GAMMA)) <= M <= 1.") M[flow <= lowerbound] = sp.inf M[flow > lowerbound] = sp.sqrt((1 + b*flow**2) / (gamma*flow**2 - b)) elif mtype in ["pres", "p"]: if (flow < 1).any() or not sp.isreal(flow).all(): raise Exception("Pressure ratio inputs must be real numbers" \ " greater than or equal to 1.") M = sp.sqrt(((flow-1)*(gamma+1)/(2*gamma)) + 1) elif mtype in ["dens", "d", "rho"]: upperbound = (gamma+1) / (gamma-1) if (flow < 1).any() or (flow > upperbound).any(): raise Exception("Density ratio inputs must be real numbers" \ " 1 <= rho <= (GAMMA+1)/(GAMMA-1).") M[flow >= upperbound] = sp.inf M[flow < upperbound] = sp.sqrt(2*flow / (1 + gamma + flow - flow*gamma)) elif mtype in ["temp", "t"]: if (flow < 1).any(): raise Exception("Temperature ratio inputs must be real numbers" \ " greater than or equal to 1.") B = b + gamma/a - gamma*b/a - flow*a M = sp.sqrt((-B + sp.sqrt(B**2 - \ 4*b*gamma*(1-gamma/a)/a)) / (2*gamma*b/a)) elif mtype in ["totalp", "p0"]: if (flow < 0).any() or (flow > 1).any(): raise Exception("Total pressure ratio inputs must be real" \ " numbers 0 <= P0 <= 1.") M[:] = 2.0 #initial guess for the solution for _ in xrange(_AETB_iternum): f = -flow + (1 + (gamma/a)*(M**2 - 1))**(1-c) \ * (a*M**2 / (1 + b*M**2))**c g = 2*M*(a*M**2 / (b*M**2 + 1))**(c-1)*((gamma* \ (M**2-1))/a + 1)**(-c)*(a*c + gamma*(-c*(b*M**4 + 1) \ + b*M**4 + M**2)) / (b*M**2 + 1)**2 M = M - (f / g) #Newton-Raphson M[flow == 0] = sp.inf elif mtype in ["pito", "pitot", "rp"]: lowerbound = a**c if (flow < lowerbound).any(): raise Exception("Rayleigh-Pitot ratio inputs must be real" \ " numbers greater than or equal to ((G+1)/2)**(-G/(G+1)).") M[:] = 5.0 #initial guess for the solution K = a**(2*c - 1) for _ in xrange(_AETB_iternum): f = -flow + K * M**(2*c) / (gamma*M**2 - b)**(c-1) #Rayleigh-Pitot g = 2*K*M**(2*c - 1) * (gamma*M**2 - b)**(-c) * (gamma*M**2 - b*c) M = M - (f / g) #Newton-Raphson else: raise Exception("Keyword input must be an acceptable string to" \ " select input parameter.") #normal shock relations M2 = sp.sqrt((1 + b*M**2) / (gamma*M**2 - b)) rho = ((gamma+1)*M**2) / (2 + (gamma-1)*M**2) P = 1 + (M**2 - 1)*gamma / a T = P / rho P0 = P**(1-c) * rho**(c) P1 = a**(2*c - 1) * M**(2*c) / (gamma*M**2 - b)**(c-1) #handle infinite mach M2[M == sp.inf] = sp.sqrt((gamma[M == sp.inf] - 1)/(2*gamma[M == sp.inf])) T[M == sp.inf] = sp.inf P[M == sp.inf] = sp.inf rho[M == sp.inf] = (gamma[M == sp.inf]+1) / (gamma[M == sp.inf]-1) P0[M == sp.inf] = 0 P1[M == sp.inf] = sp.inf return from_ndarray(itype, M, M2, T, P, rho, P0, P1)
def ldpred_gibbs(beta_hats, genotypes=None, start_betas=None, h2=None, n=1000, ld_radius=100, num_iter=60, burn_in=10, p=None, zero_jump_prob=0.05, tight_sampling=False, ld_dict=None, reference_ld_mats=None, ld_boundaries=None, verbose=False, print_progress=True): """ LDpred (Gibbs Sampler) """ t0 = time.time() m = len(beta_hats) n = float(n) # If no starting values for effects were given, then use the infinitesimal model starting values. if start_betas is None and verbose: print('Initializing LDpred effects with posterior mean LDpred-inf effects.') print('Calculating LDpred-inf effects.') start_betas = LDpred_inf.ldpred_inf(beta_hats, genotypes=genotypes, reference_ld_mats=reference_ld_mats, h2=h2, n=n, ld_window_size=2 * ld_radius, verbose=False) curr_betas = sp.copy(start_betas) assert len(curr_betas)==m,'Betas returned by LDpred_inf do not have the same length as expected.' curr_post_means = sp.zeros(m) avg_betas = sp.zeros(m) # Iterating over effect estimates in sequential order iter_order = sp.arange(m) # Setting up the marginal Bayes shrink Mp = m * p hdmp = (h2 / Mp) hdmpn = hdmp + 1.0 / n hdmp_hdmpn = (hdmp / hdmpn) c_const = (p / sp.sqrt(hdmpn)) d_const = (1.0 - p) / (sp.sqrt(1.0 / n)) for k in range(num_iter): # Big iteration # Force an alpha shrink if estimates are way off compared to heritability estimates. (Improves MCMC convergence.) h2_est = max(0.00001, sp.sum(curr_betas ** 2)) if tight_sampling: alpha = min(1.0 - zero_jump_prob, 1.0 / h2_est, (h2 + 1.0 / sp.sqrt(n)) / h2_est) else: alpha = 1.0 - zero_jump_prob rand_ps = sp.random.random(m) rand_norms = stats.norm.rvs(0.0, (hdmp_hdmpn) * (1.0 / n), size=m) if ld_boundaries is None: for i, snp_i in enumerate(iter_order): start_i = max(0, snp_i - ld_radius) focal_i = min(ld_radius, snp_i) stop_i = min(m, snp_i + ld_radius + 1) # Local LD matrix D_i = ld_dict[snp_i] # Local (most recently updated) effect estimates local_betas = curr_betas[start_i: stop_i] # Calculate the local posterior mean, used when sampling. local_betas[focal_i] = 0.0 res_beta_hat_i = beta_hats[snp_i] - sp.dot(D_i , local_betas) b2 = res_beta_hat_i ** 2 d_const_b2_exp = d_const * sp.exp(-b2 * n / 2.0) if sp.isreal(d_const_b2_exp): numerator = c_const * sp.exp(-b2 / (2.0 * hdmpn)) if sp.isreal(numerator): if numerator == 0.0: postp = 0.0 else: postp = numerator / (numerator + d_const_b2_exp) assert sp.isreal(postp), 'The posterior mean is not a real number? Possibly due to problems with summary stats, LD estimates, or parameter settings.' else: postp = 0.0 else: postp = 1.0 curr_post_means[snp_i] = hdmp_hdmpn * postp * res_beta_hat_i if rand_ps[i] < postp * alpha: # Sample from the posterior Gaussian dist. proposed_beta = rand_norms[i] + hdmp_hdmpn * res_beta_hat_i else: # Sample 0 proposed_beta = 0.0 curr_betas[snp_i] = proposed_beta # UPDATE BETA else: for i, snp_i in enumerate(iter_order): start_i = ld_boundaries[snp_i][0] stop_i = ld_boundaries[snp_i][1] focal_i = snp_i - start_i # Local LD matrix D_i = ld_dict[snp_i] # Local (most recently updated) effect imates local_betas = curr_betas[start_i: stop_i] # Calculate the local posterior mean, used when sampling. local_betas[focal_i] = 0.0 res_beta_hat_i = beta_hats[snp_i] - sp.dot(D_i , local_betas) b2 = res_beta_hat_i ** 2 d_const_b2_exp = d_const * sp.exp(-b2 * n / 2.0) if sp.isreal(d_const_b2_exp): numerator = c_const * sp.exp(-b2 / (2.0 * hdmpn)) if sp.isreal(numerator): if numerator == 0.0: postp = 0.0 else: postp = numerator / (numerator + d_const_b2_exp) assert sp.isreal(postp), 'Posterior mean is not a real number? Possibly due to problems with summary stats, LD estimates, or parameter settings.' else: postp = 0.0 else: postp = 1.0 curr_post_means[snp_i] = hdmp_hdmpn * postp * res_beta_hat_i if rand_ps[i] < postp * alpha: # Sample from the posterior Gaussian dist. proposed_beta = rand_norms[i] + hdmp_hdmpn * res_beta_hat_i else: # Sample 0 proposed_beta = 0.0 curr_betas[snp_i] = proposed_beta # UPDATE BETA if verbose and print_progress: sys.stdout.write('\b\b\b\b\b\b\b%0.2f%%' % (100.0 * (min(1, float(k + 1) / num_iter)))) sys.stdout.flush() if k >= burn_in: avg_betas += curr_post_means # Averaging over the posterior means instead of samples. if verbose and print_progress: sys.stdout.write('\b\b\b\b\b\b\b%0.2f%%\n' % (100.0)) sys.stdout.flush() avg_betas = avg_betas / float(num_iter - burn_in) t1 = time.time() t = (t1 - t0) if verbose: print('Took %d minutes and %0.2f seconds' % (t / 60, t % 60)) return {'betas':avg_betas, 'inf_betas':start_betas}
def qqplot(pvals, fileout = None, alphalevel = 0.05,legend=None,xlim=None,ylim=None,fixaxes=True,addlambda=True,minpval=1e-20,title=None,h1=None,figsize=[5,5],grid=True): ''' performs a P-value QQ-plot in -log10(P-value) space ----------------------------------------------------------------------- Args: pvals P-values, for multiple methods this should be a list (each element will be flattened) fileout if specified, the plot will be saved to the file (optional) alphalevel significance level for the error bars (default 0.05) if None: no error bars are plotted legend legend string. For multiple methods this should be a list xlim X-axis limits for the QQ-plot (unit: -log10) ylim Y-axis limits for the QQ-plot (unit: -log10) fixaxes Makes xlim=0, and ylim=max of the two ylimits, so that plot is square addlambda Compute and add genomic control to the plot, bool title plot title, string (default: empty) h1 figure handle (default None) figsize size of the figure. (default: [5,5]) grid boolean: use a grid? (default: True) Returns: fighandle, qnull, qemp ----------------------------------------------------------------------- ''' distr = 'log10' import pylab as pl if type(pvals)==list: pvallist=pvals else: pvallist = [pvals] if type(legend)==list: legendlist=legend else: legendlist = [legend] if h1 is None: h1=pl.figure(figsize=figsize) pl.grid(b=grid, alpha = 0.5) maxval = 0 for i in xrange(len(pvallist)): pval =pvallist[i].flatten() M = pval.shape[0] pnull = (0.5 + sp.arange(M))/M # pnull = np.sort(np.random.uniform(size = tests)) pval[pval<minpval]=minpval pval[pval>=1]=1 if distr == 'chi2': qnull = st.chi2.isf(pnull, 1) qemp = (st.chi2.isf(sp.sort(pval),1)) xl = 'LOD scores' yl = '$\chi^2$ quantiles' if distr == 'log10': qnull = -sp.log10(pnull) qemp = -sp.log10(sp.sort(pval)) #sorts the object, returns nothing xl = '-log10(P) observed' yl = '-log10(P) expected' if not (sp.isreal(qemp)).all(): raise Exception("imaginary qemp found") if qnull.max>maxval: maxval = qnull.max() pl.plot(qnull, qemp, '.', markersize=2) #pl.plot([0,qemp.max()], [0,qemp.max()],'r') if addlambda: lambda_gc = estimate_lambda(pval) print "lambda=%1.4f" % lambda_gc #pl.legend(["gc="+ '%1.3f' % lambda_gc],loc=2) # if there's only one method, just print the lambda if len(pvallist) == 1: legendlist=["$\lambda_{GC}=$%1.4f" % lambda_gc] # otherwise add it at the end of the name else: legendlist[i] = legendlist[i] + " ($\lambda_{GC}=$%1.4f)" % lambda_gc addqqplotinfo(qnull,M,xl,yl,xlim,ylim,alphalevel,legendlist,fixaxes) if title is not None: pl.title(title) if fileout is not None: pl.savefig(fileout) return h1,qnull, qemp,
def ldpred_gibbs(beta_hats, genotypes=None, start_betas=None, h2=None, n=1000, ld_radius=100, num_iter=60, burn_in=10, p=None, zero_jump_prob=0.05, tight_sampling=False, ld_dict=None, reference_ld_mats=None, ld_boundaries=None, verbose=False): """ LDpred (Gibbs Sampler) """ t0 = time.time() m = len(beta_hats) n = float(n) # If no starting values for effects were given, then use the infinitesimal model starting values. if start_betas is None and verbose: print( 'Initializing LDpred effects with posterior mean LDpred-inf effects.' ) print('Calculating LDpred-inf effects.') start_betas = LDpred_inf.ldpred_inf( beta_hats, genotypes=genotypes, reference_ld_mats=reference_ld_mats, h2=h2, n=n, ld_window_size=2 * ld_radius, verbose=False) curr_betas = sp.copy(start_betas) assert len( curr_betas ) == m, 'Betas returned by LDpred_inf do not have the same length as expected.' curr_post_means = sp.zeros(m) avg_betas = sp.zeros(m) # Iterating over effect estimates in sequential order iter_order = sp.arange(m) # Setting up the marginal Bayes shrink Mp = m * p hdmp = (h2 / Mp) hdmpn = hdmp + 1.0 / n hdmp_hdmpn = (hdmp / hdmpn) c_const = (p / sp.sqrt(hdmpn)) d_const = (1.0 - p) / (sp.sqrt(1.0 / n)) for k in range(num_iter): # Big iteration # Force an alpha shrink if estimates are way off compared to heritability estimates. (Improves MCMC convergence.) h2_est = max(0.00001, sp.sum(curr_betas**2)) if tight_sampling: alpha = min(1.0 - zero_jump_prob, 1.0 / h2_est, (h2 + 1.0 / sp.sqrt(n)) / h2_est) else: alpha = 1.0 - zero_jump_prob rand_ps = sp.random.random(m) rand_norms = stats.norm.rvs(0.0, (hdmp_hdmpn) * (1.0 / n), size=m) if ld_boundaries is None: for i, snp_i in enumerate(iter_order): start_i = max(0, snp_i - ld_radius) focal_i = min(ld_radius, snp_i) stop_i = min(m, snp_i + ld_radius + 1) # Local LD matrix D_i = ld_dict[snp_i] # Local (most recently updated) effect estimates local_betas = curr_betas[start_i:stop_i] # Calculate the local posterior mean, used when sampling. local_betas[focal_i] = 0.0 res_beta_hat_i = beta_hats[snp_i] - sp.dot(D_i, local_betas) b2 = res_beta_hat_i**2 d_const_b2_exp = d_const * sp.exp(-b2 * n / 2.0) if sp.isreal(d_const_b2_exp): numerator = c_const * sp.exp(-b2 / (2.0 * hdmpn)) if sp.isreal(numerator): if numerator == 0.0: postp = 0.0 else: postp = numerator / (numerator + d_const_b2_exp) assert sp.isreal( postp ), 'The posterior mean is not a real number? Possibly due to problems with summary stats, LD estimates, or parameter settings.' else: postp = 0.0 else: postp = 1.0 curr_post_means[snp_i] = hdmp_hdmpn * postp * res_beta_hat_i if rand_ps[i] < postp * alpha: # Sample from the posterior Gaussian dist. proposed_beta = rand_norms[i] + hdmp_hdmpn * res_beta_hat_i else: # Sample 0 proposed_beta = 0.0 curr_betas[snp_i] = proposed_beta # UPDATE BETA else: for i, snp_i in enumerate(iter_order): start_i = ld_boundaries[snp_i][0] stop_i = ld_boundaries[snp_i][1] focal_i = snp_i - start_i # Local LD matrix D_i = ld_dict[snp_i] # Local (most recently updated) effect imates local_betas = curr_betas[start_i:stop_i] # Calculate the local posterior mean, used when sampling. local_betas[focal_i] = 0.0 res_beta_hat_i = beta_hats[snp_i] - sp.dot(D_i, local_betas) b2 = res_beta_hat_i**2 d_const_b2_exp = d_const * sp.exp(-b2 * n / 2.0) if sp.isreal(d_const_b2_exp): numerator = c_const * sp.exp(-b2 / (2.0 * hdmpn)) if sp.isreal(numerator): if numerator == 0.0: postp = 0.0 else: postp = numerator / (numerator + d_const_b2_exp) assert sp.isreal( postp ), 'Posterior mean is not a real number? Possibly due to problems with summary stats, LD estimates, or parameter settings.' else: postp = 0.0 else: postp = 1.0 curr_post_means[snp_i] = hdmp_hdmpn * postp * res_beta_hat_i if rand_ps[i] < postp * alpha: # Sample from the posterior Gaussian dist. proposed_beta = rand_norms[i] + hdmp_hdmpn * res_beta_hat_i else: # Sample 0 proposed_beta = 0.0 curr_betas[snp_i] = proposed_beta # UPDATE BETA if verbose: sys.stdout.write('\b\b\b\b\b\b\b%0.2f%%' % (100.0 * (min(1, float(k + 1) / num_iter)))) sys.stdout.flush() if k >= burn_in: avg_betas += curr_post_means # Averaging over the posterior means instead of samples. avg_betas = avg_betas / float(num_iter - burn_in) t1 = time.time() t = (t1 - t0) if verbose: print('\nTook %d minutes and %0.2f seconds' % (t / 60, t % 60)) return {'betas': avg_betas, 'inf_betas': start_betas}
def ldpred_gibbs(beta_hats, genotypes=None, start_betas=None, h2=None, n=None, ns=None, ld_radius=100, num_iter=60, burn_in=10, p=None, zero_jump_prob=0.01, sampl_var_shrink_factor=0.9, tight_sampling=False, ld_dict=None, reference_ld_mats=None, ld_boundaries=None, verbose=False, print_progress=True): """ LDpred (Gibbs Sampler) """ # Set random seed to stabilize results sp.random.seed(42) t0 = time.time() m = len(beta_hats) ldpred_n, ldpred_inf_n = get_LDpred_sample_size(n, ns, verbose) # If no starting values for effects were given, then use the infinitesimal model starting values. if start_betas is None and verbose: print( 'Initializing LDpred effects with posterior mean LDpred-inf effects.' ) print('Calculating LDpred-inf effects.') start_betas = LDpred_inf.ldpred_inf( beta_hats, genotypes=genotypes, reference_ld_mats=reference_ld_mats, h2=h2, n=ldpred_inf_n, ld_window_size=2 * ld_radius, verbose=False) curr_betas = sp.copy(start_betas) assert len( curr_betas ) == m, 'Betas returned by LDpred_inf do not have the same length as expected.' curr_post_means = sp.zeros(m) avg_betas = sp.zeros(m) # Iterating over effect estimates in sequential order iter_order = sp.arange(m) # Setting up the marginal Bayes shrink const_dict = prepare_constants(ldpred_n, ns, m, p, h2, sampl_var_shrink_factor) for k in range(num_iter): # Big iteration h2_est = max(0.00001, sp.sum(curr_betas**2)) if tight_sampling: # Force an alpha shrink if estimates are way off compared to heritability estimates. #(May improve MCMC convergence.) alpha = min(1.0 - zero_jump_prob, 1.0 / h2_est, (h2 + 1.0 / sp.sqrt(ldpred_n)) / h2_est) else: alpha = 1.0 - zero_jump_prob rand_ps = sp.random.random(m) rand_norms = stats.norm.rvs(0.0, 1, size=m) * const_dict['rv_scalars'] for i, snp_i in enumerate(iter_order): if ld_boundaries is None: start_i = max(0, snp_i - ld_radius) focal_i = min(ld_radius, snp_i) stop_i = min(m, snp_i + ld_radius + 1) else: start_i = ld_boundaries[snp_i][0] stop_i = ld_boundaries[snp_i][1] focal_i = snp_i - start_i #Figure out what sample size and constants to use cd = get_constants(snp_i, const_dict) # Local LD matrix D_i = ld_dict[snp_i] # Local (most recently updated) effect estimates local_betas = curr_betas[start_i:stop_i] # Calculate the local posterior mean, used when sampling. local_betas[focal_i] = 0.0 res_beta_hat_i = beta_hats[snp_i] - sp.dot(D_i, local_betas) b2 = res_beta_hat_i**2 d_const_b2_exp = cd['d_const'] * sp.exp(-b2 * cd['n'] / 2.0) if sp.isreal(d_const_b2_exp): numerator = cd['c_const'] * sp.exp(-b2 / (2.0 * cd['hdmpn'])) if sp.isreal(numerator): if numerator == 0.0: postp = 0.0 else: postp = numerator / (numerator + d_const_b2_exp) assert sp.isreal( postp ), 'The posterior mean is not a real number? Possibly due to problems with summary stats, LD estimates, or parameter settings.' else: postp = 0.0 else: postp = 1.0 curr_post_means[snp_i] = cd['hdmp_hdmpn'] * postp * res_beta_hat_i if rand_ps[i] < postp * alpha: # Sample from the posterior Gaussian dist. proposed_beta = rand_norms[ snp_i] + cd['hdmp_hdmpn'] * res_beta_hat_i else: # Sample 0 proposed_beta = 0.0 curr_betas[snp_i] = proposed_beta # UPDATE BETA if verbose and print_progress: sys.stdout.write('\r%0.2f%%' % (100.0 * (min(1, float(k + 1) / num_iter)))) sys.stdout.flush() if k >= burn_in: avg_betas += curr_post_means # Averaging over the posterior means instead of samples. if verbose and print_progress: sys.stdout.write('\r%0.2f%%\n' % (100.0)) sys.stdout.flush() avg_betas = avg_betas / float(num_iter - burn_in) t1 = time.time() t = (t1 - t0) if verbose: print('Took %d minutes and %0.2f seconds' % (t / 60, t % 60)) return {'betas': avg_betas, 'inf_betas': start_betas}