def sampler_mala(x, V, sigma=0.01, nb_steps=20, random_state=None): """ Sample from :math:`\\pi(x) \\propto \\exp(-V(x))` with :math:`V` polynomial using Metropolis Adjusted Langevin Algorithm (MALA) """ rng = check_random_state(random_state) x_ = x d1_V = V.deriv(m=1) for _ in range(nb_steps): Vx, grad_Vx = V(x_), d1_V(x_) y = x_ - 0.5 * sigma**2 * grad_Vx + sigma * rng.randn() Vy, grad_Vy = V(y), d1_V(y) acceptance = Vx - Vy\ + 0.5\ / sigma**2\ * ((x_ - y + 0.5 * sigma**2 * grad_Vy)**2 - (y - x_ + 0.5 * sigma**2 * grad_Vx)**2) if np.log(rng.rand()) < acceptance: x_ = y return x_
def test_reduce_lambda(self): N, d = 100, 5 lam = 11 lam_new = 10 rng = check_random_state(self.seed) X_data = rng.randn(N, d) L_data = example_eval_L_polynomial(X_data) rls_exact = la.solve(L_data + lam * np.eye(N), L_data).diagonal() dict_approx = self.__create_lambda_acc_dictionary(X_data, example_eval_L_polynomial, lam, rng) rls_estimates = estimate_rls_bless(dict_approx, X_data, example_eval_L_polynomial, lam) np.testing.assert_allclose(rls_estimates, rls_exact, rtol=0.5) dict_reduced = reduce_lambda(X_data, example_eval_L_polynomial, dict_approx, lam_new, rng) rls_estimates_reduced = estimate_rls_bless(dict_reduced, X_data, example_eval_L_polynomial, lam_new) rls_exact_reduced = la.solve(L_data + lam_new * np.eye(N), L_data).diagonal() np.testing.assert_allclose(rls_estimates_reduced, rls_exact_reduced, rtol=0.5) self.assertTrue(len(dict_reduced.idx) <= len(dict_approx.idx))
def initialize_AED_sampler(kernel, random_state=None): """ .. seealso:: - :func:`add_delete_sampler <add_delete_sampler>` - :func:`basis_exchange_sampler <basis_exchange_sampler>` - :func:`initialize_AED_sampler <initialize_AED_sampler>` - :func:`add_exchange_delete_sampler <add_exchange_delete_sampler>` """ rng = check_random_state(random_state) N = kernel.shape[0] ground_set = np.arange(N) S0, det_S0 = [], 0.0 nb_trials = 100 tol = 1e-9 for _ in range(nb_trials): if det_S0 > tol: break else: T = rng.choice(2 * N, size=N, replace=False) S0 = np.intersect1d(T, ground_set, assume_unique=True) det_S0 = det_ST(kernel, S0) else: err_str = [ 'Initialization terminated unsuccessfully.', 'After {} random trials, no initial set S0 satisfies det L_S0 > {}.' .format(nb_trials, tol), 'You may consider passing your own initial state **{"s_init": S0}.' ] raise ValueError('\n'.join(err_str)) return S0.tolist()
def hermite_sampler_full(N, beta=2, random_state=None): # size_sym_mat = int(N * (N-1) / 2) rng = check_random_state(random_state) if beta == 1: A = rng.randn(N, N) elif beta == 2: A = rng.randn(N, N) + 1j * rng.randn(N, N) elif beta == 4: X = rng.randn(N, N) + 1j * rng.randn(N, N) Y = rng.randn(N, N) + 1j * rng.randn(N, N) A = np.block([[X, Y], [-Y.conj(), X.conj()]]) else: err_print = ('`beta` parameter must be 1, 2 or 4.\ Given: {}'.format(beta)) raise ValueError(err_print) # return la.eigvalsh(A+A.conj().T) return la.eigvalsh(A + A.conj().T) / np.sqrt(2.0)
def ust_sampler_aldous_broder(list_of_neighbors, root=None, random_state=None): rng = check_random_state(random_state) # Initialize the tree aldous_tree_graph = nx.Graph() nb_nodes = len(list_of_neighbors) # Initialize the root, if root not specified start from any node n0 = root if root else rng.choice(nb_nodes) # size=1)[0] visited = np.zeros(nb_nodes, dtype=bool) visited[n0] = True nb_nodes_in_tree = 1 tree_edges = np.zeros((nb_nodes - 1, 2), dtype=np.int) while nb_nodes_in_tree < nb_nodes: # visit a neighbor of n0 uniformly at random n1 = rng.choice(list_of_neighbors[n0]) # size=1)[0] if visited[n1]: pass # continue the walk else: # create edge (n0, n1) and continue the walk tree_edges[nb_nodes_in_tree - 1] = [n0, n1] visited[n1] = True # mark it as in the tree nb_nodes_in_tree += 1 n0 = n1 aldous_tree_graph.add_edges_from(tree_edges) return aldous_tree_graph
def proj_dpp_sampler_eig_GS(eig_vecs, size=None, random_state=None): """ Sample from projection :math:`\\operatorname{DPP}(K)` using the eigendecomposition of the projection kernel :math:`K=VV^{\top}` where :math:`V^{\top}V = I_r` and :math:`r=\\operatorname{rank}(\\mathbf{K})`. It performs sequential update of Cholesky decomposition, which is equivalent to Gram-Schmidt orthogonalization of the rows of the eigenvectors. :param eig_vecs: Eigenvectors used to form projection kernel :math:`K=VV^{\top}`. :type eig_vecs: array_like :return: A sample from projection :math:`\\operatorname{DPP}(K)`. :rtype: list, array_like .. seealso:: - cite:`TrBaAm18` Algorithm 3, :cite:`Gil14` Algorithm 2 - :func:`proj_dpp_sampler_eig_GS_bis <proj_dpp_sampler_eig_GS_bis>` - :func:`proj_dpp_sampler_eig_KuTa12 <proj_dpp_sampler_eig_KuTa12>` """ rng = check_random_state(random_state) # Initialization V = eig_vecs N, rank = V.shape # ground set size / rank(K) if size is None: # full projection DPP size = rank # else: k-DPP with k = size ground_set = np.arange(N) sampl = np.zeros(size, dtype=int) # sample list avail = np.ones(N, dtype=bool) # available items # Phase 1: Already performed! # Select eigvecs with Bernoulli variables with parameter = eigvals of K. # Phase 2: Chain rule # Use Gram-Schmidt recursion to compute the Vol^2 of the parallelepiped spanned by the feature vectors associated to the sample c = np.zeros((N, size)) norms_2 = inner1d(V, axis=1) # ||V_i:||^2 for it in range(size): # Pick an item \propto this squred distance j = rng.choice(ground_set[avail], p=np.abs(norms_2[avail]) / (rank - it)) sampl[it] = j if it == size - 1: break # Cancel the contribution of V_j to the remaining feature vectors avail[j] = False c[avail, it] =\ (V[avail, :].dot(V[j, :]) - c[avail, :it].dot(c[j, :it]))\ / np.sqrt(norms_2[j]) norms_2[avail] -= c[avail, it]**2 # update residual norm^2 return sampl.tolist()
def initialize_AD_and_E_sampler(kernel, size=None, random_state=None): """ .. seealso:: - :func:`add_delete_sampler <add_delete_sampler>` - :func:`basis_exchange_sampler <basis_exchange_sampler>` - :func:`initialize_AED_sampler <initialize_AED_sampler>` - :func:`add_exchange_delete_sampler <add_exchange_delete_sampler>` """ rng = check_random_state(random_state) N = kernel.shape[0] S0, det_S0 = [], 0.0 it_max = 100 tol = 1e-9 for _ in range(it_max): if det_S0 > tol: break else: S0 = rng.choice(N, size=size if size else rng.randint(1, N + 1), replace=False) det_S0 = det_ST(kernel, S0) else: raise ValueError('Initialization problem, you may be using a size `k` > rank of the kernel') return S0.tolist()
def initialize_AED_sampler(kernel, random_state=None): """ .. seealso:: - :func:`add_delete_sampler <add_delete_sampler>` - :func:`basis_exchange_sampler <basis_exchange_sampler>` - :func:`initialize_AED_sampler <initialize_AED_sampler>` - :func:`add_exchange_delete_sampler <add_exchange_delete_sampler>` """ rng = check_random_state(random_state) N = kernel.shape[0] ground_set = np.arange(N) S0, det_S0 = [], 0.0 nb_iter = 100 tol = 1e-9 for _ in range(nb_iter): if det_S0 > tol: break else: T = rng.choice(2 * N, size=N, replace=False) S0 = np.intersect1d(T, ground_set, assume_unique=True) det_S0 = det_ST(kernel, S0) else: raise ValueError('Initialization problem, you may be using a size `k` > rank of the kernel') return S0.tolist()
def dpp_eig_vecs_selector(ber_params, eig_vecs, random_state=None): """ Phase 1 of exact sampling procedure. Subsample eigenvectors :math:`V` of the initial kernel (correlation :math:`K`, resp. likelihood :math:`L`) to build a projection DPP with kernel :math:`U U^{\\top}` from which sampling is easy. The selection is made based on a realization of Bernoulli variables with parameters to the eigenvalues of :math:`K`. :param ber_params: Parameters of Bernoulli variables :math:`\\lambda^K=\\lambda^L/(1+\\lambda^L) :type ber_params: list, array_like :param eig_vecs: Collection of eigenvectors of the kernel :math:`K`, resp. :math:`L` :type eig_vecs: array_like :return: selected eigenvectors :rtype: array_like .. seealso:: - :func:`dpp_sampler_eig <dpp_sampler_eig>` """ rng = check_random_state(random_state) # Realisation of Bernoulli random variables with params ber_params ind_sel = rng.rand(ber_params.size) < ber_params return eig_vecs[:, ind_sel]
def jacobi_sampler_full(M_1, M_2, N, beta=2, random_state=None): rng = check_random_state(random_state) if beta == 1: X = rng.randn(N, M_1) Y = rng.randn(N, M_2) elif beta == 2: X = rng.randn(N, M_1) + 1j * rng.randn(N, M_1) Y = rng.randn(N, M_2) + 1j * rng.randn(N, M_2) elif beta == 4: X_1 = rng.randn(N, M_1) + 1j * rng.randn(N, M_1) X_2 = rng.randn(N, M_1) + 1j * rng.randn(N, M_1) Y_1 = rng.randn(N, M_2) + 1j * rng.randn(N, M_2) Y_2 = rng.randn(N, M_2) + 1j * rng.randn(N, M_2) X = np.block([[X_1, X_2], [-X_2.conj(), X_1.conj()]]) Y = np.block([[Y_1, Y_2], [-Y_2.conj(), Y_1.conj()]]) else: err_print = ('`beta` parameter must be 1, 2 or 4.\ Given: {}'.format(beta)) raise ValueError(err_print) X_tmp = X.dot(X.conj().T) Y_tmp = Y.dot(Y.conj().T) return la.eigvals(X_tmp.dot(la.inv(X_tmp + Y_tmp))).real
def test_estimate_rls_bless(self): N, d = 100, 5 lam = 11 lam_new = 10 rng = check_random_state(self.seed) X_data = rng.randn(N, d) L_data = example_eval_L_polynomial(X_data) rls_exact = la.solve(L_data + lam_new * np.eye(N), L_data).diagonal() dict_exact = self.__create_lambda_acc_dictionary( X_data, example_eval_L_polynomial, 0.0, rng) dict_approx = self.__create_lambda_acc_dictionary( X_data, example_eval_L_polynomial, lam, rng) rls_estimates_exact = estimate_rls_bless(dict_exact, X_data, example_eval_L_polynomial, lam_new) rls_estimates_approx = estimate_rls_bless(dict_approx, X_data, example_eval_L_polynomial, lam_new) np.testing.assert_almost_equal(rls_estimates_exact, rls_exact) np.testing.assert_allclose(rls_estimates_approx, rls_exact, rtol=1 / 2.)
def proj_dpp_sampler_kernel(kernel, mode='GS', size=None, random_state=None): """ .. seealso:: - :func:`proj_dpp_sampler_kernel_GS <proj_dpp_sampler_kernel_GS>` - :func:`proj_dpp_sampler_kernel_Schur <proj_dpp_sampler_kernel_Schur>` - :func:`proj_dpp_sampler_kernel_Chol <proj_dpp_sampler_kernel_Chol>` """ rng = check_random_state(random_state) if size: rank = np.rint(np.trace(kernel)).astype(int) if size > rank: raise ValueError('size k={} > rank={}'.format(size, rank)) # Sample from orthogonal projection kernel K = K^2 = K.H K if mode == 'GS': # Gram-Schmidt equiv Cholesky sampl = proj_dpp_sampler_kernel_GS(kernel, size, rng) elif mode == 'Chol': # Cholesky updates of Pou19 sampl = proj_dpp_sampler_kernel_Chol(kernel, size, rng)[0] elif mode == 'Schur': # Schur complement sampl = proj_dpp_sampler_kernel_Schur(kernel, size, rng) else: str_list = [ 'Invalid sampling mode, choose among:', '- "GS (default)', '- "Chol"', '- "Schur"', 'Given "{}"'.format(mode) ] raise ValueError('\n'.join(str_list)) return sampl
def mu_ref_gamma_sampler_tridiag(shape=1.0, scale=1.0, beta=2, size=10, random_state=None): """ .. seealso:: :cite:`DuEd02` III-B """ rng = check_random_state(random_state) if not (beta > 0): raise ValueError('`beta` must be positive. Given: {}'.format(beta)) # beta/2*[N-1, N-2, ..., 1, 0] b_2_Ni = 0.5 * beta * np.arange(size - 1, -1, step=-1) # xi_odd = xi_1, ... , xi_2N-1 xi_odd = rng.gamma(shape=b_2_Ni + shape, scale=scale) # odd # xi_even = xi_0=0, xi_2, ... ,xi_2N-2 xi_even = np.zeros(size) xi_even[1:] = rng.gamma(shape=b_2_Ni[:-1], scale=scale) # even # alpha_i = xi_2i-2 + xi_2i-1, xi_0 = 0 alpha_coef = xi_even + xi_odd # beta_i+1 = xi_2i-1 * xi_2i beta_coef = xi_odd[:-1] * xi_even[1:] return la.eigvalsh_tridiagonal(alpha_coef, np.sqrt(beta_coef))
def sample(self, size=100, random_state=None): """ Draw a permutation uniformly at random and record the descents i.e. indices where :math:`\\sigma(i+1) < \\sigma(i)` and something else... :param size: size of the permutation i.e. degree :math:`N` of :math:`\\mathfrak{S}_N`. :type size: int .. seealso:: - :cite:`Kam18`, Sec ?? .. todo:: ask @kammmoun to complete the docsting and Section in see also """ rng = check_random_state(random_state) self.size = size sigma = uniform_permutation(self.size + 1, random_state=rng) X = sigma[:-1] > sigma[1:] # Record the descents in permutation Y = rng.binomial(n=2, p=self.x_0, size=self.size + 1) != 1 descent = [ i for i in range(self.size) if (~Y[i] and Y[i + 1]) or (~Y[i] and ~Y[i + 1] and X[i]) ] self.list_of_samples.append(descent)
def mu_ref_normal_sampler_tridiag(loc=0.0, scale=1.0, beta=2, size=10, random_state=None): """Implementation of the tridiagonal model to sample from .. math:: \\Delta(x_{1}, \\dots, x_{N})^{\\beta} \\prod_{n=1}^{N} \\exp(-\\frac{(x_i-\\mu)^2}{2\\sigma^2} ) dx_i .. seealso:: :cite:`DuEd02` II-C """ rng = check_random_state(random_state) if not (beta > 0): raise ValueError('`beta` must be positive. Given: {}'.format(beta)) # beta/2*[N-1, N-2, ..., 1] b_2_Ni = 0.5 * beta * np.arange(size - 1, 0, step=-1) alpha_coef = rng.normal(loc=loc, scale=scale, size=size) beta_coef = rng.gamma(shape=b_2_Ni, scale=scale**2) return la.eigvalsh_tridiagonal(alpha_coef, np.sqrt(beta_coef))
def ginibre_sampler_full(N, random_state=None): """Compute the eigenvalues of a random complex standard Gaussian matrix""" rng = check_random_state(random_state) A = rng.randn(N, N) + 1j * rng.randn(N, N) return la.eigvals(A) / np.sqrt(2.0)
def circular_sampler_full(N, beta=2, haar_mode='QR', random_state=None): """ .. seealso:: :cite:`Mez06` Section 5 """ rng = check_random_state(random_state) if haar_mode == 'Hermite': # size_sym_mat = int(N*(N-1)/2) if beta == 1: # COE A = rng.randn(N, N) elif beta == 2: # CUE A = rng.randn(N, N) + 1j * rng.randn(N, N) elif beta == 4: X = rng.randn(N, N) + 1j * rng.randn(N, N) Y = rng.randn(N, N) + 1j * rng.randn(N, N) A = np.block([[X, Y], [-Y.conj(), X.conj()]]) else: err_print = ('For `haar_mode="hermite"`, `beta` = 1, 2 or 4.', 'Given: {}'.format(beta)) raise ValueError('\n'.join(err_print)) _, U = la.eigh(A + A.conj().T) elif haar_mode == 'QR': if beta == 1: # COE A = rng.randn(N, N) elif beta == 2: # CUE A = rng.randn(N, N) + 1j * rng.randn(N, N) # elif beta==4: else: err_print = ('With `haar_mode="QR", `beta` = 1 or 2.', 'Given: {}'.format(beta)) raise ValueError('\n'.join(err_print)) # U, _ = la.qr(A) Q, R = la.qr(A) d = np.diagonal(R) U = np.multiply(Q, d / np.abs(d), Q) else: err_print = ('Invalid `haar_mode`.', 'Choose from `haar_mode="Hermite" or "QR".', 'Given: {}'.format(haar_mode)) raise ValueError('\n'.join(err_print)) return la.eigvals(U)
def ust_sampler_wilson(list_of_neighbors, root=None, random_state=None): rng = check_random_state(random_state) # Initialize the tree wilson_tree_graph = nx.Graph() nb_nodes = len(list_of_neighbors) # Initialize the root, if root not specified start from any node n0 = root if root else rng.choice(nb_nodes) # size=1)[0] # -1 = not visited / 0 = in path / 1 = in tree state = -np.ones(nb_nodes, dtype=int) state[n0] = 1 nb_nodes_in_tree = 1 path, branches = [], [] # branches of tree, temporary path while nb_nodes_in_tree < nb_nodes: # |Tree| = |V| - 1 # visit a neighbor of n0 uniformly at random n1 = rng.choice(list_of_neighbors[n0]) # size=1)[0] if state[n1] == -1: # not visited => continue the walk path.append(n1) # add it to the path state[n1] = 0 # mark it as in the path n0 = n1 # continue the walk if state[n1] == 0: # loop on the path => erase the loop knot = path.index(n1) # find 1st appearence of n1 in the path nodes_loop = path[knot + 1:] # identify nodes forming the loop del path[knot + 1:] # erase the loop state[nodes_loop] = -1 # mark loopy nodes as not visited n0 = n1 # continue the walk elif state[n1] == 1: # hits the tree => new branch if nb_nodes_in_tree == 1: branches.append([n1] + path) # initial branch of the tree else: branches.append(path + [n1]) # path as a new branch state[path] = 1 # mark nodes in path as in the tree nb_nodes_in_tree += len(path) # Restart the walk from a random node among those not visited nodes_not_visited = np.where(state == -1)[0] if nodes_not_visited.size: n0 = rng.choice(nodes_not_visited) # size=1)[0] path = [n0] tree_edges = list( chain.from_iterable(map(lambda x: zip(x[:-1], x[1:]), branches))) wilson_tree_graph.add_edges_from(tree_edges) return wilson_tree_graph
def plot(self, vs_bernoullis=True, random_state=None): """Display the last realization of the process. If ``vs_bernoullis=True`` compare it to a sequence of i.i.d. Bernoullis with parameter ``_bernoulli_param`` .. seealso:: - :py:meth:`sample` """ rng = check_random_state(random_state) title = 'Realization of the {} process'.format(self.name) fig, ax = plt.subplots(figsize=(19, 2)) sampl = self.list_of_samples[-1] ax.scatter(sampl, np.zeros_like(sampl) + (1.0 if vs_bernoullis else 0.0), color='b', s=20, label=self.name) if vs_bernoullis: title += r' vs independent Bernoulli variables with parameter $p$={:.3f}'.format( self._bernoulli_param) bern = np.where(rng.rand(self.size) < self._bernoulli_param)[0] ax.scatter(bern, -np.ones_like(bern), color='r', s=20, label='Bernoullis') plt.title(title) # Spine options ax.spines['bottom'].set_position('center') ax.spines['left'].set_visible(False) ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False) # Ticks options minor_ticks = np.arange(0, self.size + 1) major_ticks = np.arange(0, self.size + 1, 10) ax.set_xticks(major_ticks) ax.set_xticks(minor_ticks, minor=True) ax.set_xticklabels(major_ticks, fontsize=15) ax.xaxis.set_ticks_position('bottom') ax.tick_params( axis='y', # changes apply to the y-axis which='both', # both major and minor ticks are affected left=False, # ticks along the left edge are off right=False, # ticks along the right edge are off labelleft=False) # labels along the left edge are off ax.xaxis.grid(True) ax.set_xlim([-1, self.size + 1]) ax.legend(bbox_to_anchor=(0, 0.85), frameon=False, prop={'size': 15})
def dpp_sampler_mcmc(kernel, mode='AED', **params): """ Interface function with initializations and samplers for MCMC schemes. .. seealso:: - :ref:`finite_dpps_mcmc_sampling_add_exchange_delete` - :func:`add_exchange_delete_sampler <add_exchange_delete_sampler>` - :func:`initialize_AED_sampler <initialize_AED_sampler>` - :func:`add_delete_sampler <add_delete_sampler>` - :func:`basis_exchange_sampler <basis_exchange_sampler>` - :func:`initialize_AD_and_E_sampler <initialize_AD_and_E_sampler>` """ rng = check_random_state(params.get('random_state', None)) s_init = params.get('s_init', None) nb_iter = params.get('nb_iter', 10) T_max = params.get('T_max', None) size = params.get('size', None) # = Tr(K) for projection correlation K if mode == 'AED': # Add-Exchange-Delete S'=S+t, S-t+u, S-t if s_init is None: s_init = initialize_AED_sampler(kernel, random_state=rng) sampl = add_exchange_delete_sampler(kernel, s_init, nb_iter, T_max, random_state=rng) elif mode == 'AD': # Add-Delete S'=S+t, S-t if s_init is None: s_init = initialize_AD_and_E_sampler(kernel, random_state=rng) sampl = add_delete_sampler(kernel, s_init, nb_iter, T_max, random_state=rng) elif mode == 'E': # Exchange S'=S-t+u if s_init is None: s_init = initialize_AD_and_E_sampler(kernel, size, random_state=rng) sampl = basis_exchange_sampler(kernel, s_init, nb_iter, T_max, random_state=rng) return sampl
def trunc_gaussian_sampler(b, mu, var, random_state=None): rng = check_random_state(random_state) it_max = int(1e7) for it in range(1, it_max + 1): X = rng.normal(loc=b, scale=np.sqrt(var)) U = rng.rand() if (np.log(U) < -(b - mu) * (X - b) / var) and (X > b): break else: # if no acceptation print('gen_gamma with alpha=1 not accepted\ after {} iterations'.format(it)) X = 1e-7 return X, it
def dpp_eig_vecs_selector_L_dual(eig_vals, eig_vecs, gram_factor, random_state=None): """ Subsample eigenvectors :math:`V` of likelihood kernel :math:`L=\\Phi^{\\top} \\Phi` based on the eigendecomposition dual kernel :math:`L'=\\Phi \\Phi^{\\top}`. Note that :math:`L'` and :math:`L'` share the same nonzero eigenvalues. :param eig_vals: Collection of eigenvalues of :math:`L_dual` kernel. :type eig_vals: list, array_like :param eig_vecs: Collection of eigenvectors of :math:`L_dual` kernel. :type eig_vecs: array_like :param gram_factor: Feature matrix :math:`\\Phi` :type gram_factor: array_like :return: selected eigenvectors :rtype: array_like .. see also:: Phase 1: - :func:`dpp_eig_vecs_selector <dpp_eig_vecs_selector>` Phase 2: - :func:`proj_dpp_sampler_eig_GS <proj_dpp_sampler_eig_GS>` - :func:`proj_dpp_sampler_eig_GS_bis <proj_dpp_sampler_eig_GS_bis>` - :func:`proj_dpp_sampler_eig_KuTa12 <proj_dpp_sampler_eig_KuTa12>` """ rng = check_random_state(random_state) # Realisation of Bernoulli random variables with params eig_vals ind_sel = rng.rand(eig_vals.size) < eig_vals / (1.0 + eig_vals) return gram_factor.T.dot(eig_vecs[:, ind_sel] / np.sqrt(eig_vals[ind_sel]))
def sample(self, size=100, random_state=None): """ Draw a permutation :math:`\\sigma \\in \\mathfrak{S}_N` uniformly at random and record the descents i.e. :math:`\\{ i ~;~ \\sigma_i > \\sigma_{i+1} \\}`. :param size: size of the permutation i.e. degree :math:`N` of :math:`\\mathfrak{S}_N`. :type size: int """ rng = check_random_state(random_state) self.size = size sigma = uniform_permutation(self.size, random_state=rng) descent = 1 + np.where(sigma[:-1] > sigma[1:])[0] self.list_of_samples.append(descent.tolist())
def sample(self, size=100, random_state=None): """ Compute the cumulative sum (in base :math:`b`) of a sequence of i.i.d. digits and record the position of carries. :param size: size of the sequence of i.i.d. digits in :math:`\\{0, \\dots, b-1\\}` :type size: int """ rng = check_random_state(random_state) self.size = size A = rng.randint(0, self.base, self.size) B = np.mod(np.cumsum(A), self.base) carries = 1 + np.where(B[:-1] > B[1:])[0] self.list_of_samples.append(carries.tolist())
def mu_ref_beta_sampler_tridiag(a, b, beta=2, size=10, random_state=None): """ Implementation of the tridiagonal model given by Theorem 2 of :cite:`KiNe04` to sample from .. math:: \\Delta(x_{1}, \\dots, x_{N})^{\\beta} \\prod_{n=1}^{N} x^{a-1} (1-x)^{b-1} dx .. seealso:: :cite:`KiNe04` Theorem 2 """ rng = check_random_state(random_state) if not (beta > 0): raise ValueError('`beta` must be positive. Given: {}'.format(beta)) # beta/2*[N-1, N-2, ..., 1, 0] b_2_Ni = 0.5 * beta * np.arange(size - 1, -1, step=-1) # c_odd = c_1, c_3, ..., c_2N-1 c_odd = rng.beta(b_2_Ni + a, b_2_Ni + b) # c_even = c_0, c_2, c_2N-2 c_even = np.zeros(size) c_even[1:] = rng.beta(b_2_Ni[:-1], b_2_Ni[1:] + a + b) # xi_odd = xi_2i-1 = (1-c_2i-2) c_2i-1 xi_odd = (1 - c_even) * c_odd # xi_even = xi_0=0, xi_2, xi_2N-2 # xi_2i = (1-c_2i-1)*c_2i xi_even = np.zeros(size) xi_even[1:] = (1 - c_odd[:-1]) * c_even[1:] # alpha_i = xi_2i-2 + xi_2i-1 # alpha_1 = xi_0 + xi_1 = xi_1 alpha_coef = xi_even + xi_odd # beta_i+1 = xi_2i-1 * xi_2i beta_coef = xi_odd[:-1] * xi_even[1:] return la.eigvalsh_tridiagonal(alpha_coef, np.sqrt(beta_coef))
def sample(self, random_state=None): """ Sample from the Poissonized Plancherel measure. :param random_state: :type random_state: None, np.random, int, np.random.RandomState """ rng = check_random_state(random_state) N = rng.poisson(self.theta) sigma = uniform_permutation(N, random_state=rng) P, _ = RSK(sigma) # young_diag = [len(row) for row in P] young_diag = np.fromiter(map(len, P), dtype=int) self.list_of_young_diag.append(young_diag) # sampl = [len(row) - i + 0.5 for i, row in enumerate(P, start=1)] sampl = young_diag - np.arange(0.5, young_diag.size) self.list_of_samples.append(sampl.tolist())
def gen_gamma_alpha_lt_1_sampler(shape, P, random_state=None): rng = check_random_state(random_state) it_max = int(1e2) for it in range(1, it_max + 1): X = rng.gamma(shape=shape, scale=1 / P[1], size=1) U = rng.rand() if np.log(U) < -P[2] * X**2: break else: print('gen_gamma with alpha<1 not accepted\ after {} iterations'.format(it)) pass # X = ... return X, it
def mu_ref_unif_unit_circle_sampler_quindiag(beta=2, size=10, random_state=None): """ .. see also:: :cite:`KiNe04` Theorem 1 """ rng = check_random_state(random_state) if not (isinstance(beta, int) and (beta > 0)): raise ValueError('`beta` must be positive integer.\ Given: {}'.format(beta)) alpha = np.zeros(size, dtype=np.complex_) # nu = 1 + beta*(N-1, N-2, ..., 0) for i, nu in enumerate(1 + beta * np.arange(size - 1, -1, step=-1)): gauss_vec = rng.randn(nu + 1) alpha[i] = (gauss_vec[0] + 1j * gauss_vec[1]) / la.norm(gauss_vec) rho = np.sqrt(1 - np.abs(alpha[:-1])**2) xi = np.zeros((size - 1, 2, 2), dtype=np.complex_) # xi[0,..,N-1] xi[:, 0, 0], xi[:, 0, 1] = alpha[:-1].conj(), rho xi[:, 1, 0], xi[:, 1, 1] = rho, -alpha[:-1] # L = diag(xi_0, xi_2, ...) # M = diag(1, xi_1, x_3, ...) # xi[N-1] = alpha[N-1].conj() if size % 2 == 0: # even L = sp.block_diag(xi[::2, :, :], dtype=np.complex_) M = sp.block_diag([1.0, *xi[1::2, :, :], alpha[-1].conj()], dtype=np.complex_) else: # odd L = sp.block_diag([*xi[::2, :, :], alpha[-1].conj()], dtype=np.complex_) M = sp.block_diag([1.0, *xi[1::2, :, :]], dtype=np.complex_) return la.eigvals(L.dot(M).toarray())
def test_bless(self): N, d = 100, 5 lam = 11 rng = check_random_state(self.seed) X_data = rng.randn(N, d) L_data = example_eval_L_polynomial(X_data) rls_exact = la.solve(L_data + lam * np.eye(N), L_data).diagonal() dict_reduced = bless(X_data, example_eval_L_polynomial, lam_final=lam, rls_oversample_param=5, random_state=rng, verbose=False) rls_estimates = estimate_rls_bless(dict_reduced, X_data, example_eval_L_polynomial, lam) np.testing.assert_allclose(rls_estimates, rls_exact, rtol=1 / 2.) self.assertTrue(len(dict_reduced.idx) <= 5 * rls_exact.sum())
def proj_dpp_sampler_eig(eig_vecs, mode='GS', size=None, random_state=None): """ Sample from projection :math:`\\operatorname{DPP}(K)` using the eigendecomposition of the projection kernel :math:`K=VV^{\top}` where :math:`V^{\top}V = I_r` and :math:`r=\\operatorname{rank}(\\mathbf{K})`. .. seealso:: Phase 1: - :func:`dpp_eig_vecs_selector <dpp_eig_vecs_selector>` - :func:`dpp_eig_vecs_selector_gram_factor <dpp_eig_vecs_selector_gram_factor>` Phase 2: - :func:`proj_dpp_sampler_eig_GS <proj_dpp_sampler_eig_GS>` - :func:`proj_dpp_sampler_eig_GS_bis <proj_dpp_sampler_eig_GS_bis>` - :func:`proj_dpp_sampler_eig_KuTa12 <proj_dpp_sampler_eig_KuTa12>` """ rng = check_random_state(random_state) if eig_vecs.shape[1]: # Phase 2: Sample from projection kernel VV.T # Chain rule, conditionals are updated using: if mode == 'GS': # Gram-Schmidt sampl = proj_dpp_sampler_eig_GS(eig_vecs, size, rng) elif mode == 'GS_bis': # Slight modif of 'GS' sampl = proj_dpp_sampler_eig_GS_bis(eig_vecs, size, rng) elif mode == 'KuTa12': # cf Kulesza-Taskar sampl = proj_dpp_sampler_eig_KuTa12(eig_vecs, size, rng) else: str_list = [ 'Invalid sampling mode, choose among:', '- "GS" (default)', '- "GS_bis"', '- "KuTa12"', 'Given "{}"'.format(mode) ] raise ValueError('\n'.join(str_list)) else: sampl = [] return sampl