def sample_at_prob(self, prob, mean, var, rstate=None):
"""
"""
shape = mean.shape[0]
# Get a sample from a distribution N(0,I)
scale = spstat.norm.ppf(prob, loc=0, scale=1)
v = spstat.multivariate_normal.rvs(
mean=None,
cov=1,
size=shape,
random_state=rstate)
v *= np.fabs(scale) / np.sqrt((v**2).sum())
# Spectral decomposition of target dist covariance
eigs, vects = np.linalg.eigh(var)
assert eigs.shape[0] == shape, 'Too few eigenvalues'
assert np.all(eigs >= 0.0), 'Negative eigenvalues'
assert np.all(np.isreal(eigs)), 'Imaginary eigenvalues'
assert np.all(np.fabs(
np.dot(vects.T, vects) - np.eye(shape)) < 1E-14),\
'Eigenvectors are not orthogonal'
# Calculate map from N(0,I) to N(0,E)
a_mat = np.dot(vects.T, np.dot(np.diag(np.sqrt(eigs)), vects))
# Add the mean to get N(u,E)
#return mean + np.copysign(np.dot(a_mat, v), scale)
return mean + scale * np.diag(np.sqrt(var))
评论列表
文章目录