Source code for fermifab.rdm

import numpy as np
from scipy.sparse import csr_matrix
from .fermistate import FermiState
from .fermiop import FermiOp
from .util import trace_prod
from fermifab.kernel import gen_rdm

__all__ = ['rdm']


def construct_rdm_kernel(orbs, p1, N1, N2):
    """
    Generate the kernel K (as array of sparse matrices) required for
    calculating p-body reduced density matrices.
    """
    # convert to iterable tuples, if necessary
    if not hasattr(orbs, '__len__'): orbs = (orbs,)
    if not hasattr(p1,   '__len__'): p1   = (p1,)
    if not hasattr(N1,   '__len__'): N1   = (N1,)
    if not hasattr(N2,   '__len__'): N2   = (N2,)
    dims, val, ind = gen_rdm(orbs, p1, N1, N2)
    # store data in nested lists
    val_arr = [[[] for j in range(dims[1])] for i in range(dims[0])]
    row_arr = [[[] for j in range(dims[1])] for i in range(dims[0])]
    col_arr = [[[] for j in range(dims[1])] for i in range(dims[0])]
    for n in range(len(ind)):
        val_arr[ind[n, 0]][ind[n, 1]].append(val[n])
        row_arr[ind[n, 0]][ind[n, 1]].append(ind[n, 2])
        col_arr[ind[n, 0]][ind[n, 1]].append(ind[n, 3])
    K = [[csr_matrix((val_arr[i][j], (row_arr[i][j], col_arr[i][j])), shape=(dims[2], dims[3]))
            for j in range(dims[1])]
            for i in range(dims[0])]
    return K


[docs]def rdm(state, p): """ Calculate the p-body reduced density matrix of a N-body quantum state. Args: state: quantum state of type 'FermiState' p: target particle number Returns: numpy.ndarray: reduced density matrix """ if type(state) == FermiState: N1 = state.N N2 = N1 elif type(state) == FermiOp: N1 = state.pFrom N2 = state.pTo # TODO: add support for lists of N assert N1 == N2 K = construct_rdm_kernel(state.orbs, p, N1, N2) G = np.zeros((len(K), len(K[0])), dtype=state.data.dtype) for i in range(G.shape[0]): for j in range(G.shape[1]): if type(state) == FermiState: G[i, j] = np.vdot(state.data, K[i][j].dot(state.data)) else: G[i, j] = trace_prod(K[i][j], state.data) return FermiOp(state.orbs, p, p, data=G)