Пример #1
0
def sigmay(hilbert: _AbstractHilbert,
           site: int,
           dtype: _DType = complex) -> _LocalOperator:
    """
    Builds the :math:`\\sigma^y` operator acting on the `site`-th of the Hilbert
    space `hilbert`.

    If `hilbert` is a non-Spin space of local dimension M, it is considered
    as a (M-1)/2 - spin space.

    :param hilbert: The hilbert space
    :param site: the site on which this operator acts
    :return: a nk.operator.LocalOperator
    """
    import numpy as np
    import netket.jax as nkjax

    if not nkjax.is_complex_dtype(dtype):
        import jax.numpy as jnp
        import warnings

        old_dtype = dtype
        dtype = jnp.promote_types(complex, old_dtype)
        warnings.warn(
            np.ComplexWarning(
                f"A complex dtype is required (dtype={old_dtype} specified). "
                f"Promoting to dtype={dtype}."))

    N = hilbert.size_at_index(site)
    S = (N - 1) / 2

    D = np.array(
        [1j * np.sqrt((S + 1) * 2 * a - a * (a + 1)) for a in np.arange(1, N)])
    mat = np.diag(D, -1) + np.diag(-D, 1)
    return _LocalOperator(hilbert, mat, [site], dtype=dtype)
Пример #2
0
def proj(hilbert: AbstractHilbert,
         site: int,
         n: int,
         dtype: DType = float) -> _LocalOperator:
    """
    Builds the projector operator :math:`|n\\rangle\\langle n |` acting on the `site`-th of the
    Hilbert space `hilbert` and collapsing on the state with `n` bosons.

    If `hilbert` is a non-Bosonic space of local dimension M, it is considered
    as a bosonic space of local dimension M.

    Args:
        hilbert: The hilbert space
        site: the site on which this operator acts
        n: the state on which to project

    Returns:
        the resulting operator
    """
    import numpy as np

    N = hilbert.size_at_index(site)

    if n >= N:
        raise ValueError("Cannot project on a state above the cutoff.")

    D = np.array([0 for m in np.arange(0, N)])
    D[n] = 1
    mat = np.diag(D, 0)
    return _LocalOperator(hilbert, mat, [site], dtype=dtype)
Пример #3
0
def sigmaz(hilbert: _AbstractHilbert,
           site: int,
           dtype: _DType = float) -> _LocalOperator:
    """
    Builds the :math:`\\sigma^z` operator acting on the `site`-th of the Hilbert
    space `hilbert`.

    If `hilbert` is a non-Spin space of local dimension M, it is considered
    as a (M-1)/2 - spin space.

    :param hilbert: The hilbert space
    :param site: the site on which this operator acts
    :return: a nk.operator.LocalOperator
    """
    import numpy as np

    N = hilbert.size_at_index(site)
    S = (N - 1) / 2

    D = np.array([2 * m for m in np.arange(S, -(S + 1), -1)])
    mat = np.diag(D, 0)
    return _LocalOperator(hilbert, mat, [site], dtype=dtype)
Пример #4
0
def sigmax(hilbert: AbstractHilbert,
           site: int,
           dtype: DType = float) -> _LocalOperator:
    """
    Builds the :math:`\\sigma^x` operator acting on the `site`-th of the Hilbert
    space `hilbert`.

    If `hilbert` is a non-Spin space of local dimension M, it is considered
    as a (M-1)/2 - spin space.

    :param hilbert: The hilbert space
    :param site: the site on which this operator acts
    :return: a nk.operator.LocalOperator
    """
    import numpy as np

    N = hilbert.size_at_index(site)
    S = (N - 1) / 2

    D = [np.sqrt((S + 1) * 2 * a - a * (a + 1)) for a in np.arange(1, N)]
    mat = np.diag(D, 1) + np.diag(D, -1)
    return _LocalOperator(hilbert, mat, [site], dtype=dtype)
Пример #5
0
def number(hilbert: AbstractHilbert, site: int, dtype: DType = float) -> _LocalOperator:
    """
    Builds the number operator :math:`\\hat{a}^\\dagger\\hat{a}`  acting on the
    `site`-th of the Hilbert space `hilbert`.

    If `hilbert` is a non-Bosonic space of local dimension M, it is considered
    as a bosonic space of local dimension M.

    Args:
        hilbert: The hilbert space
        site: the site on which this operator acts

    Returns:
        The resulting Local Operator
    """
    import numpy as np

    N = hilbert.size_at_index(site)

    D = np.array([m for m in np.arange(0, N)])
    mat = np.diag(D, 0)
    return _LocalOperator(hilbert, mat, [site], dtype=dtype)
