コード例 #1
0
def _reorder_kronecker_product(hi, mat, acting_on) -> Tuple[Array, Tuple]:
    """
    Reorders the matrix resulting from a kronecker product of several
    operators in such a way to sort acting_on.

    A conceptual example is the following:
    if `mat = Â ⊗ B̂ ⊗ Ĉ` and `acting_on = [[2],[1],[3]`
    you will get `result = B̂ ⊗ Â ⊗ Ĉ, [[1], [2], [3]].

    However, essentially, A,B,C represent some operators acting on
    thei sub-space acting_on[1], [2] and [3] of the hilbert space.

    This function also handles any possible set of values in acting_on.

    The inner logic uses the Fock.all_states(), number_to_state and
    state_to_number to perform the re-ordering.
    """
    acting_on_sorted = np.sort(acting_on)
    if np.array_equal(acting_on_sorted, acting_on):
        return mat, acting_on

    # could write custom binary <-> int logic instead of using Fock...
    # Since i need to work with bit-strings (where instead of bits i
    # have integers, in order to support arbitrary size spaces) this
    # is exactly what hilbert.to_number() and viceversa do.

    # target ordering binary representation
    hi_subspace = Fock(hi.shape[acting_on_sorted[0]] - 1)
    for site in acting_on_sorted[1:]:
        hi_subspace = hi_subspace * Fock(hi.shape[site] - 1)

    hi_unsorted_subspace = Fock(hi.shape[acting_on[0]] - 1)
    for site in acting_on[1:]:
        hi_unsorted_subspace = hi_unsorted_subspace * Fock(hi.shape[site] - 1)

    # find how to map target ordering back to unordered
    acting_on_unsorted_ids = np.zeros(len(acting_on), dtype=np.intp)
    for (i, site) in enumerate(acting_on):
        acting_on_unsorted_ids[i] = np.argmax(site == acting_on_sorted)

    # now it is valid that
    # acting_on_sorted == acting_on[acting_on_unsorted_ids]

    # generate n-bit strings in the target ordering
    v = hi_subspace.all_states()

    # convert them to origin (unordered) ordering
    v_unsorted = v[:, acting_on_unsorted_ids]
    # convert the unordered bit-strings to numbers in the target space.
    n_unsorted = hi_unsorted_subspace.states_to_numbers(v_unsorted)

    # reorder the matrix
    mat_sorted = mat[n_unsorted, :][:, n_unsorted]

    return mat_sorted, tuple(acting_on_sorted)
コード例 #2
0
ファイル: _local_operator.py プロジェクト: huihuangvv/netket
def _reorder_matrix(hi, mat, acting_on):
    acting_on_sorted = np.sort(acting_on)
    if np.all(acting_on_sorted == acting_on):
        return mat, acting_on

    acting_on_sorted_ids = np.argsort(acting_on)

    # could write custom binary <-> int logic instead of using Fock...
    # Since i need to work with bit-strings (where instead of bits i
    # have integers, in order to support arbitrary size spaces) this
    # is exactly what hilbert.to_number() and viceversa do.

    # target ordering binary representation
    hi_subspace = Fock(hi.shape[acting_on_sorted[0]] - 1)
    for site in acting_on_sorted[1:]:
        hi_subspace = Fock(hi.shape[site] - 1) * hi_subspace

    # find how to map target ordering back to unordered
    acting_on_unsorted_ids = np.zeros(len(acting_on), dtype=np.intp)
    for (i, site) in enumerate(acting_on):
        acting_on_unsorted_ids[i] = np.argmax(site == acting_on_sorted)

    # now it is valid that
    # acting_on_sorted == acting_on[acting_on_unsorted_ids]

    # generate n-bit strings in the target ordering
    v = hi_subspace.all_states()

    # convert them to origin (unordered) ordering
    v_unsorted = v[:, acting_on_unsorted_ids]
    # convert the unordered bit-strings to numbers in the target space.
    n_unsorted = hi_subspace.states_to_numbers(v_unsorted)

    # reorder the matrix
    mat_sorted = mat[n_unsorted, :][:, n_unsorted]

    return mat_sorted, acting_on_sorted