def test_frozen(self): # Test that the frozen and non-frozen inverse Wishart gives the same # answers # Construct an arbitrary positive definite scale matrix dim = 4 scale = np.diag(np.arange(dim)+1) scale[np.tril_indices(dim, k=-1)] = np.arange(dim*(dim-1)/2) scale = np.dot(scale.T, scale) # Construct a collection of positive definite matrices to test the PDF X = [] for i in range(5): x = np.diag(np.arange(dim)+(i+1)**2) x[np.tril_indices(dim, k=-1)] = np.arange(dim*(dim-1)/2) x = np.dot(x.T, x) X.append(x) X = np.array(X).T # Construct a 1D and 2D set of parameters parameters = [ (10, 1, np.linspace(0.1, 10, 5)), # 1D case (10, scale, X) ] for (df, scale, x) in parameters: iw = invwishart(df, scale) assert_equal(iw.var(), invwishart.var(df, scale)) assert_equal(iw.mean(), invwishart.mean(df, scale)) assert_equal(iw.mode(), invwishart.mode(df, scale)) assert_allclose(iw.pdf(x), invwishart.pdf(x, df, scale))
def test_1D_is_invgamma(self): # The 1-dimensional inverse Wishart with an identity scale matrix is # just an inverse gamma distribution. # Test variance, mean, pdf # Kolgomorov-Smirnov test for rvs np.random.seed(482974) sn = 500 dim = 1 scale = np.eye(dim) df_range = np.arange(5, 20, 2, dtype=float) X = np.linspace(0.1,10,num=10) for df in df_range: iw = invwishart(df, scale) ig = invgamma(df/2, scale=1./2) # Statistics assert_allclose(iw.var(), ig.var()) assert_allclose(iw.mean(), ig.mean()) # PDF assert_allclose(iw.pdf(X), ig.pdf(X)) # rvs rvs = iw.rvs(size=sn) args = (df/2, 0, 1./2) alpha = 0.01 check_distribution_rvs('invgamma', args, alpha, rvs)
def test_wishart_invwishart_2D_rvs(self): dim = 3 df = 10 # Construct a simple non-diagonal positive definite matrix scale = np.eye(dim) scale[0,1] = 0.5 scale[1,0] = 0.5 # Construct frozen Wishart and inverse Wishart random variables w = wishart(df, scale) iw = invwishart(df, scale) # Get the generated random variables from a known seed np.random.seed(248042) w_rvs = wishart.rvs(df, scale) np.random.seed(248042) frozen_w_rvs = w.rvs() np.random.seed(248042) iw_rvs = invwishart.rvs(df, scale) np.random.seed(248042) frozen_iw_rvs = iw.rvs() # Manually calculate what it should be, based on the Bartlett (1933) # decomposition of a Wishart into D A A' D', where D is the Cholesky # factorization of the scale matrix and A is the lower triangular matrix # with the square root of chi^2 variates on the diagonal and N(0,1) # variates in the lower triangle. np.random.seed(248042) covariances = np.random.normal(size=3) variances = np.r_[ np.random.chisquare(df), np.random.chisquare(df-1), np.random.chisquare(df-2), ]**0.5 # Construct the lower-triangular A matrix A = np.diag(variances) A[np.tril_indices(dim, k=-1)] = covariances # Wishart random variate D = np.linalg.cholesky(scale) DA = D.dot(A) manual_w_rvs = np.dot(DA, DA.T) # inverse Wishart random variate # Supposing that the inverse wishart has scale matrix `scale`, then the # random variate is the inverse of a random variate drawn from a Wishart # distribution with scale matrix `inv_scale = np.linalg.inv(scale)` iD = np.linalg.cholesky(np.linalg.inv(scale)) iDA = iD.dot(A) manual_iw_rvs = np.linalg.inv(np.dot(iDA, iDA.T)) # Test for equality assert_allclose(w_rvs, manual_w_rvs) assert_allclose(frozen_w_rvs, manual_w_rvs) assert_allclose(iw_rvs, manual_iw_rvs) assert_allclose(frozen_iw_rvs, manual_iw_rvs)
def __init__(self, df, scale, size=1, preload=1, *args, **kwargs): # Initialize the Wishart super(InverseWishart, self).__init__(df, scale, size, preload, *args, **kwargs) # Replace the wishart _rvs with an invwishart self._frozen = invwishart(self.df, self.scale) self._rvs = self._frozen._invwishart # df, scale are the same # Helpers for the triangular matrix inversion self._trtri = lapack.get_lapack_funcs(('trtri'), (self.scale,))
def bayes_estim(Y, v_0, delta_0, n): s = np.zeros([2, 2]) for i in range(n): s = s + np.outer(Y[i], Y[i]) v_n = v_0 + n delta_n = delta_0 + s generator = stats.invwishart(df=v_n, scale=delta_n) mmse = generator.mean() mAP = generator.mode() print("\nBayes MMSE: " + str(mmse)) print("\nBayes mAP: " + str(mAP))
def bayes_monte_carlo(Y, v_0, delta_0, n, m): s = np.zeros([2, 2]) for i in range(n): s = s + np.outer(Y[i], Y[i]) v_n = v_0 + n delta_n = delta_0 + s generator = stats.invwishart(df=v_n, scale=delta_n) numer = np.zeros([2, 2]) denom = 0 for i in range(m): sigma = generator.rvs(size=1) numer = numer + (1 / (i + 1)) * (sigma - numer) denom = denom + (1 / (i + 1)) * (1 - denom) print("\nMC integ: " + str(numer / denom))
def draw_sigma_k(sk_dict, nk_dict, k, N): return {i: sts.invwishart(nk_dict[i]+N-1, scale=sk_dict[i]).rvs() for i in xrange(k)}
def draw_covm(param_dict): covm = sts.invwishart(df=param_dict['up_n0'], scale=param_dict['up_covm_0']).rvs() return covm #invwishart takes as input a covariance matrix and returns a covariance matrix