Пример #6
0
def sigmam(hilbert: AbstractHilbert,
           site: int,
           dtype: DType = float) -> _LocalOperator:
    """
    Builds the :math:`\\sigma^{-} = \\frac{1}{2}(\\sigma^x - i \\sigma^y)` operator acting on the
    `site`-th of the Hilbert space `hilbert`.

    If `hilbert` is a non-Spin space of local dimension M, it is considered
    as a (M-1)/2 - spin space.

    :param hilbert: The hilbert space
    :param site: the site on which this operator acts
    :return: a nk.operator.LocalOperator
    """
    import numpy as np

    N = hilbert.size_at_index(site)
    S = (N - 1) / 2

    S2 = (S + 1) * S
    D = np.array([np.sqrt(S2 - m * (m - 1)) for m in np.arange(S, -S, -1)])
    mat = np.diag(D, -1)
    return _LocalOperator(hilbert, mat, [site], dtype=dtype)
def pack_internals(
    hilbert: AbstractHilbert,
    operators_dict: dict,
    constant,
    dtype: DType,
    mel_cutoff: float,
):
    """
    Take the internal lazy representation of a local operator and returns the arrays
    needed for the numba implementation.

    This takes as input a dictionary with Tuples as keys, the `acting_on` and matrices as values.
    The keys represent the sites upon which the matrix acts.
    It is assumed that the integer in the tuples are sorted.

    Returns a dictionary with all the data fields
    """
    op_acting_on = list(operators_dict.keys())
    operators = list(operators_dict.values())
    n_operators = len(operators_dict)
    """Analyze the operator strings and precompute arrays for get_conn inference"""
    acting_size = np.array([len(aon) for aon in op_acting_on], dtype=np.intp)
    max_acting_on_sz = np.max(acting_size)
    max_local_hilbert_size = max(
        [max(map(hilbert.size_at_index, aon)) for aon in op_acting_on])
    max_op_size = max(map(lambda x: x.shape[0], operators))

    acting_on = np.full((n_operators, max_acting_on_sz), -1, dtype=np.intp)
    for (i, aon) in enumerate(op_acting_on):
        acting_on[i][:len(aon)] = aon

    local_states = np.full(
        (n_operators, max_acting_on_sz, max_local_hilbert_size), np.nan)
    basis = np.full((n_operators, max_acting_on_sz), 1e10, dtype=np.int64)

    diag_mels = np.full((n_operators, max_op_size), np.nan, dtype=dtype)
    mels = np.full(
        (n_operators, max_op_size, max_op_size - 1),
        np.nan,
        dtype=dtype,
    )
    x_prime = np.full(
        (n_operators, max_op_size, max_op_size - 1, max_acting_on_sz),
        -1,
        dtype=np.float64,
    )
    n_conns = np.full((n_operators, max_op_size), -1, dtype=np.intp)

    for (i, (aon, op)) in enumerate(operators_dict.items()):
        aon_size = len(aon)
        n_local_states_per_site = np.asarray(
            [hilbert.size_at_index(i) for i in aon])

        ## add an operator to local_states
        for (j, site) in enumerate(aon):
            local_states[i, j, :hilbert.shape[site]] = np.asarray(
                hilbert.states_at_index(site))

        ba = 1
        for s in range(aon_size):
            basis[i, s] = ba
            ba *= hilbert.shape[aon_size - s - 1]

        # eventually could support sparse matrices
        # if isinstance(op, sparse.spmatrix):
        #    op = op.todense()

        _append_matrix(
            op,
            diag_mels[i],
            mels[i],
            x_prime[i],
            n_conns[i],
            aon_size,
            local_states[i],
            mel_cutoff,
            n_local_states_per_site,
        )

    nonzero_diagonal = (np.any(np.abs(diag_mels) >= mel_cutoff)
                        or np.abs(constant) >= mel_cutoff)

    max_conn_size = 1 if nonzero_diagonal else 0
    for op in operators:
        nnz_mat = np.abs(op) > mel_cutoff
        nnz_mat[np.diag_indices(nnz_mat.shape[0])] = False
        nnz_rows = np.sum(nnz_mat, axis=1)
        max_conn_size += np.max(nnz_rows)

    return {
        "acting_on": acting_on,
        "acting_size": acting_size,
        "diag_mels": diag_mels,
        "mels": mels,
        "x_prime": x_prime,
        "n_conns": n_conns,
        "local_states": local_states,
        "basis": basis,
        "nonzero_diagonal": nonzero_diagonal,
        "max_conn_size": max_conn_size,
    }