def estimate_nll(X, f_nll_z, f_nll_x_given_z, f_nll_z_given_x, f_sample_z_given_x, n_samples): if X.ndim == 2: log_prior = np.empty((n_samples, X.shape[0])) log_posterior = np.empty((n_samples, X.shape[0])) log_recog = np.empty((n_samples, X.shape[0])) elif X.ndim == 3: log_prior = np.empty((n_samples, X.shape[0], X.shape[1])) log_posterior = np.empty((n_samples, X.shape[0], X.shape[1])) log_recog = np.empty((n_samples, X.shape[0], X.shape[1])) else: raise ValueError('unexpected ndim for X, can be 2 or 3') for i in range(n_samples): Z = f_sample_z_given_x(X) log_prior[i] = ma.assert_numpy(-f_nll_z(Z)) log_posterior[i] = ma.assert_numpy(-f_nll_x_given_z(X, Z)) log_recog[i] = ma.assert_numpy(-f_nll_z_given_x(Z, X)) d = log_prior + log_posterior - log_recog while d.ndim > 1: d = d.sum(-1) ll = logsumexp(d, 0) - np.log(n_samples) # Normalize to average. ll /= X.shape[0] if X.ndim == 3: ll /= X.shape[1] return -ll
def bound_spectral_radius(arr, bound=1.2): """Set the spectral radius of the square matrix ``arr`` to ``bound``. This is performed by making an Eigendecomposition of ``arr``, rescale all Eigenvalues such that the absolute value of the greatest matches ``bound`` and recompose it again. Parameters ---------- arr : array_like, two dimensional Array to work upon in place. bound : float, optional, default: 1.2 Examples -------- >>> import numpy as np >>> from climin.initialize import bound_spectral_radius >>> arr = np.arange(9).reshape((3, 3)).astype('float64') >>> bound_spectral_radius(arr, 1.1) >>> arr # doctest: +SKIP array([[ -7.86816957e-17, 8.98979486e-02, 1.79795897e-01], [ 2.69693846e-01, 3.59591794e-01, 4.49489743e-01], [ 5.39387691e-01, 6.29285640e-01, 7.19183588e-01]]) """ vals, vecs = np.linalg.eig(ma.assert_numpy(arr)) vals /= abs(vals).max() vals *= 1.2 arr[...] = np.dot(vecs, np.dot(np.diag(vals), np.linalg.inv(vecs)))