def rvs(n, tau=None, cov=None): """ rvs(n, tau=None, cov=None) Return a Wishart random matrix. :Parameters: - `n` : Degrees of freedom. - `tau` : (k,k) Positive definite precision matrix. - `cov` : (k,k) Positive definite covariance matrix. """ if (tau is None and cov is None): raise ValueError('Must specify either tau or cov.') if tau is not None: p = np.shape(tau)[0] sig = np.linalg.cholesky(tau) if n<p: raise ValueError('Wishart parameter n must be greater ' 'than size of matrix.') norms = np.random.normal(size=p*(p-1)/2) chi_sqs = np.sqrt(np.random.chisquare(df=np.arange(n,n-p,-1))) A = flib.expand_triangular(chi_sqs, norms) flib.dtrsm_wrap(sig, A, side='L', uplo='L', transa='T', alpha=1.) # w = np.asmatrix(np.dot(A,A.T)) w = np.dot(A,A.T) flib.symmetrize(w) return w elif cov is not None: p = np.shape(cov)[0] # Need cholesky decomposition of precision matrix C^-1? sig = np.linalg.cholesky(cov) if n<p: raise ValueError('Wishart parameter n must be greater ' 'than size of matrix.') norms = np.random.normal(size=p*(p-1)/2) chi_sqs = np.sqrt(np.random.chisquare(df=np.arange(n,n-p,-1))) A = flib.expand_triangular(chi_sqs, norms) flib.dtrmm_wrap(sig, A, side='L', uplo='L', transa='N', alpha=1.) # w = np.asmatrix(np.dot(A,A.T)) w = np.dot(A,A.T) flib.symmetrize(w) return w
def rvs(mu, tau=None, cov=None, sig=None, size=1): """ rvs(mu, tau=None, cov=None, sig=None, size=1) Random multivariate normal variates. :Parameters: - `mu` : Mean vector. - `tau` : Precision matrix. - `cov` : Covariance matrix. - `sig` : Lower-triangular matrix resulting from the Cholesky decomposition of the covariance matrix. - `size` : Number of random samples to generate. """ if (tau is not None and cov is not None) or (tau is not None and sig is not None) or (cov is not None and sig is not None): raise ValueError('Only specify one of {tau, cov, sig}.') if tau is None and cov is None and sig is None: # Default the precision to identity matrix. tau = np.eye(mu.size) if tau is not None: sig = np.linalg.cholesky(tau) mu_size = np.shape(mu) if size==1: out = np.random.normal(size=mu_size) try: flib.dtrsm_wrap(sig , out, 'L', 'T', 'L', 1.) except: out = np.linalg.solve(sig, out) out+=mu return out else: if not hasattr(size,'__iter__'): size = (size,) tot_size = np.prod(size) out = np.random.normal(size = (tot_size,) + mu_size) for i in xrange(tot_size): try: flib.dtrsm_wrap(sig , out[i,:], 'L', 'T', 'L', 1.) except: out[i,:] = np.linalg.solve(sig, out[i,:]) out[i,:] += mu return out.reshape(size+mu_size) elif cov is not None: mu_size = np.shape(mu) if size==1: return np.random.multivariate_normal(mu, cov, size).reshape(mu_size) else: return np.random.multivariate_normal(mu, cov, size).reshape((size,)+mu_size) elif sig is not None: mu_size = np.shape(mu) if size==1: out = np.random.normal(size=mu_size) try: flib.dtrmm_wrap(sig , out, 'L', 'N', 'L', 1.) except: out = np.dot(sig, out) out+=mu return out else: if not hasattr(size,'__iter__'): size = (size,) tot_size = np.prod(size) out = np.random.normal(size = (tot_size,) + mu_size) for i in xrange(tot_size): try: flib.dtrmm_wrap(sig , out[i,:], 'L', 'N', 'L', 1.) except: out[i,:] = np.dot(sig, out[i,:]) out[i,:] += mu return out.reshape(size+mu_size)