コード例 #1
0
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_
コード例 #2
0
    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))
コード例 #3
0
ファイル: mcmc_sampling.py プロジェクト: xidongzhang/DPPy
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()
コード例 #4
0
ファイル: random_matrices.py プロジェクト: zshwuhan/DPPy
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)
コード例 #5
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
コード例 #6
0
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()
コード例 #7
0
ファイル: mcmc_sampling.py プロジェクト: zshwuhan/DPPy
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()
コード例 #8
0
ファイル: mcmc_sampling.py プロジェクト: zshwuhan/DPPy
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()
コード例 #9
0
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]
コード例 #10
0
ファイル: random_matrices.py プロジェクト: zshwuhan/DPPy
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
コード例 #11
0
ファイル: test_bless.py プロジェクト: xidongzhang/DPPy
    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.)
コード例 #12
0
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
コード例 #13
0
ファイル: random_matrices.py プロジェクト: zshwuhan/DPPy
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))
コード例 #14
0
ファイル: exotic_dpps.py プロジェクト: zshwuhan/DPPy
    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)
コード例 #15
0
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))
コード例 #16
0
ファイル: random_matrices.py プロジェクト: zshwuhan/DPPy
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)
コード例 #17
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)
コード例 #18
0
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
コード例 #19
0
ファイル: exotic_dpps.py プロジェクト: zshwuhan/DPPy
    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})
コード例 #20
0
ファイル: mcmc_sampling.py プロジェクト: xidongzhang/DPPy
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
コード例 #21
0
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
コード例 #22
0
ファイル: exact_sampling.py プロジェクト: yewu1212/DPPy
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]))
コード例 #23
0
ファイル: exotic_dpps.py プロジェクト: zshwuhan/DPPy
    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())
コード例 #24
0
ファイル: exotic_dpps.py プロジェクト: zshwuhan/DPPy
    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())
コード例 #25
0
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))
コード例 #26
0
ファイル: exotic_dpps.py プロジェクト: zshwuhan/DPPy
    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())
コード例 #27
0
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
コード例 #28
0
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())
コード例 #29
0
ファイル: test_bless.py プロジェクト: xidongzhang/DPPy
    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())
コード例 #30
0
ファイル: exact_sampling.py プロジェクト: yewu1212/DPPy
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