Exemplo n.º 1
0
    def rotate_rho(self, basis, space, Z, unitaries, rho=None):
        r"""Computes the density matrix rotated into some basis

        :param basis: The basis into which to rotate the density matrix
        :type basis: numpy.ndarray
        :param space: The Hilbert space of the system
        :type space: torch.Tensor
        :param unitaries: A dictionary of unitary matrices associated with
                          rotation into each basis
        :type unitaries: dict[str, torch.Tensor]
        :returns: The rotated density matrix
        :rtype: torch.Tensor
        """
        rho = self.rhoRBM(space, space) if rho is None else rho

        unitaries = {k: v for k, v in unitaries.items()}
        us = [unitaries[b] for b in basis]
        if len(us) == 0:
            return rho

        # After ensuring there is more than one measurement, compute the
        # composite unitary by repeated Kronecker products
        U = us[0]
        for index in range(len(us) - 1):
            U = cplx.kronecker_prod(U, us[index + 1])

        U = U.to(rho)
        U_dag = cplx.conjugate(U)

        rot_rho = cplx.matmul(rho, U_dag)
        rot_rho_ = cplx.matmul(U, rot_rho)

        return rot_rho_
Exemplo n.º 2
0
def test_rotate_rho(num_visible, state_type):
    nn_state = state_type(num_visible, gpu=False)
    basis = "X" * num_visible
    unitary_dict = create_dict()

    space = nn_state.generate_hilbert_space()
    rho = nn_state.rho(space, space)

    rho_r_fast = rotate_rho(nn_state, basis, space, unitary_dict, rho=rho)

    U = reduce(cplx.kronecker_prod, [unitary_dict[b] for b in basis])
    rho_r_correct = cplx.matmul(U, rho)
    rho_r_correct = cplx.matmul(rho_r_correct, cplx.conjugate(U))

    assertAlmostEqual(rho_r_fast, rho_r_correct, msg="Fast rho rotation failed!")
Exemplo n.º 3
0
 def test_matrix_matrix_matmul(self):
     matrix1 = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]], dtype=torch.double)
     matrix2 = torch.tensor([[[1, 0], [3, 0]], [[0, 6], [0, 8]]], dtype=torch.double)
     expect = torch.tensor(
         [[[7, -78], [15, -106]], [[23, 22], [31, 50]]], dtype=torch.double
     )
     self.assertTensorsEqual(
         cplx.matmul(matrix1, matrix2),
         expect,
         msg="Matrix * Matrix multiplication failed!",
     )
Exemplo n.º 4
0
    def test_matrix_vector_matmul(self):
        matrix = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]], dtype=torch.double)
        vector = torch.tensor([[1, 2], [3, 4]], dtype=torch.double)

        expect = torch.tensor([[-34, -42], [28, 48]], dtype=torch.double)

        self.assertTensorsEqual(
            cplx.matmul(matrix, vector),
            expect,
            msg="Matrix * Vector multiplication failed!",
        )
Exemplo n.º 5
0
def test_rotate_psi(num_visible, wvfn_type):
    nn_state = wvfn_type(num_visible, gpu=False)
    basis = "X" * num_visible
    unitary_dict = create_dict()

    space = nn_state.generate_hilbert_space()
    psi = nn_state.psi(space)

    psi_r_fast = rotate_psi(nn_state, basis, space, unitary_dict, psi=psi)

    U = reduce(cplx.kronecker_prod, [unitary_dict[b] for b in basis])
    psi_r_correct = cplx.matmul(U, psi)

    assertAlmostEqual(psi_r_fast, psi_r_correct, msg="Fast psi rotation failed!")
Exemplo n.º 6
0
def rotate_psi(nn_state, basis, space, unitaries, psi=None):
    r"""A function that rotates the reconstructed wavefunction to a different
    basis.

    :param nn_state: The neural network state (i.e. complex wavefunction or
                     positive wavefunction).
    :type nn_state: qucumber.nn_states.WaveFunctionBase
    :param basis: The basis to rotate the wavefunction to.
    :type basis: str
    :param space: The basis elements of the Hilbert space of the system :math:`\mathcal{H}`.
    :type space: torch.Tensor
    :param unitaries: A dictionary of (2x2) unitary operators.
    :type unitaries: dict(str, torch.Tensor)
    :param psi: A wavefunction that the user can input to override the neural
                network state's wavefunction.
    :type psi: torch.Tensor

    :returns: A wavefunction in a new basis.
    :rtype: torch.Tensor
    """
    psi = (
        nn_state.psi(space)
        if psi is None
        else psi.to(dtype=torch.double, device=nn_state.device)
    )

    unitaries = {k: v.to(device=nn_state.device) for k, v in unitaries.items()}
    us = [unitaries[b] for b in basis]
    n_u = [u.size()[0] for u in us]

    l, r = np.prod(n_u), 1  # noqa: E741

    psi_r = psi.clone()
    for s in reversed(range(len(n_u))):
        l //= n_u[s]  # noqa: E741
        m = us[s]

        for k in range(l):
            for i in range(r):
                slc = slice(k * n_u[s] * r + i, (k + 1) * n_u[s] * r + i, r)
                U = psi_r[:, slc]
                psi_r[:, slc] = cplx.matmul(m, U)
        r *= n_u[s]

    return psi_r
Exemplo n.º 7
0
def _kron_mult(matrices, x):
    n = [m.size()[0] for m in matrices]
    l, r = np.prod(n), 1  # noqa: E741

    if l != x.shape[1]:  # noqa: E741
        raise ValueError("Incompatible sizes!")

    y = x.clone()
    for s in reversed(range(len(n))):
        l //= n[s]  # noqa: E741
        m = matrices[s]

        for k in range(l):
            for i in range(r):
                slc = slice(k * n[s] * r + i, (k + 1) * n[s] * r + i, r)
                temp = y[:, slc, ...]
                y[:, slc, ...] = cplx.matmul(m, temp)
        r *= n[s]

    return y
Exemplo n.º 8
0
 def rotate_psi_full(self, basis, full_unitary_dict, psi):
     U = full_unitary_dict[basis]
     Upsi = cplx.matmul(U, psi)
     return Upsi