def logp(self): '''Gaussian probability function. The equation is (Wikipedia or Kevin P. Murphy, 2007): -------- logpdf estimate of Xi''' if self.d==1: #parametrized by the mean and prec. pr = self.__prec() self.logp_ =-0.5*math.log(2*math.pi) +0.5*math.log(pr)-0.5*(((self.__delta())**2)*(pr)) return self.logp_ else: cpm = self.__chol_prec() det = Cholesky(cpm, method='lower').log_determinant() delta = self.__delta() in_exp = delta.T.dot(Cholesky(cpm, method='lower').matrix).dot(delta) self.logp_ = (-0.5*self.d)*math.log(2*math.pi) + 0.5*det -0.5*in_exp return self.logp_
def prior_lp_mu_(self, prec=None, mu=None, mu_0=None, kappa=None, d=None): '''Computes the log prior probability of the mean. Eqs (13), (14),(15), (16).''' if prec is None: prec = self.GaussComp.prec if kappa is None: kappa = self.GaussComp.kappa_0 if mu is None: mu = self.GaussComp.emp_mu if mu_0 is None: mu_0 = self.GaussComp.mu_0 if d is None: d = self.d if d == 1: prec = abs(prec) self.prior_lp_mu = self.__mu_norm_Z( kappa, 1) + (0.5 * math.log(prec)) - (0.5 * (kappa * prec) * ((mu - mu_0)**2)) else: self.prior_lp_mu = self.__mu_norm_Z(kappa, d) + ( 0.5 * Cholesky(prec).log_determinant()) - (0.5 * np.einsum( 'ij, ij', kappa * prec, np.einsum('i,j->ij', (mu) - mu_0, (mu) - mu_0))) return self.prior_lp_mu
def main(argv): mp.dps = 1000 mp.prec = 1000 if (len(argv) == 3): n = int(argv[1]) p = int(argv[2]) else: n = 5 p = 10 A = np.zeros((n, n), dtype=object) b = np.ones((n, ), dtype=object) # A = [[0, 4, 5], [-1, -2, -3], [0, 0, 1]] # A = np.array(A) # b = [23, -14, 3] # b = np.array(b) for i in range(n): for j in range(n): A[i, j] = mp.mpf(combination(p + j, i)) # print (A) # print (A.T.dot(b)) x = Cholesky(A.T.dot(A), A.T.dot(b)) y = np.dot(A.T.dot(A), x) print(x)
def chol_cov_rvs(self): if self.d == 1: return 1. / self.chol_prec_rvs() else: return Cholesky(self.chol_prec_rvs(), method='lower')._Cholesky__chol_of_the_inv()
def __prec_mu_norm_Z(self, S=None, kappa=None, v=None, d=None): '''Log of the normalizing constant of the precision and mean. This normalizing function is used throughout different equations.eq(1), (2), (3)''' if S is None: S = self.GaussComp.S_0 if kappa is None: kappa = self.GaussComp.kappa_0 if v is None: v = self.GaussComp.v_0 if d is None: d = self.d df = self.__df(v, d) if kappa == 0: kt = 0 else: kt = 0.5 * d * math.log(kappa) if d == 1: self.prec_mu_norm_Z = -kt + 0.5 * math.log(math.pi) - 0.5 * ( df - 1) * math.log(S) + 0.5 * df * math.log(2) + gamlog( 0.5 * (df - 1)) else: self.prec_mu_norm_Z = (0.5*df*d*math.log(2))+ (0.25*(d*(d+1))*math.log(math.pi)) - kt \ -((0.5*(df-1))*Cholesky(S).log_determinant())+sum(gamlog(0.5*(df-np.arange(1,d+1)))) return self.prec_mu_norm_Z
def data_lp_(self, prec=None, XX_T=None, sX=None, mu=None, n=None, d=None): if prec is None: prec = self.GaussComp.prec if XX_T is None: XX_T = self.GaussComp.XX_T if sX is None: sX = self.GaussComp.sX if mu is None: mu = self.GaussComp.emp_mu if n is None: n = self.n if d is None: d = self.d if n == 0: n = 1 if d == 1: prec = abs(prec) self.data_lp = (-0.5 * (n * d) * math.log(2 * math.pi)) + ( (0.5 * n) * math.log(prec)) - (0.5 * prec * ((XX_T) - (2 * mu * sX) + (n * mu * mu))) else: self.data_lp = (-0.5 * (n * d) * math.log(2 * math.pi)) + ( (0.5 * n) * Cholesky(prec).log_determinant()) - ( 0.5 * np.einsum('ij, ij', prec, (n * np.einsum('i,j->ij', mu, mu) - 2 * np.einsum('i,j->ij', sX, mu) + XX_T))) return self.data_lp
def prior_lp_prec_(self, prec=None, S=None, v=None, d=None): '''Computes the log prior probability of the precision matrix.eq (9), (10), (11), (12)''' if prec is None: prec = self.GaussComp.prec if S is None: S = self.GaussComp.S_0 if v is None: v = self.GaussComp.v_0 if d is None: d = self.d df = self.__df(v, d) if d == 1: prec = abs(prec) self.prior_lp_prec = (-self.__prec_norm_Z(S, df - 1, d) + (0.5 * (df - 3) * math.log(prec)) - (0.5 * prec * S)) else: self.prior_lp_prec = -self.__prec_norm_Z(S, df - 1, d) + ( 0.5 * (df - 2 - d) * Cholesky(prec).log_determinant()) - ( 0.5 * np.einsum('ij, ij', prec, S)) return self.prior_lp_prec
def __chol_prec(self): '''returns the Cholesky dec. of the precision matrix''' if self.d==1: if self.method=='cov' or self.method=='chol_cov': self.chol_prec=1./self.S elif self.method=='prec' or self.method=='chol_prec': self.chol_prec = self.S else: if self.method=='cov': self.chol_prec = Cholesky(self.S)._Cholesky__chol_of_the_inv() elif self.method=='chol_cov': self.chol_prec = Cholesky(self.S, method='lower')._Cholesky__chol_of_the_inv() elif self.method=='prec': self.chol_prec = Cholesky(self.S).lower elif self.method=='chol_prec': self.chol_prec= self.S return self.chol_prec
def __prec(self): '''returns the precision matrix''' if self.d==1: if self.method=='cov' or self.method=='chol_cov': self.prec=1./self.S elif self.method=='prec' or self.method=='chol_prec': self.prec = self.S else: if self.method=='cov': self.prec = Cholesky(self.S)._Cholesky__inv() elif self.method=='chol_cov': self.prec = Cholesky(self.S, method='lower')._Cholesky__inv() elif self.method=='prec': self.prec = self.S elif self.method=='chol_prec': self.prec= Cholesky(self.S, method='lower').matrix return self.prec
def __cov(self): '''returns the covariance matrix''' if self.d==1: if self.method=='cov' or self.method=='chol_cov': self.cov=self.S elif self.method=='prec' or self.method=='chol_prec': self.cov = 1./self.S else: if self.method=='cov': self.cov = self.S elif self.method=='chol_cov': self.cov = Cholesky(self.S, method = 'lower').matrix elif self.method=='prec': self.cov = Cholesky(self.S)._Cholesky__inv() elif self.method=='chol_prec': self.cov= Cholesky(self.S, method='lower')._Cholesky__inv() return self.cov
def __chol_inv_scale(self): if self.inv_scale is None: self.inv_scale = self.__inv_scale() if self.d == 1: self.chol_inv_scale = self.inv_scale else: self.chol_inv_scale = Cholesky(self.inv_scale).lower return self.chol_inv_scale
def __inv_scale(self): if self.scale is None: self.scale = self.__scale() if self.d == 1: self.inv_scale = 1. / self.scale else: self.inv_scale = Cholesky(self.scale)._Cholesky__inv() return self.inv_scale
def marginal_mu_lp_(self, mu_i, prec, mu, kappa, v, n, d): df = v + n + 1 - d if n == 0: n = 1 M = (df * (kappa + n)) * prec self.marginal_mu_lp = gamlog(0.5*(df+d)) - gamlog(0.5*df) + 0.5*Cholesky(M).log_determinant()-0.5*d*math.log(df*math.pi)\ - 0.5*(df+d)*(math.log(1+(1/df)*np.einsum('i,ij,j->', mu_i-mu, M, mu_i-mu))) return self.marginal_mu_lp
def __prec_norm_Z(self, S=None, v=None, d=None): '''normalizing constant for the probability that the precision matrix is Lamda, given the prior. This is modelled as Wi(v, S). The normalizing constant is 1/Z and Z = [2**(0.5*v*d)][det(S)**(-0.5*v)][prod(gamma_func(v+1-i)) for i in xrange(d)].''' if S is None: S = self.GaussComp.S_0 if v is None: v = self.GaussComp.v_0 if d is None: d = self.d df = self.__df(v, d) if d == 1: self.prec_norm_Z = (-0.5 * (df - 1) * (math.log(S) - math.log(2))) + gamlog(0.5 * (df - 1)) else: self.prec_norm_Z = (0.5*d*(df-1)*math.log(2))-((0.5*(df-1))*Cholesky(S).log_determinant()) + ((0.25*d*(d-1))*math.log(math.pi))\ +sum(gamlog(0.5*(df-np.arange(1, d+1)))) return self.prec_norm_Z
def prior_lp_(self, prec=None, mu=None, mu_0=None, S=None, kappa=None, v=None, d=None): if prec is None: prec = self.GaussComp.prec if kappa is None: kappa = self.GaussComp.kappa_0 if mu is None: mu = self.GaussComp.emp_mu if mu_0 is None: mu_0 = self.GaussComp.mu_0 if v is None: v = self.GaussComp.v_0 if S is None: S = self.GaussComp.S_0 if d is None: d = self.d df = self.__df(v, d) if d == 1: prec = abs(prec) self.prior_lp = -self.__prec_mu_norm_Z( S, kappa, df - 1, d) + 0.5 * ( df - 2) * math.log(prec) - 0.5 * prec * (S + kappa * (mu - mu_0)**2) else: self.prior_lp = -self.__prec_mu_norm_Z(S, kappa, df-1,d)+((0.5*(df-1-d))*Cholesky(prec).log_determinant())\ -(0.5*np.einsum('ij, ij', prec, (kappa*np.einsum('i,j->ij', mu-mu_0, mu-mu_0))+S)) return self.prior_lp
def prec_rvs(self): if self.d == 1: return self.chol_prec_rvs() else: return Cholesky(self.chol_prec_rvs(), method='lower').matrix
def post_lp_(self, prec=None, scale=None, mu=None, post_mu=None, sX=None, kappa=None, v=None, n=None, d=None): if prec is None: prec = self.GaussComp.prec if scale is None: scale = self.GaussComp.scale if post_mu is None: post_mu = self.GaussComp.mu if mu is None: mu = self.GaussComp.emp_mu if sX is None: sX = self.GaussComp.sX if kappa is None: kappa = self.GaussComp.kappa_0 if v is None: v = self.GaussComp.v_0 if n is None: n = self.n if d is None: d = self.GaussComp.d df = self.__df(v, d) if n == 0: n = 1 if d == 1: self.post_lp = -self.__prec_mu_norm_Z( scale, kappa + n, df - 1 + n, d) + ( 0.5 * (df - 2 + n) * math.log(prec)) - (0.5 * prec * ( (kappa + n) * ((mu - post_mu)**2) + scale)) else: self.post_lp = -self.__prec_mu_norm_Z(scale, kappa+n, df-1+n,d) + (0.5*(df-1+n-d))*Cholesky(prec).log_determinant()\ -(0.5*np.einsum('ij, ij', prec, ((kappa+n)*np.einsum('i,j->ij', mu-post_mu, mu-post_mu) + scale))) return self.post_lp
def marginal_prec_lp_(self, prec_i, prec, v, n, d): df = self.__df(v, d) if n == 0: n = 1 self.marginal_prec_lp = -self.__prec_norm_Z(prec,df-1+n,d)+(0.5*(df-1+n-d-1))*Cholesky(prec_i).log_determinant()\ -0.5*np.einsum('ij,ij', prec, prec_i) return self.marginal_prec_lp
def joint_lp_(self, prec=None, XX_T=None, S=None, mu_0=None, sX=None, mu=None, kappa=None, v=None, n=None, d=None): if prec is None: prec = self.GaussComp.prec if XX_T is None: XX_T = self.GaussComp.XX_T if S is None: S = self.GaussComp.S_0 if mu_0 is None: mu_0 = self.GaussComp.mu_0 if sX is None: sX = self.GaussComp.sX if mu is None: mu = self.GaussComp.emp_mu if kappa is None: kappa = self.GaussComp.kappa_0 if v is None: v = self.GaussComp.v_0 if n is None: n = self.n if d is None: d = self.d df = self.__df(v, d) if n == 0: n = 1 if d == 1: prec = abs(prec) self.joint_lp = (-0.5*n*math.log(2*math.pi)) - self.__prec_mu_norm_Z(S, kappa, df-1, d) + (0.5*(df-2+n)*math.log(prec))- \ (0.5*prec*((kappa*(mu-mu_0)**2)+S+XX_T-(2*mu*sX)+(n*mu*mu))) else: self.joint_lp = (-0.5*(n*d)*math.log(2*math.pi)) -self.__prec_mu_norm_Z(S, kappa, df-1,d) + ((0.5*(df-1+n-d))*Cholesky(prec).log_determinant())\ -(0.5*np.einsum('ij, ij', prec, ((kappa+n)*np.einsum('i,j->ij', mu, mu) - 2*np.einsum('i,j->ij', mu, ((kappa*mu_0)+sX)) + kappa*np.einsum('i,j->ij', mu_0, mu_0)+XX_T+S))) return self.joint_lp